summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-01-02 01:48:38 +0200
committerAndrei Karas <akaras@inbox.ru>2011-01-02 02:41:24 +0200
commit3eeae12c498d1a4dbe969462d2ba841f77ee3ccb (patch)
treeff8eab35e732bc0749fc11677c8873a7b3a58704
downloadplus-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.gz
plus-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.bz2
plus-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.xz
plus-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.zip
Initial commit.
This code based on mana client http://www.gitorious.org/mana/mana and my private repository.
-rw-r--r--.gitignore120
-rw-r--r--.mailmap13
-rw-r--r--AUTHORS71
-rw-r--r--CMake/Modules/FindENet.cmake52
-rw-r--r--CMake/Modules/FindGuichan.cmake100
-rw-r--r--CMake/Modules/FindLibIntl.cmake46
-rw-r--r--CMake/Modules/FindSDL_gfx.cmake39
-rw-r--r--CMakeLists.txt74
-rw-r--r--COPYING340
-rw-r--r--ChangeLog6267
-rw-r--r--English.lproj/InfoPlist.stringsbin0 -> 204 bytes
-rw-r--r--English.lproj/SDLMain.nib/classes.nib8
-rw-r--r--English.lproj/SDLMain.nib/info.nib20
-rw-r--r--English.lproj/SDLMain.nib/objects.xib77
-rw-r--r--English.lproj/main.nib/classes.nib8
-rw-r--r--English.lproj/main.nib/info.nib20
-rw-r--r--English.lproj/main.nib/objects.xib77
-rw-r--r--INSTALL77
-rw-r--r--Info.plist30
-rw-r--r--Makefile.am20
-rw-r--r--Mana.icnsbin0 -> 65136 bytes
-rw-r--r--NEWS552
-rw-r--r--README110
-rw-r--r--README.cmake136
-rw-r--r--README.txt110
-rw-r--r--SDLMain.nib/classes.nib8
-rw-r--r--SDLMain.nib/info.nib20
-rw-r--r--SDLMain.nib/objects.xib80
-rwxr-xr-xbcmake7
-rwxr-xr-xbdeb.sh3
-rwxr-xr-xbmake48
-rwxr-xr-xconfigure.ac166
-rw-r--r--data/CMakeLists.txt9
-rw-r--r--data/Makefile.am6
-rw-r--r--data/fonts/CMakeLists.txt12
-rw-r--r--data/fonts/Makefile.am15
-rw-r--r--data/fonts/dejavusans-bold.ttfbin0 -> 584396 bytes
-rw-r--r--data/fonts/dejavusans.ttfbin0 -> 633604 bytes
-rw-r--r--data/fonts/dejavusansmono-bold.ttfbin0 -> 302868 bytes
-rw-r--r--data/fonts/dejavusansmono.ttfbin0 -> 322524 bytes
-rw-r--r--data/fonts/liberationsans-bold.ttfbin0 -> 139008 bytes
-rw-r--r--data/fonts/liberationsans.ttfbin0 -> 139280 bytes
-rw-r--r--data/fonts/liberationsansmono-bold.ttfbin0 -> 105116 bytes
-rw-r--r--data/fonts/liberationsansmono.ttfbin0 -> 107696 bytes
-rw-r--r--data/graphics/CMakeLists.txt12
-rw-r--r--data/graphics/Makefile.am16
-rw-r--r--data/graphics/gui/CMakeLists.txt48
-rw-r--r--data/graphics/gui/Makefile.am52
-rw-r--r--data/graphics/gui/bubble.pngbin0 -> 407 bytes
-rw-r--r--data/graphics/gui/button.pngbin0 -> 374 bytes
-rw-r--r--data/graphics/gui/button_disabled.pngbin0 -> 313 bytes
-rw-r--r--data/graphics/gui/buttonhi.pngbin0 -> 374 bytes
-rw-r--r--data/graphics/gui/buttonpress.pngbin0 -> 377 bytes
-rw-r--r--data/graphics/gui/checkbox.pngbin0 -> 802 bytes
-rw-r--r--data/graphics/gui/circle-gray.pngbin0 -> 300 bytes
-rw-r--r--data/graphics/gui/circle-green.pngbin0 -> 328 bytes
-rw-r--r--data/graphics/gui/close_button.pngbin0 -> 650 bytes
-rw-r--r--data/graphics/gui/colors.xml53
-rw-r--r--data/graphics/gui/deepbox.pngbin0 -> 219 bytes
-rw-r--r--data/graphics/gui/hscroll_left_default.pngbin0 -> 358 bytes
-rw-r--r--data/graphics/gui/hscroll_left_highlight.pngbin0 -> 364 bytes
-rw-r--r--data/graphics/gui/hscroll_left_pressed.pngbin0 -> 349 bytes
-rw-r--r--data/graphics/gui/hscroll_right_default.pngbin0 -> 340 bytes
-rw-r--r--data/graphics/gui/hscroll_right_highlight.pngbin0 -> 359 bytes
-rw-r--r--data/graphics/gui/hscroll_right_pressed.pngbin0 -> 350 bytes
-rw-r--r--data/graphics/gui/item_shortcut_bgr.pngbin0 -> 284 bytes
-rw-r--r--data/graphics/gui/mouse.pngbin0 -> 6193 bytes
-rw-r--r--data/graphics/gui/progress-indicator.pngbin0 -> 5533 bytes
-rw-r--r--data/graphics/gui/radioin.pngbin0 -> 454 bytes
-rw-r--r--data/graphics/gui/radioin_highlight.pngbin0 -> 485 bytes
-rw-r--r--data/graphics/gui/radioout.pngbin0 -> 380 bytes
-rw-r--r--data/graphics/gui/radioout_highlight.pngbin0 -> 434 bytes
-rw-r--r--data/graphics/gui/resize.pngbin0 -> 443 bytes
-rw-r--r--data/graphics/gui/selection.pngbin0 -> 740 bytes
-rw-r--r--data/graphics/gui/slider.pngbin0 -> 485 bytes
-rw-r--r--data/graphics/gui/slider_hilight.pngbin0 -> 444 bytes
-rw-r--r--data/graphics/gui/speechbubble.xml18
-rw-r--r--data/graphics/gui/sticky_button.pngbin0 -> 526 bytes
-rw-r--r--data/graphics/gui/tab.pngbin0 -> 329 bytes
-rw-r--r--data/graphics/gui/tab_hilight.pngbin0 -> 316 bytes
-rw-r--r--data/graphics/gui/tabselected.pngbin0 -> 313 bytes
-rw-r--r--data/graphics/gui/unknown-item.pngbin0 -> 540 bytes
-rw-r--r--data/graphics/gui/vscroll_down_default.pngbin0 -> 367 bytes
-rw-r--r--data/graphics/gui/vscroll_down_highlight.pngbin0 -> 382 bytes
-rw-r--r--data/graphics/gui/vscroll_down_pressed.pngbin0 -> 376 bytes
-rw-r--r--data/graphics/gui/vscroll_grey.pngbin0 -> 338 bytes
-rw-r--r--data/graphics/gui/vscroll_highlight.pngbin0 -> 338 bytes
-rw-r--r--data/graphics/gui/vscroll_up_default.pngbin0 -> 377 bytes
-rw-r--r--data/graphics/gui/vscroll_up_highlight.pngbin0 -> 376 bytes
-rw-r--r--data/graphics/gui/vscroll_up_pressed.pngbin0 -> 364 bytes
-rw-r--r--data/graphics/gui/window.pngbin0 -> 3410 bytes
-rw-r--r--data/graphics/gui/window.xml18
-rw-r--r--data/graphics/images/CMakeLists.txt6
-rw-r--r--data/graphics/images/Makefile.am9
-rw-r--r--data/graphics/images/error.pngbin0 -> 314 bytes
-rw-r--r--data/graphics/images/login_wallpaper.pngbin0 -> 10948 bytes
-rw-r--r--data/graphics/sprites/CMakeLists.txt13
-rw-r--r--data/graphics/sprites/Makefile.am16
-rw-r--r--data/graphics/sprites/arrow_down.gifbin0 -> 152 bytes
-rw-r--r--data/graphics/sprites/arrow_left.gifbin0 -> 148 bytes
-rw-r--r--data/graphics/sprites/arrow_right.gifbin0 -> 145 bytes
-rw-r--r--data/graphics/sprites/arrow_up.gifbin0 -> 139 bytes
-rw-r--r--data/graphics/sprites/error.pngbin0 -> 314 bytes
-rw-r--r--data/graphics/sprites/error.xml10
-rw-r--r--data/graphics/sprites/manaplus_emote.xml10
-rw-r--r--data/graphics/sprites/manaplus_emotes.xml22
-rw-r--r--data/graphics/sprites/manaplus_emotions.pngbin0 -> 27366 bytes
-rw-r--r--data/graphics/target-cursor-in-range-l.pngbin0 -> 23803 bytes
-rw-r--r--data/graphics/target-cursor-in-range-m.pngbin0 -> 18439 bytes
-rw-r--r--data/graphics/target-cursor-in-range-s.pngbin0 -> 8353 bytes
-rw-r--r--data/graphics/target-cursor-normal-l.pngbin0 -> 25586 bytes
-rw-r--r--data/graphics/target-cursor-normal-m.pngbin0 -> 17950 bytes
-rw-r--r--data/graphics/target-cursor-normal-s.pngbin0 -> 8361 bytes
-rw-r--r--data/help/CMakeLists.txt12
-rw-r--r--data/help/Makefile.am16
-rw-r--r--data/help/about.txt16
-rw-r--r--data/help/changes.txt885
-rw-r--r--data/help/chatcommands.txt74
-rw-r--r--data/help/commands.txt175
-rw-r--r--data/help/header.txt11
-rw-r--r--data/help/index.txt23
-rw-r--r--data/help/skills.txt16
-rw-r--r--data/help/support.txt22
-rw-r--r--data/help/team.txt132
-rw-r--r--data/help/windows.txt15
-rw-r--r--data/icons/CMakeLists.txt7
-rw-r--r--data/icons/Makefile.am16
-rw-r--r--data/icons/manaplus.hqx2938
-rw-r--r--data/icons/manaplus.icnsbin0 -> 139364 bytes
-rw-r--r--data/icons/manaplus.icobin0 -> 353118 bytes
-rw-r--r--data/icons/manaplus.pngbin0 -> 2985 bytes
-rw-r--r--data/icons/manaplus.svg150
-rw-r--r--data/icons/manaplus.xpm40
-rw-r--r--data/items.xsd41
-rw-r--r--data/sfx/CMakeLists.txt1
-rw-r--r--data/sfx/Makefile.am1
-rw-r--r--data/sfx/system/CMakeLists.txt5
-rw-r--r--data/sfx/system/Makefile.am8
-rw-r--r--data/sfx/system/newmessage.oggbin0 -> 12525 bytes
-rw-r--r--data/themes/CMakeLists.txt5
-rwxr-xr-xdata/themes/Makefile.am2
-rw-r--r--data/themes/blackwood/CMakeLists.txt44
-rw-r--r--data/themes/blackwood/Makefile.am53
-rw-r--r--data/themes/blackwood/button.pngbin0 -> 1085 bytes
-rw-r--r--data/themes/blackwood/button_disabled.pngbin0 -> 1205 bytes
-rw-r--r--data/themes/blackwood/buttonhi.pngbin0 -> 978 bytes
-rw-r--r--data/themes/blackwood/buttonpress.pngbin0 -> 986 bytes
-rw-r--r--data/themes/blackwood/checkbox.pngbin0 -> 648 bytes
-rw-r--r--data/themes/blackwood/circle-gray.pngbin0 -> 436 bytes
-rw-r--r--data/themes/blackwood/circle-green.pngbin0 -> 455 bytes
-rw-r--r--data/themes/blackwood/close_button.pngbin0 -> 1485 bytes
-rw-r--r--data/themes/blackwood/colors.xml52
-rw-r--r--data/themes/blackwood/deepbox.pngbin0 -> 162 bytes
-rw-r--r--data/themes/blackwood/hscroll_left_default.pngbin0 -> 435 bytes
-rw-r--r--data/themes/blackwood/hscroll_left_highlight.pngbin0 -> 436 bytes
-rw-r--r--data/themes/blackwood/hscroll_left_pressed.pngbin0 -> 415 bytes
-rw-r--r--data/themes/blackwood/hscroll_right_default.pngbin0 -> 432 bytes
-rw-r--r--data/themes/blackwood/hscroll_right_highlight.pngbin0 -> 419 bytes
-rw-r--r--data/themes/blackwood/hscroll_right_pressed.pngbin0 -> 428 bytes
-rw-r--r--data/themes/blackwood/item_shortcut_bgr.pngbin0 -> 1722 bytes
-rw-r--r--data/themes/blackwood/mouse.pngbin0 -> 13541 bytes
-rw-r--r--data/themes/blackwood/progress-indicator.pngbin0 -> 4997 bytes
-rw-r--r--data/themes/blackwood/radioin.pngbin0 -> 376 bytes
-rw-r--r--data/themes/blackwood/radioin_highlight.pngbin0 -> 298 bytes
-rw-r--r--data/themes/blackwood/radioout.pngbin0 -> 346 bytes
-rw-r--r--data/themes/blackwood/radioout_highlight.pngbin0 -> 319 bytes
-rw-r--r--data/themes/blackwood/selection.pngbin0 -> 442 bytes
-rw-r--r--data/themes/blackwood/slider.pngbin0 -> 549 bytes
-rw-r--r--data/themes/blackwood/slider_hilight.pngbin0 -> 540 bytes
-rw-r--r--data/themes/blackwood/speech_bubble.pngbin0 -> 2031 bytes
-rw-r--r--data/themes/blackwood/speechbubble.xml18
-rw-r--r--data/themes/blackwood/sticky_button.pngbin0 -> 940 bytes
-rw-r--r--data/themes/blackwood/tab.pngbin0 -> 1030 bytes
-rw-r--r--data/themes/blackwood/tab_hilight.pngbin0 -> 1525 bytes
-rw-r--r--data/themes/blackwood/tabselected.pngbin0 -> 1028 bytes
-rw-r--r--data/themes/blackwood/target-cursor-blue-l.pngbin0 -> 20680 bytes
-rw-r--r--data/themes/blackwood/target-cursor-blue-m.pngbin0 -> 17811 bytes
-rw-r--r--data/themes/blackwood/target-cursor-blue-s.pngbin0 -> 8019 bytes
-rw-r--r--data/themes/blackwood/target-cursor-red-l.pngbin0 -> 43220 bytes
-rw-r--r--data/themes/blackwood/target-cursor-red-m.pngbin0 -> 30210 bytes
-rw-r--r--data/themes/blackwood/target-cursor-red-s.pngbin0 -> 20194 bytes
-rw-r--r--data/themes/blackwood/vscroll_down_default.pngbin0 -> 417 bytes
-rw-r--r--data/themes/blackwood/vscroll_down_highlight.pngbin0 -> 405 bytes
-rw-r--r--data/themes/blackwood/vscroll_down_pressed.pngbin0 -> 403 bytes
-rw-r--r--data/themes/blackwood/vscroll_grey.pngbin0 -> 485 bytes
-rw-r--r--data/themes/blackwood/vscroll_highlight.pngbin0 -> 417 bytes
-rw-r--r--data/themes/blackwood/vscroll_up_default.pngbin0 -> 421 bytes
-rw-r--r--data/themes/blackwood/vscroll_up_highlight.pngbin0 -> 396 bytes
-rw-r--r--data/themes/blackwood/vscroll_up_pressed.pngbin0 -> 398 bytes
-rw-r--r--data/themes/blackwood/window.pngbin0 -> 8408 bytes
-rw-r--r--data/themes/classic/CMakeLists.txt54
-rwxr-xr-xdata/themes/classic/Makefile.am56
-rwxr-xr-xdata/themes/classic/bubble.pngbin0 -> 407 bytes
-rwxr-xr-xdata/themes/classic/button.pngbin0 -> 374 bytes
-rwxr-xr-xdata/themes/classic/button_disabled.pngbin0 -> 313 bytes
-rwxr-xr-xdata/themes/classic/buttonhi.pngbin0 -> 374 bytes
-rwxr-xr-xdata/themes/classic/buttonpress.pngbin0 -> 377 bytes
-rw-r--r--data/themes/classic/checkbox.pngbin0 -> 802 bytes
-rwxr-xr-xdata/themes/classic/circle-gray.pngbin0 -> 300 bytes
-rwxr-xr-xdata/themes/classic/circle-green.pngbin0 -> 328 bytes
-rwxr-xr-xdata/themes/classic/close_button.pngbin0 -> 650 bytes
-rw-r--r--data/themes/classic/colors.xml53
-rwxr-xr-xdata/themes/classic/deepbox.pngbin0 -> 219 bytes
-rwxr-xr-xdata/themes/classic/hscroll_left_default.pngbin0 -> 358 bytes
-rwxr-xr-xdata/themes/classic/hscroll_left_highlight.pngbin0 -> 364 bytes
-rwxr-xr-xdata/themes/classic/hscroll_left_pressed.pngbin0 -> 349 bytes
-rwxr-xr-xdata/themes/classic/hscroll_right_default.pngbin0 -> 340 bytes
-rwxr-xr-xdata/themes/classic/hscroll_right_highlight.pngbin0 -> 359 bytes
-rwxr-xr-xdata/themes/classic/hscroll_right_pressed.pngbin0 -> 350 bytes
-rwxr-xr-xdata/themes/classic/item_shortcut_bgr.pngbin0 -> 284 bytes
-rw-r--r--data/themes/classic/mouse.pngbin0 -> 6193 bytes
-rw-r--r--data/themes/classic/progress-indicator.pngbin0 -> 5533 bytes
-rwxr-xr-xdata/themes/classic/radioin.pngbin0 -> 454 bytes
-rw-r--r--data/themes/classic/radioin_highlight.pngbin0 -> 485 bytes
-rwxr-xr-xdata/themes/classic/radioout.pngbin0 -> 380 bytes
-rw-r--r--data/themes/classic/radioout_highlight.pngbin0 -> 434 bytes
-rwxr-xr-xdata/themes/classic/resize.pngbin0 -> 443 bytes
-rw-r--r--data/themes/classic/selection.pngbin0 -> 740 bytes
-rwxr-xr-xdata/themes/classic/slider.pngbin0 -> 485 bytes
-rw-r--r--data/themes/classic/slider_hilight.pngbin0 -> 444 bytes
-rwxr-xr-xdata/themes/classic/speechbubble.xml18
-rwxr-xr-xdata/themes/classic/sticky_button.pngbin0 -> 526 bytes
-rwxr-xr-xdata/themes/classic/tab.pngbin0 -> 329 bytes
-rw-r--r--data/themes/classic/tab_hilight.pngbin0 -> 316 bytes
-rwxr-xr-xdata/themes/classic/tabselected.pngbin0 -> 313 bytes
-rwxr-xr-xdata/themes/classic/target-cursor-blue-l.pngbin0 -> 23803 bytes
-rwxr-xr-xdata/themes/classic/target-cursor-blue-m.pngbin0 -> 18439 bytes
-rwxr-xr-xdata/themes/classic/target-cursor-blue-s.pngbin0 -> 8353 bytes
-rwxr-xr-xdata/themes/classic/target-cursor-red-l.pngbin0 -> 25586 bytes
-rwxr-xr-xdata/themes/classic/target-cursor-red-m.pngbin0 -> 17950 bytes
-rwxr-xr-xdata/themes/classic/target-cursor-red-s.pngbin0 -> 8361 bytes
-rwxr-xr-xdata/themes/classic/unknown-item.pngbin0 -> 540 bytes
-rwxr-xr-xdata/themes/classic/vscroll_down_default.pngbin0 -> 367 bytes
-rwxr-xr-xdata/themes/classic/vscroll_down_highlight.pngbin0 -> 382 bytes
-rwxr-xr-xdata/themes/classic/vscroll_down_pressed.pngbin0 -> 376 bytes
-rwxr-xr-xdata/themes/classic/vscroll_grey.pngbin0 -> 338 bytes
-rw-r--r--data/themes/classic/vscroll_highlight.pngbin0 -> 338 bytes
-rwxr-xr-xdata/themes/classic/vscroll_up_default.pngbin0 -> 377 bytes
-rwxr-xr-xdata/themes/classic/vscroll_up_highlight.pngbin0 -> 376 bytes
-rwxr-xr-xdata/themes/classic/vscroll_up_pressed.pngbin0 -> 364 bytes
-rwxr-xr-xdata/themes/classic/window.pngbin0 -> 3410 bytes
-rwxr-xr-xdata/themes/classic/window.xml18
-rw-r--r--data/themes/enchilado/CMakeLists.txt14
-rwxr-xr-xdata/themes/enchilado/Makefile.am17
-rw-r--r--data/themes/enchilado/button.pngbin0 -> 2659 bytes
-rw-r--r--data/themes/enchilado/button_disabled.pngbin0 -> 2659 bytes
-rw-r--r--data/themes/enchilado/buttonhi.pngbin0 -> 2659 bytes
-rw-r--r--data/themes/enchilado/buttonpress.pngbin0 -> 2659 bytes
-rw-r--r--data/themes/enchilado/colors.xml53
-rw-r--r--data/themes/enchilado/tab.pngbin0 -> 867 bytes
-rw-r--r--data/themes/enchilado/tab_hilight.pngbin0 -> 2344 bytes
-rw-r--r--data/themes/enchilado/tabselected.pngbin0 -> 2344 bytes
-rw-r--r--data/themes/enchilado/window.pngbin0 -> 7500 bytes
-rw-r--r--data/themes/enchilado/window.xml19
-rw-r--r--data/themes/redandblack/CMakeLists.txt53
-rwxr-xr-xdata/themes/redandblack/Makefile.am56
-rwxr-xr-xdata/themes/redandblack/bubble.pngbin0 -> 484 bytes
-rwxr-xr-xdata/themes/redandblack/button.pngbin0 -> 709 bytes
-rwxr-xr-xdata/themes/redandblack/button_disabled.pngbin0 -> 587 bytes
-rwxr-xr-xdata/themes/redandblack/buttonhi.pngbin0 -> 734 bytes
-rwxr-xr-xdata/themes/redandblack/buttonpress.pngbin0 -> 658 bytes
-rwxr-xr-xdata/themes/redandblack/checkbox.pngbin0 -> 728 bytes
-rwxr-xr-xdata/themes/redandblack/circle-gray.pngbin0 -> 340 bytes
-rwxr-xr-xdata/themes/redandblack/circle-green.pngbin0 -> 360 bytes
-rwxr-xr-xdata/themes/redandblack/close_button.pngbin0 -> 562 bytes
-rw-r--r--data/themes/redandblack/colors.xml53
-rwxr-xr-xdata/themes/redandblack/deepbox.pngbin0 -> 703 bytes
-rwxr-xr-xdata/themes/redandblack/hscroll_left_default.pngbin0 -> 377 bytes
-rwxr-xr-xdata/themes/redandblack/hscroll_left_highlight.pngbin0 -> 367 bytes
-rwxr-xr-xdata/themes/redandblack/hscroll_left_pressed.pngbin0 -> 378 bytes
-rwxr-xr-xdata/themes/redandblack/hscroll_right_default.pngbin0 -> 395 bytes
-rwxr-xr-xdata/themes/redandblack/hscroll_right_highlight.pngbin0 -> 389 bytes
-rwxr-xr-xdata/themes/redandblack/hscroll_right_pressed.pngbin0 -> 396 bytes
-rwxr-xr-xdata/themes/redandblack/item_shortcut_bgr.pngbin0 -> 1507 bytes
-rwxr-xr-xdata/themes/redandblack/mouse.pngbin0 -> 4154 bytes
-rwxr-xr-xdata/themes/redandblack/radioin.pngbin0 -> 383 bytes
-rwxr-xr-xdata/themes/redandblack/radioin_highlight.pngbin0 -> 383 bytes
-rwxr-xr-xdata/themes/redandblack/radioout.pngbin0 -> 383 bytes
-rwxr-xr-xdata/themes/redandblack/radioout_highlight.pngbin0 -> 383 bytes
-rwxr-xr-xdata/themes/redandblack/resize.pngbin0 -> 538 bytes
-rwxr-xr-xdata/themes/redandblack/selection.pngbin0 -> 599 bytes
-rwxr-xr-xdata/themes/redandblack/slider.pngbin0 -> 618 bytes
-rwxr-xr-xdata/themes/redandblack/slider_hilight.pngbin0 -> 618 bytes
-rwxr-xr-xdata/themes/redandblack/speechbubble.xml18
-rwxr-xr-xdata/themes/redandblack/sticky_button.pngbin0 -> 456 bytes
-rwxr-xr-xdata/themes/redandblack/tab.pngbin0 -> 627 bytes
-rwxr-xr-xdata/themes/redandblack/tab_hilight.pngbin0 -> 627 bytes
-rwxr-xr-xdata/themes/redandblack/tabselected.pngbin0 -> 597 bytes
-rwxr-xr-xdata/themes/redandblack/target-cursor-blue-l.pngbin0 -> 20110 bytes
-rwxr-xr-xdata/themes/redandblack/target-cursor-blue-m.pngbin0 -> 15419 bytes
-rwxr-xr-xdata/themes/redandblack/target-cursor-blue-s.pngbin0 -> 7607 bytes
-rwxr-xr-xdata/themes/redandblack/target-cursor-red-l.pngbin0 -> 21602 bytes
-rwxr-xr-xdata/themes/redandblack/target-cursor-red-m.pngbin0 -> 15121 bytes
-rwxr-xr-xdata/themes/redandblack/target-cursor-red-s.pngbin0 -> 7406 bytes
-rwxr-xr-xdata/themes/redandblack/unknown-item.pngbin0 -> 540 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_down_default.pngbin0 -> 365 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_down_highlight.pngbin0 -> 356 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_down_pressed.pngbin0 -> 352 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_grey.pngbin0 -> 278 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_highlight.pngbin0 -> 278 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_up_default.pngbin0 -> 363 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_up_highlight.pngbin0 -> 353 bytes
-rwxr-xr-xdata/themes/redandblack/vscroll_up_pressed.pngbin0 -> 372 bytes
-rwxr-xr-xdata/themes/redandblack/window.pngbin0 -> 1055 bytes
-rwxr-xr-xdata/themes/redandblack/window.xml18
-rw-r--r--data/themes/wood/CMakeLists.txt53
-rwxr-xr-xdata/themes/wood/Makefile.am56
-rwxr-xr-xdata/themes/wood/bubble.pngbin0 -> 407 bytes
-rwxr-xr-xdata/themes/wood/button.pngbin0 -> 1463 bytes
-rwxr-xr-xdata/themes/wood/button_disabled.pngbin0 -> 1463 bytes
-rwxr-xr-xdata/themes/wood/buttonhi.pngbin0 -> 1530 bytes
-rwxr-xr-xdata/themes/wood/buttonpress.pngbin0 -> 1558 bytes
-rwxr-xr-xdata/themes/wood/checkbox.pngbin0 -> 537 bytes
-rwxr-xr-xdata/themes/wood/circle-gray.pngbin0 -> 300 bytes
-rwxr-xr-xdata/themes/wood/circle-green.pngbin0 -> 328 bytes
-rwxr-xr-xdata/themes/wood/close_button.pngbin0 -> 769 bytes
-rw-r--r--data/themes/wood/colors.xml53
-rwxr-xr-xdata/themes/wood/deepbox.pngbin0 -> 560 bytes
-rwxr-xr-xdata/themes/wood/hscroll_left_default.pngbin0 -> 478 bytes
-rwxr-xr-xdata/themes/wood/hscroll_left_highlight.pngbin0 -> 479 bytes
-rwxr-xr-xdata/themes/wood/hscroll_left_pressed.pngbin0 -> 470 bytes
-rwxr-xr-xdata/themes/wood/hscroll_right_default.pngbin0 -> 444 bytes
-rwxr-xr-xdata/themes/wood/hscroll_right_highlight.pngbin0 -> 484 bytes
-rwxr-xr-xdata/themes/wood/hscroll_right_pressed.pngbin0 -> 468 bytes
-rwxr-xr-xdata/themes/wood/item_shortcut_bgr.pngbin0 -> 1463 bytes
-rwxr-xr-xdata/themes/wood/mouse.pngbin0 -> 4508 bytes
-rwxr-xr-xdata/themes/wood/radioin.pngbin0 -> 636 bytes
-rwxr-xr-xdata/themes/wood/radioin_highlight.pngbin0 -> 652 bytes
-rwxr-xr-xdata/themes/wood/radioout.pngbin0 -> 528 bytes
-rwxr-xr-xdata/themes/wood/radioout_highlight.pngbin0 -> 528 bytes
-rwxr-xr-xdata/themes/wood/resize.pngbin0 -> 670 bytes
-rwxr-xr-xdata/themes/wood/selection.pngbin0 -> 739 bytes
-rwxr-xr-xdata/themes/wood/slider.pngbin0 -> 486 bytes
-rwxr-xr-xdata/themes/wood/slider_hilight.pngbin0 -> 468 bytes
-rwxr-xr-xdata/themes/wood/speechbubble.xml18
-rwxr-xr-xdata/themes/wood/sticky_button.pngbin0 -> 746 bytes
-rwxr-xr-xdata/themes/wood/tab.pngbin0 -> 1352 bytes
-rwxr-xr-xdata/themes/wood/tab_hilight.pngbin0 -> 1398 bytes
-rwxr-xr-xdata/themes/wood/tabselected.pngbin0 -> 1437 bytes
-rwxr-xr-xdata/themes/wood/target-cursor-blue-l.pngbin0 -> 23803 bytes
-rwxr-xr-xdata/themes/wood/target-cursor-blue-m.pngbin0 -> 18439 bytes
-rwxr-xr-xdata/themes/wood/target-cursor-blue-s.pngbin0 -> 8353 bytes
-rwxr-xr-xdata/themes/wood/target-cursor-red-l.pngbin0 -> 25586 bytes
-rwxr-xr-xdata/themes/wood/target-cursor-red-m.pngbin0 -> 17950 bytes
-rwxr-xr-xdata/themes/wood/target-cursor-red-s.pngbin0 -> 8361 bytes
-rwxr-xr-xdata/themes/wood/unknown-item.pngbin0 -> 540 bytes
-rwxr-xr-xdata/themes/wood/vscroll_down_default.pngbin0 -> 489 bytes
-rwxr-xr-xdata/themes/wood/vscroll_down_highlight.pngbin0 -> 486 bytes
-rwxr-xr-xdata/themes/wood/vscroll_down_pressed.pngbin0 -> 475 bytes
-rwxr-xr-xdata/themes/wood/vscroll_grey.pngbin0 -> 436 bytes
-rwxr-xr-xdata/themes/wood/vscroll_highlight.pngbin0 -> 446 bytes
-rwxr-xr-xdata/themes/wood/vscroll_up_default.pngbin0 -> 484 bytes
-rwxr-xr-xdata/themes/wood/vscroll_up_highlight.pngbin0 -> 481 bytes
-rwxr-xr-xdata/themes/wood/vscroll_up_pressed.pngbin0 -> 462 bytes
-rwxr-xr-xdata/themes/wood/window.pngbin0 -> 25969 bytes
-rwxr-xr-xdata/themes/wood/window.xml19
-rw-r--r--docs/FAQ.txt88
-rw-r--r--docs/HACKING.txt137
-rw-r--r--docs/Makefile.am9
-rw-r--r--docs/SOURCE/Doxyfile1153
-rw-r--r--docs/clientupdates.txt46
-rw-r--r--docs/example.mana24
-rw-r--r--docs/items.txt198
-rw-r--r--docs/manaplus.6104
-rw-r--r--docs/packages.txt250
-rw-r--r--docs/progression.txt129
-rw-r--r--docs/sounddev.txt38
-rwxr-xr-xmakecheck13
-rwxr-xr-xmakecheck23
-rwxr-xr-xmakeflawfinder4
-rwxr-xr-xmakegprof5
-rw-r--r--mana.cbp659
-rw-r--r--mana.config1
-rw-r--r--mana.creator1
-rw-r--r--mana.files754
-rw-r--r--mana.includes4
-rw-r--r--mana.xcodeproj/garfield.mode11329
-rw-r--r--mana.xcodeproj/garfield.mode1v31409
-rw-r--r--mana.xcodeproj/project.pbxproj2339
-rw-r--r--manaplus.desktop17
-rw-r--r--manaplus.menu4
-rw-r--r--packaging/debian/changelog77
-rw-r--r--packaging/debian/compat1
-rw-r--r--packaging/debian/control27
-rw-r--r--packaging/debian/copyright49
-rw-r--r--packaging/debian/mana-data.install5
-rw-r--r--packaging/debian/mana.desktop16
-rw-r--r--packaging/debian/mana.docs6
-rw-r--r--packaging/debian/mana.install5
-rw-r--r--packaging/debian/mana.sgml149
-rw-r--r--packaging/debian/patches/00list0
-rw-r--r--packaging/debian/rules69
-rw-r--r--packaging/debian/watch2
-rwxr-xr-xpackaging/windows/make-translations.sh6
-rw-r--r--packaging/windows/make-translations.vbs42
-rw-r--r--packaging/windows/portable.xml6
-rw-r--r--packaging/windows/readme.txt6
-rw-r--r--packaging/windows/setup.nsi336
-rw-r--r--packaging/windows/setup_finish.bmpbin0 -> 206243 bytes
-rw-r--r--packaging/windows/setup_welcome.bmpbin0 -> 206243 bytes
-rwxr-xr-xpackwin12
-rwxr-xr-xpmake27
-rw-r--r--po/CMakeLists.txt42
-rw-r--r--po/LINGUAS38
-rw-r--r--po/Makevars41
-rw-r--r--po/POTFILES.in102
-rw-r--r--po/ar.po3631
-rw-r--r--po/bg.po3559
-rw-r--r--po/ca.po3566
-rw-r--r--po/cs.po3720
-rw-r--r--po/da.po5711
-rw-r--r--po/de.po6558
-rw-r--r--po/en_GB.po5705
-rw-r--r--po/eo.po3561
-rw-r--r--po/es.po5740
-rw-r--r--po/et.po3568
-rw-r--r--po/fa.po3591
-rw-r--r--po/fi.po3763
-rw-r--r--po/fr.po5816
-rw-r--r--po/he.po3973
-rw-r--r--po/hr.po5665
-rw-r--r--po/hu.po5708
-rw-r--r--po/id.po3632
-rw-r--r--po/it.po5676
-rw-r--r--po/ja.po3991
-rw-r--r--po/ka.po3563
-rw-r--r--po/manaplus.pot4889
-rw-r--r--po/nb.po3685
-rw-r--r--po/nds.po3587
-rw-r--r--po/nl.po5642
-rw-r--r--po/pl.po5759
-rw-r--r--po/pt.po5689
-rw-r--r--po/pt_BR.po5722
-rw-r--r--po/ru.po5315
-rw-r--r--po/sk.po3632
-rw-r--r--po/sq.po3560
-rw-r--r--po/sv.po5761
-rw-r--r--po/te.po3598
-rw-r--r--po/th.po3585
-rw-r--r--po/tr.po3699
-rw-r--r--po/uk.po3889
-rw-r--r--po/zh_CN.po3966
-rw-r--r--po/zh_HK.po3696
-rw-r--r--po/zh_TW.po4177
-rw-r--r--src/CMakeLists.txt723
-rw-r--r--src/Makefile.am589
-rw-r--r--src/SDLMain.h11
-rw-r--r--src/SDLMain.m385
-rw-r--r--src/SDL_gfxBlitFunc.h128
-rw-r--r--src/actor.cpp64
-rw-r--r--src/actor.h128
-rw-r--r--src/actorsprite.cpp491
-rw-r--r--src/actorsprite.h255
-rw-r--r--src/actorspritelistener.h42
-rw-r--r--src/actorspritemanager.cpp1081
-rw-r--r--src/actorspritemanager.h253
-rw-r--r--src/animatedsprite.cpp241
-rw-r--r--src/animatedsprite.h97
-rw-r--r--src/animationparticle.cpp54
-rw-r--r--src/animationparticle.h48
-rw-r--r--src/avatar.cpp62
-rw-r--r--src/avatar.h189
-rw-r--r--src/being.cpp2009
-rw-r--r--src/being.h770
-rw-r--r--src/channel.cpp40
-rw-r--r--src/channel.h89
-rw-r--r--src/channelmanager.cpp91
-rw-r--r--src/channelmanager.h48
-rw-r--r--src/chatlog.cpp201
-rw-r--r--src/chatlog.h78
-rw-r--r--src/client.cpp1986
-rw-r--r--src/client.h317
-rw-r--r--src/commandhandler.cpp1124
-rw-r--r--src/commandhandler.h281
-rw-r--r--src/compoundsprite.cpp408
-rw-r--r--src/compoundsprite.h112
-rw-r--r--src/configlistener.h48
-rw-r--r--src/configuration.cpp438
-rw-r--r--src/configuration.h302
-rw-r--r--src/defaults.cpp253
-rw-r--r--src/defaults.h42
-rw-r--r--src/dropshortcut.cpp172
-rw-r--r--src/dropshortcut.h155
-rw-r--r--src/effectmanager.cpp107
-rw-r--r--src/effectmanager.h61
-rw-r--r--src/emoteshortcut.cpp89
-rw-r--r--src/emoteshortcut.h125
-rw-r--r--src/enet/ChangeLog86
-rw-r--r--src/enet/LICENSE7
-rw-r--r--src/enet/README15
-rw-r--r--src/enet/callbacks.c47
-rw-r--r--src/enet/callbacks.h27
-rw-r--r--src/enet/compress.c654
-rw-r--r--src/enet/design.txt117
-rw-r--r--src/enet/enet.h540
-rw-r--r--src/enet/host.c479
-rw-r--r--src/enet/list.c75
-rw-r--r--src/enet/list.h43
-rw-r--r--src/enet/packet.c159
-rw-r--r--src/enet/peer.c816
-rw-r--r--src/enet/protocol.c1671
-rw-r--r--src/enet/protocol.h196
-rw-r--r--src/enet/time.h18
-rw-r--r--src/enet/types.h13
-rw-r--r--src/enet/unix.c443
-rw-r--r--src/enet/unix.h45
-rw-r--r--src/enet/utility.h12
-rw-r--r--src/enet/win32.c348
-rw-r--r--src/enet/win32.h58
-rw-r--r--src/equipment.h94
-rw-r--r--src/event.cpp142
-rw-r--r--src/event.h175
-rw-r--r--src/filefilter.txt26
-rw-r--r--src/filefilter_more.txt12
-rw-r--r--src/flooritem.cpp133
-rw-r--r--src/flooritem.h92
-rw-r--r--src/game.cpp1501
-rw-r--r--src/game.h110
-rw-r--r--src/graphics.cpp426
-rw-r--r--src/graphics.h241
-rw-r--r--src/gui/beingpopup.cpp142
-rw-r--r--src/gui/beingpopup.h59
-rw-r--r--src/gui/botcheckerwindow.cpp413
-rw-r--r--src/gui/botcheckerwindow.h95
-rw-r--r--src/gui/buy.cpp323
-rw-r--r--src/gui/buy.h151
-rw-r--r--src/gui/buysell.cpp137
-rw-r--r--src/gui/buysell.h78
-rw-r--r--src/gui/changeemaildialog.cpp167
-rw-r--r--src/gui/changeemaildialog.h78
-rw-r--r--src/gui/changepassworddialog.cpp157
-rw-r--r--src/gui/changepassworddialog.h73
-rw-r--r--src/gui/charcreatedialog.cpp372
-rw-r--r--src/gui/charcreatedialog.h122
-rw-r--r--src/gui/charselectdialog.cpp456
-rw-r--r--src/gui/charselectdialog.h113
-rw-r--r--src/gui/chat.cpp1350
-rw-r--r--src/gui/chat.h318
-rw-r--r--src/gui/confirmdialog.cpp112
-rw-r--r--src/gui/confirmdialog.h57
-rw-r--r--src/gui/connectiondialog.cpp65
-rw-r--r--src/gui/connectiondialog.h62
-rw-r--r--src/gui/debugwindow.cpp248
-rw-r--r--src/gui/debugwindow.h72
-rw-r--r--src/gui/editdialog.cpp73
-rw-r--r--src/gui/editdialog.h66
-rw-r--r--src/gui/emotepopup.cpp214
-rw-r--r--src/gui/emotepopup.h121
-rw-r--r--src/gui/equipmentwindow.cpp260
-rw-r--r--src/gui/equipmentwindow.h98
-rw-r--r--src/gui/focushandler.cpp99
-rw-r--r--src/gui/focushandler.h77
-rw-r--r--src/gui/gui.cpp310
-rw-r--r--src/gui/gui.h148
-rw-r--r--src/gui/help.cpp106
-rw-r--r--src/gui/help.h76
-rw-r--r--src/gui/inventorywindow.cpp503
-rw-r--r--src/gui/inventorywindow.h155
-rw-r--r--src/gui/itemamount.cpp432
-rw-r--r--src/gui/itemamount.h124
-rw-r--r--src/gui/itempopup.cpp238
-rw-r--r--src/gui/itempopup.h71
-rw-r--r--src/gui/killstats.cpp424
-rw-r--r--src/gui/killstats.h132
-rw-r--r--src/gui/login.cpp231
-rw-r--r--src/gui/login.h90
-rw-r--r--src/gui/minimap.cpp292
-rw-r--r--src/gui/minimap.h69
-rw-r--r--src/gui/ministatus.cpp228
-rw-r--r--src/gui/ministatus.h94
-rw-r--r--src/gui/npcdialog.cpp483
-rw-r--r--src/gui/npcdialog.h232
-rw-r--r--src/gui/npcpostdialog.cpp128
-rw-r--r--src/gui/npcpostdialog.h70
-rw-r--r--src/gui/okdialog.cpp81
-rw-r--r--src/gui/okdialog.h57
-rw-r--r--src/gui/outfitwindow.cpp914
-rw-r--r--src/gui/outfitwindow.h135
-rw-r--r--src/gui/palette.cpp274
-rw-r--r--src/gui/palette.h191
-rw-r--r--src/gui/popupmenu.cpp1286
-rw-r--r--src/gui/popupmenu.h149
-rw-r--r--src/gui/quitdialog.cpp204
-rw-r--r--src/gui/quitdialog.h77
-rw-r--r--src/gui/register.cpp258
-rw-r--r--src/gui/register.h110
-rw-r--r--src/gui/sdlinput.cpp432
-rw-r--r--src/gui/sdlinput.h188
-rw-r--r--src/gui/sell.cpp333
-rw-r--r--src/gui/sell.h145
-rw-r--r--src/gui/serverdialog.cpp768
-rw-r--r--src/gui/serverdialog.h204
-rw-r--r--src/gui/setup.cpp178
-rw-r--r--src/gui/setup.h82
-rw-r--r--src/gui/setup_audio.cpp179
-rw-r--r--src/gui/setup_audio.h53
-rw-r--r--src/gui/setup_chat.cpp306
-rw-r--r--src/gui/setup_chat.h92
-rw-r--r--src/gui/setup_colors.cpp443
-rw-r--r--src/gui/setup_colors.h96
-rw-r--r--src/gui/setup_joystick.cpp101
-rw-r--r--src/gui/setup_joystick.h48
-rw-r--r--src/gui/setup_keyboard.cpp210
-rw-r--r--src/gui/setup_keyboard.h81
-rw-r--r--src/gui/setup_other.cpp426
-rw-r--r--src/gui/setup_other.h125
-rw-r--r--src/gui/setup_players.cpp505
-rw-r--r--src/gui/setup_players.h95
-rw-r--r--src/gui/setup_theme.cpp239
-rw-r--r--src/gui/setup_theme.h74
-rw-r--r--src/gui/setup_video.cpp819
-rw-r--r--src/gui/setup_video.h136
-rw-r--r--src/gui/shopwindow.cpp788
-rw-r--r--src/gui/shopwindow.h173
-rw-r--r--src/gui/shortcutwindow.cpp152
-rw-r--r--src/gui/shortcutwindow.h71
-rw-r--r--src/gui/skilldialog.cpp523
-rw-r--r--src/gui/skilldialog.h91
-rw-r--r--src/gui/socialwindow.cpp1306
-rw-r--r--src/gui/socialwindow.h159
-rw-r--r--src/gui/specialswindow.cpp257
-rw-r--r--src/gui/specialswindow.h73
-rw-r--r--src/gui/speechbubble.cpp91
-rw-r--r--src/gui/speechbubble.h58
-rw-r--r--src/gui/spellpopup.cpp105
-rw-r--r--src/gui/spellpopup.h67
-rw-r--r--src/gui/statuspopup.cpp543
-rw-r--r--src/gui/statuspopup.h78
-rw-r--r--src/gui/statuswindow.cpp880
-rw-r--r--src/gui/statuswindow.h99
-rw-r--r--src/gui/textcommandeditor.cpp390
-rw-r--r--src/gui/textcommandeditor.h105
-rw-r--r--src/gui/textdialog.cpp94
-rw-r--r--src/gui/textdialog.h74
-rw-r--r--src/gui/textpopup.cpp99
-rw-r--r--src/gui/textpopup.h68
-rw-r--r--src/gui/theme.cpp791
-rw-r--r--src/gui/theme.h273
-rw-r--r--src/gui/trade.cpp420
-rw-r--r--src/gui/trade.h170
-rw-r--r--src/gui/truetypefont.cpp336
-rw-r--r--src/gui/truetypefont.h104
-rw-r--r--src/gui/unregisterdialog.cpp145
-rw-r--r--src/gui/unregisterdialog.h68
-rw-r--r--src/gui/updatewindow.cpp672
-rw-r--r--src/gui/updatewindow.h210
-rw-r--r--src/gui/userpalette.cpp292
-rw-r--r--src/gui/userpalette.h222
-rw-r--r--src/gui/viewport.cpp763
-rw-r--r--src/gui/viewport.h298
-rw-r--r--src/gui/whoisonline.cpp550
-rw-r--r--src/gui/whoisonline.h139
-rw-r--r--src/gui/widgets/avatarlistbox.cpp346
-rw-r--r--src/gui/widgets/avatarlistbox.h70
-rw-r--r--src/gui/widgets/battletab.cpp54
-rw-r--r--src/gui/widgets/battletab.h47
-rw-r--r--src/gui/widgets/browserbox.cpp534
-rw-r--r--src/gui/widgets/browserbox.h205
-rw-r--r--src/gui/widgets/button.cpp227
-rw-r--r--src/gui/widgets/button.h94
-rw-r--r--src/gui/widgets/channeltab.cpp132
-rw-r--r--src/gui/widgets/channeltab.h62
-rw-r--r--src/gui/widgets/chattab.cpp431
-rw-r--r--src/gui/widgets/chattab.h173
-rw-r--r--src/gui/widgets/checkbox.cpp187
-rw-r--r--src/gui/widgets/checkbox.h92
-rw-r--r--src/gui/widgets/container.cpp33
-rw-r--r--src/gui/widgets/container.h43
-rw-r--r--src/gui/widgets/desktop.cpp157
-rw-r--r--src/gui/widgets/desktop.h73
-rw-r--r--src/gui/widgets/dropdown.cpp303
-rw-r--r--src/gui/widgets/dropdown.h97
-rw-r--r--src/gui/widgets/dropshortcutcontainer.cpp303
-rw-r--r--src/gui/widgets/dropshortcutcontainer.h88
-rw-r--r--src/gui/widgets/emoteshortcutcontainer.cpp259
-rw-r--r--src/gui/widgets/emoteshortcutcontainer.h84
-rw-r--r--src/gui/widgets/flowcontainer.cpp88
-rw-r--r--src/gui/widgets/flowcontainer.h73
-rw-r--r--src/gui/widgets/icon.cpp60
-rw-r--r--src/gui/widgets/icon.h66
-rw-r--r--src/gui/widgets/inttextfield.cpp112
-rw-r--r--src/gui/widgets/inttextfield.h76
-rw-r--r--src/gui/widgets/itemcontainer.cpp475
-rw-r--r--src/gui/widgets/itemcontainer.h195
-rw-r--r--src/gui/widgets/itemlinkhandler.cpp66
-rw-r--r--src/gui/widgets/itemlinkhandler.h47
-rw-r--r--src/gui/widgets/itemshortcutcontainer.cpp375
-rw-r--r--src/gui/widgets/itemshortcutcontainer.h93
-rw-r--r--src/gui/widgets/label.cpp38
-rw-r--r--src/gui/widgets/label.h52
-rw-r--r--src/gui/widgets/layout.cpp362
-rw-r--r--src/gui/widgets/layout.h319
-rw-r--r--src/gui/widgets/layouthelper.cpp63
-rw-r--r--src/gui/widgets/layouthelper.h90
-rw-r--r--src/gui/widgets/linkhandler.h42
-rw-r--r--src/gui/widgets/listbox.cpp146
-rw-r--r--src/gui/widgets/listbox.h78
-rw-r--r--src/gui/widgets/passwordfield.cpp36
-rw-r--r--src/gui/widgets/passwordfield.h46
-rw-r--r--src/gui/widgets/playerbox.cpp120
-rw-r--r--src/gui/widgets/playerbox.h74
-rw-r--r--src/gui/widgets/popup.cpp174
-rw-r--r--src/gui/widgets/popup.h174
-rw-r--r--src/gui/widgets/progressbar.cpp225
-rw-r--r--src/gui/widgets/progressbar.h139
-rw-r--r--src/gui/widgets/progressindicator.cpp78
-rw-r--r--src/gui/widgets/progressindicator.h45
-rw-r--r--src/gui/widgets/radiobutton.cpp163
-rw-r--r--src/gui/widgets/radiobutton.h85
-rw-r--r--src/gui/widgets/resizegrip.cpp82
-rw-r--r--src/gui/widgets/resizegrip.h60
-rw-r--r--src/gui/widgets/scrollarea.cpp445
-rw-r--r--src/gui/widgets/scrollarea.h151
-rw-r--r--src/gui/widgets/setuptab.cpp31
-rw-r--r--src/gui/widgets/setuptab.h64
-rw-r--r--src/gui/widgets/shopitems.cpp118
-rw-r--r--src/gui/widgets/shopitems.h120
-rw-r--r--src/gui/widgets/shoplistbox.cpp185
-rw-r--r--src/gui/widgets/shoplistbox.h104
-rw-r--r--src/gui/widgets/shortcutcontainer.cpp67
-rw-r--r--src/gui/widgets/shortcutcontainer.h115
-rw-r--r--src/gui/widgets/slider.cpp298
-rw-r--r--src/gui/widgets/slider.h98
-rw-r--r--src/gui/widgets/spellshortcutcontainer.cpp285
-rw-r--r--src/gui/widgets/spellshortcutcontainer.h88
-rw-r--r--src/gui/widgets/tab.cpp196
-rw-r--r--src/gui/widgets/tab.h80
-rw-r--r--src/gui/widgets/tabbedarea.cpp221
-rw-r--r--src/gui/widgets/tabbedarea.h129
-rw-r--r--src/gui/widgets/table.cpp585
-rw-r--r--src/gui/widgets/table.h195
-rw-r--r--src/gui/widgets/tablemodel.cpp173
-rw-r--r--src/gui/widgets/tablemodel.h149
-rw-r--r--src/gui/widgets/textbox.cpp149
-rw-r--r--src/gui/widgets/textbox.h70
-rw-r--r--src/gui/widgets/textfield.cpp306
-rw-r--r--src/gui/widgets/textfield.h110
-rw-r--r--src/gui/widgets/textpreview.cpp82
-rw-r--r--src/gui/widgets/textpreview.h130
-rw-r--r--src/gui/widgets/tradetab.cpp59
-rw-r--r--src/gui/widgets/tradetab.h50
-rw-r--r--src/gui/widgets/vertcontainer.cpp53
-rw-r--r--src/gui/widgets/vertcontainer.h52
-rw-r--r--src/gui/widgets/whispertab.cpp164
-rw-r--r--src/gui/widgets/whispertab.h67
-rw-r--r--src/gui/widgets/window.cpp924
-rw-r--r--src/gui/widgets/window.h441
-rw-r--r--src/gui/widgets/windowcontainer.cpp40
-rw-r--r--src/gui/widgets/windowcontainer.h59
-rw-r--r--src/gui/windowmenu.cpp285
-rw-r--r--src/gui/windowmenu.h82
-rw-r--r--src/gui/worldselectdialog.cpp139
-rw-r--r--src/gui/worldselectdialog.h73
-rw-r--r--src/guichanfwd.h101
-rw-r--r--src/guild.cpp296
-rw-r--r--src/guild.h199
-rw-r--r--src/imageparticle.cpp91
-rw-r--r--src/imageparticle.h61
-rw-r--r--src/imagesprite.cpp54
-rw-r--r--src/imagesprite.h79
-rw-r--r--src/inventory.cpp225
-rw-r--r--src/inventory.h160
-rw-r--r--src/item.cpp94
-rw-r--r--src/item.h167
-rw-r--r--src/itemshortcut.cpp155
-rw-r--r--src/itemshortcut.h146
-rw-r--r--src/joystick.cpp150
-rw-r--r--src/joystick.h114
-rw-r--r--src/keyboardconfig.cpp449
-rw-r--r--src/keyboardconfig.h333
-rw-r--r--src/listener.cpp43
-rw-r--r--src/listener.h45
-rw-r--r--src/localplayer.cpp3633
-rw-r--r--src/localplayer.h577
-rw-r--r--src/log.cpp213
-rw-r--r--src/log.h109
-rw-r--r--src/main.cpp261
-rw-r--r--src/main.h109
-rw-r--r--src/mana.rc23
-rw-r--r--src/map.cpp1654
-rw-r--r--src/map.h611
-rw-r--r--src/mumblemanager.cpp273
-rw-r--r--src/mumblemanager.h57
-rw-r--r--src/net/adminhandler.h60
-rw-r--r--src/net/beinghandler.h43
-rw-r--r--src/net/buysellhandler.h47
-rw-r--r--src/net/charhandler.cpp37
-rw-r--r--src/net/charhandler.h112
-rw-r--r--src/net/chathandler.h71
-rw-r--r--src/net/download.cpp355
-rw-r--r--src/net/download.h123
-rw-r--r--src/net/gamehandler.h62
-rw-r--r--src/net/generalhandler.h50
-rw-r--r--src/net/guildhandler.h76
-rw-r--r--src/net/inventoryhandler.h72
-rw-r--r--src/net/logindata.h95
-rw-r--r--src/net/loginhandler.h112
-rw-r--r--src/net/manaserv/adminhandler.cpp93
-rw-r--r--src/net/manaserv/adminhandler.h64
-rw-r--r--src/net/manaserv/attributes.cpp411
-rw-r--r--src/net/manaserv/attributes.h72
-rw-r--r--src/net/manaserv/beinghandler.cpp385
-rw-r--r--src/net/manaserv/beinghandler.h73
-rw-r--r--src/net/manaserv/buysellhandler.cpp132
-rw-r--r--src/net/manaserv/buysellhandler.h57
-rw-r--r--src/net/manaserv/charhandler.cpp406
-rw-r--r--src/net/manaserv/charhandler.h119
-rw-r--r--src/net/manaserv/chathandler.cpp472
-rw-r--r--src/net/manaserv/chathandler.h139
-rw-r--r--src/net/manaserv/connection.cpp113
-rw-r--r--src/net/manaserv/connection.h89
-rw-r--r--src/net/manaserv/defines.h77
-rw-r--r--src/net/manaserv/effecthandler.cpp80
-rw-r--r--src/net/manaserv/effecthandler.h44
-rw-r--r--src/net/manaserv/gamehandler.cpp154
-rw-r--r--src/net/manaserv/gamehandler.h74
-rw-r--r--src/net/manaserv/generalhandler.cpp211
-rw-r--r--src/net/manaserv/generalhandler.h78
-rw-r--r--src/net/manaserv/guildhandler.cpp360
-rw-r--r--src/net/manaserv/guildhandler.h84
-rw-r--r--src/net/manaserv/internal.cpp27
-rw-r--r--src/net/manaserv/internal.h30
-rw-r--r--src/net/manaserv/inventoryhandler.cpp219
-rw-r--r--src/net/manaserv/inventoryhandler.h109
-rw-r--r--src/net/manaserv/itemhandler.cpp90
-rw-r--r--src/net/manaserv/itemhandler.h40
-rw-r--r--src/net/manaserv/loginhandler.cpp479
-rw-r--r--src/net/manaserv/loginhandler.h99
-rw-r--r--src/net/manaserv/messagehandler.cpp36
-rw-r--r--src/net/manaserv/messagehandler.h44
-rw-r--r--src/net/manaserv/messagein.cpp62
-rw-r--r--src/net/manaserv/messagein.h49
-rw-r--r--src/net/manaserv/messageout.cpp65
-rw-r--r--src/net/manaserv/messageout.h59
-rw-r--r--src/net/manaserv/network.cpp178
-rw-r--r--src/net/manaserv/network.h75
-rw-r--r--src/net/manaserv/npchandler.cpp237
-rw-r--r--src/net/manaserv/npchandler.h89
-rw-r--r--src/net/manaserv/partyhandler.cpp197
-rw-r--r--src/net/manaserv/partyhandler.h82
-rw-r--r--src/net/manaserv/playerhandler.cpp440
-rw-r--r--src/net/manaserv/playerhandler.h85
-rw-r--r--src/net/manaserv/protocol.h392
-rw-r--r--src/net/manaserv/specialhandler.cpp70
-rw-r--r--src/net/manaserv/specialhandler.h56
-rw-r--r--src/net/manaserv/tradehandler.cpp237
-rw-r--r--src/net/manaserv/tradehandler.h82
-rw-r--r--src/net/messagehandler.h50
-rw-r--r--src/net/messagein.cpp227
-rw-r--r--src/net/messagein.h118
-rw-r--r--src/net/messageout.cpp92
-rw-r--r--src/net/messageout.h91
-rw-r--r--src/net/net.cpp198
-rw-r--r--src/net/net.h81
-rw-r--r--src/net/npchandler.h66
-rw-r--r--src/net/packetcounters.cpp128
-rw-r--r--src/net/packetcounters.h55
-rw-r--r--src/net/partyhandler.h82
-rw-r--r--src/net/playerhandler.h75
-rw-r--r--src/net/serverinfo.h117
-rw-r--r--src/net/specialhandler.h45
-rw-r--r--src/net/tmwa/adminhandler.cpp135
-rw-r--r--src/net/tmwa/adminhandler.h69
-rw-r--r--src/net/tmwa/beinghandler.cpp1075
-rw-r--r--src/net/tmwa/beinghandler.h53
-rw-r--r--src/net/tmwa/buysellhandler.cpp231
-rw-r--r--src/net/tmwa/buysellhandler.h59
-rw-r--r--src/net/tmwa/charserverhandler.cpp386
-rw-r--r--src/net/tmwa/charserverhandler.h87
-rw-r--r--src/net/tmwa/chathandler.cpp552
-rw-r--r--src/net/tmwa/chathandler.h87
-rw-r--r--src/net/tmwa/gamehandler.cpp196
-rw-r--r--src/net/tmwa/gamehandler.h85
-rw-r--r--src/net/tmwa/generalhandler.cpp285
-rw-r--r--src/net/tmwa/generalhandler.h83
-rw-r--r--src/net/tmwa/gui/guildtab.cpp150
-rw-r--r--src/net/tmwa/gui/guildtab.h57
-rw-r--r--src/net/tmwa/gui/partytab.cpp242
-rw-r--r--src/net/tmwa/gui/partytab.h57
-rw-r--r--src/net/tmwa/guildhandler.cpp780
-rw-r--r--src/net/tmwa/guildhandler.h84
-rw-r--r--src/net/tmwa/inventoryhandler.cpp609
-rw-r--r--src/net/tmwa/inventoryhandler.h177
-rw-r--r--src/net/tmwa/itemhandler.cpp93
-rw-r--r--src/net/tmwa/itemhandler.h40
-rw-r--r--src/net/tmwa/loginhandler.cpp342
-rw-r--r--src/net/tmwa/loginhandler.h105
-rw-r--r--src/net/tmwa/messagehandler.cpp48
-rw-r--r--src/net/tmwa/messagehandler.h59
-rw-r--r--src/net/tmwa/messagein.cpp85
-rw-r--r--src/net/tmwa/messagein.h52
-rw-r--r--src/net/tmwa/messageout.cpp142
-rw-r--r--src/net/tmwa/messageout.h65
-rw-r--r--src/net/tmwa/network.cpp483
-rw-r--r--src/net/tmwa/network.h136
-rw-r--r--src/net/tmwa/npchandler.cpp249
-rw-r--r--src/net/tmwa/npchandler.h90
-rw-r--r--src/net/tmwa/partyhandler.cpp547
-rw-r--r--src/net/tmwa/partyhandler.h85
-rw-r--r--src/net/tmwa/playerhandler.cpp752
-rw-r--r--src/net/tmwa/playerhandler.h74
-rw-r--r--src/net/tmwa/protocol.h327
-rw-r--r--src/net/tmwa/specialhandler.cpp273
-rw-r--r--src/net/tmwa/specialhandler.h57
-rw-r--r--src/net/tmwa/token.h43
-rw-r--r--src/net/tmwa/tradehandler.cpp347
-rw-r--r--src/net/tmwa/tradehandler.h65
-rw-r--r--src/net/tradehandler.h67
-rw-r--r--src/net/worldinfo.h39
-rw-r--r--src/opengl1graphics.cpp603
-rw-r--r--src/opengl1graphics.h133
-rw-r--r--src/openglgraphics.cpp950
-rw-r--r--src/openglgraphics.h146
-rw-r--r--src/particle.cpp450
-rw-r--r--src/particle.h331
-rw-r--r--src/particlecontainer.cpp189
-rw-r--r--src/particlecontainer.h121
-rw-r--r--src/particleemitter.cpp568
-rw-r--r--src/particleemitter.h153
-rw-r--r--src/particleemitterprop.h116
-rw-r--r--src/party.cpp258
-rw-r--r--src/party.h168
-rw-r--r--src/playerinfo.cpp330
-rw-r--r--src/playerinfo.h238
-rw-r--r--src/playerrelations.cpp496
-rw-r--r--src/playerrelations.h251
-rw-r--r--src/position.cpp45
-rw-r--r--src/position.h55
-rw-r--r--src/properties.h126
-rw-r--r--src/resources/action.cpp52
-rw-r--r--src/resources/action.h51
-rw-r--r--src/resources/ambientlayer.cpp126
-rw-r--r--src/resources/ambientlayer.h59
-rw-r--r--src/resources/ambientoverlay.cpp126
-rw-r--r--src/resources/ambientoverlay.h60
-rw-r--r--src/resources/animation.cpp46
-rw-r--r--src/resources/animation.h90
-rw-r--r--src/resources/beinginfo.cpp115
-rw-r--r--src/resources/beinginfo.h161
-rw-r--r--src/resources/colordb.cpp115
-rw-r--r--src/resources/colordb.h51
-rw-r--r--src/resources/dye.cpp320
-rw-r--r--src/resources/dye.h107
-rw-r--r--src/resources/emotedb.cpp222
-rw-r--r--src/resources/emotedb.h64
-rw-r--r--src/resources/image.cpp797
-rw-r--r--src/resources/image.h308
-rw-r--r--src/resources/imageloader.cpp114
-rw-r--r--src/resources/imageloader.h69
-rw-r--r--src/resources/imageset.cpp64
-rw-r--r--src/resources/imageset.h72
-rw-r--r--src/resources/imagewriter.cpp111
-rw-r--r--src/resources/imagewriter.h31
-rw-r--r--src/resources/itemdb.cpp463
-rw-r--r--src/resources/itemdb.h79
-rw-r--r--src/resources/iteminfo.cpp66
-rw-r--r--src/resources/iteminfo.h242
-rw-r--r--src/resources/mapreader.cpp723
-rw-r--r--src/resources/mapreader.h78
-rw-r--r--src/resources/monsterdb.cpp199
-rw-r--r--src/resources/monsterdb.h39
-rw-r--r--src/resources/music.cpp84
-rw-r--r--src/resources/music.h81
-rw-r--r--src/resources/npcdb.cpp127
-rw-r--r--src/resources/npcdb.h39
-rw-r--r--src/resources/resource.cpp58
-rw-r--r--src/resources/resource.h81
-rw-r--r--src/resources/resourcemanager.cpp658
-rw-r--r--src/resources/resourcemanager.h265
-rw-r--r--src/resources/soundeffect.cpp58
-rw-r--r--src/resources/soundeffect.h75
-rw-r--r--src/resources/specialdb.cpp132
-rw-r--r--src/resources/specialdb.h72
-rw-r--r--src/resources/spritedef.cpp339
-rw-r--r--src/resources/spritedef.h176
-rw-r--r--src/resources/wallpaper.cpp172
-rw-r--r--src/resources/wallpaper.h50
-rw-r--r--src/rotationalparticle.cpp82
-rw-r--r--src/rotationalparticle.h48
-rw-r--r--src/shopitem.cpp95
-rw-r--r--src/shopitem.h140
-rw-r--r--src/simpleanimation.cpp212
-rw-r--r--src/simpleanimation.h86
-rw-r--r--src/sound.cpp344
-rw-r--r--src/sound.h130
-rw-r--r--src/spellmanager.cpp346
-rw-r--r--src/spellmanager.h76
-rw-r--r--src/spellshortcut.cpp71
-rw-r--r--src/spellshortcut.h91
-rw-r--r--src/sprite.h110
-rw-r--r--src/statuseffect.cpp205
-rw-r--r--src/statuseffect.h112
-rw-r--r--src/text.cpp194
-rw-r--r--src/text.h113
-rw-r--r--src/textcommand.cpp115
-rw-r--r--src/textcommand.h173
-rw-r--r--src/textmanager.cpp170
-rw-r--r--src/textmanager.h82
-rw-r--r--src/textparticle.cpp69
-rw-r--r--src/textparticle.h54
-rw-r--r--src/textrenderer.h78
-rw-r--r--src/tileset.h53
-rw-r--r--src/units.cpp248
-rw-r--r--src/units.h46
-rw-r--r--src/utils/base64.cpp170
-rw-r--r--src/utils/base64.h36
-rw-r--r--src/utils/copynpaste.cpp324
-rw-r--r--src/utils/copynpaste.h33
-rw-r--r--src/utils/dtor.h54
-rw-r--r--src/utils/gettext.h44
-rw-r--r--src/utils/mathutils.h114
-rw-r--r--src/utils/mkdir.cpp118
-rw-r--r--src/utils/mkdir.h26
-rw-r--r--src/utils/mutex.h97
-rw-r--r--src/utils/sha256.cpp294
-rw-r--r--src/utils/sha256.h35
-rw-r--r--src/utils/specialfolder.cpp78
-rw-r--r--src/utils/specialfolder.h30
-rw-r--r--src/utils/stringutils.cpp360
-rw-r--r--src/utils/stringutils.h159
-rw-r--r--src/utils/xml.cpp164
-rw-r--r--src/utils/xml.h101
-rw-r--r--src/variabledata.h113
-rw-r--r--src/vector.cpp28
-rw-r--r--src/vector.h199
-rw-r--r--src/winver.h6
-rw-r--r--src/winver.h.in6
-rw-r--r--toolchain.cmake33
-rw-r--r--tools/Reorganize.java198
-rw-r--r--tools/adler32.c68
-rw-r--r--tools/dyecmd/CMakeLists.txt28
-rw-r--r--tools/dyecmd/README12
-rw-r--r--tools/dyecmd/dyecmd.cbp56
-rw-r--r--tools/dyecmd/run.cmd1
-rw-r--r--tools/dyecmd/src/CMakeLists.txt59
-rwxr-xr-xtools/dyecmd/src/dye.cpp202
-rwxr-xr-xtools/dyecmd/src/dye.h105
-rwxr-xr-xtools/dyecmd/src/dyecmd.cpp155
-rwxr-xr-xtools/dyecmd/src/imagewriter.cpp113
-rwxr-xr-xtools/dyecmd/src/imagewriter.h31
-rw-r--r--tools/tmxcopy/base64.cpp148
-rw-r--r--tools/tmxcopy/base64.h36
-rw-r--r--tools/tmxcopy/map.cpp679
-rw-r--r--tools/tmxcopy/map.hpp183
-rw-r--r--tools/tmxcopy/readme.txt104
-rw-r--r--tools/tmxcopy/tmx_random_fill.cpp115
-rw-r--r--tools/tmxcopy/tmxcollide.cpp103
-rw-r--r--tools/tmxcopy/tmxcopy.cbp39
-rw-r--r--tools/tmxcopy/tmxcopy.cpp106
-rw-r--r--tools/tmxcopy/tostring.h35
-rw-r--r--tools/tmxcopy/xmlutils.cpp75
-rw-r--r--tools/tmxcopy/xmlutils.h61
-rw-r--r--tools/tmxcopy/zlibutils.cpp122
-rw-r--r--tools/tmxcopy/zlibutils.h11
-rw-r--r--tools/upalyzer/analyze.php191
-rwxr-xr-xtools/update-copyright.sh24
-rwxr-xr-xupdate-creator.sh8
1057 files changed, 319835 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..4a8456907
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,120 @@
+# files created by autoreconf
+ABOUT-NLS
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.guess
+config.h.in
+config.h.in~
+config.rpath
+config.sub
+configure
+depcomp
+install-sh
+m4/
+missing
+po/Makefile.in.in
+po/Makevars.template
+po/Rules-quot
+po/boldquot.sed
+po/en@boldquot.header
+po/en@quot.header
+po/insert-header.sin
+po/quot.sed
+po/remove-potcdate.*
+po/*.po~
+
+# files created by configure
+Makefile
+config.h
+config.log
+config.status
+config.status.lineno
+po/POTFILES
+.deps
+stamp-h1
+
+# files created by CMake
+CMakeFiles/
+CMakeCache.txt
+CPackConfig.cmake
+CPackSourceConfig.cmake
+cmake_install.cmake
+install_manifest.txt
+
+# files created during build
+*.o
+*.gmo
+*.gcda
+*.gcno
+.dirstamp
+po/stamp-po
+src/tmw
+src/tmw-ea
+src/mana
+src/mana-ea
+src/manaplus
+
+# files created during Windows build
+.objs
+*.dll
+*.exe
+tmw.depend
+tmw.layout
+mana.depend
+mana.layout
+
+# files copied in on Windows
+include/*
+lib/*
+packaging/windows/upx/*
+data/music/*.ogg
+
+# files created by Qt Creator
+mana.creator.user*
+
+run/*
+my/*
+win/*
+make.log
+make1.log
+make2.log
+make_nsiqcppstyle.txt
+bcmake1
+bmake1
+gprof.png
+gprof.txt
+gmon.out
+makecheck.txt
+makecheck_err.txt
+makeflawfinder.log
+makegprof1
+pmake1
+packwin1
+toolchain.cmake1
+makerats.log
+make_hc.txt
+make_hc2.txt
+
+# debian
+debian/*
+build-stamp
+
+# files created by gtags
+GPATH
+GRTAGS
+GSYMS
+GTAGS
+
+# generated for nsis build
+translations/*
+
+# documentation generated by Doxygen
+docs/SOURCE/html/*
+
+*.kdev4
+
+gmon.out
+
+# patch files created by git
+[0-9][0-9][0-9][0-9]-*.patch
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 000000000..3a5b083ac
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,13 @@
+Blue <bluesansdouze@gmail.com>
+Cédric Borgese <cedric.borgese@gmail.com>
+Thorbjørn Lindeijer <bjorn@lindeijer.nl>
+Thorbjørn Lindeijer <thorbjorn.lindeijer@nokia.com>
+Thorbjørn Lindeijer <bjorn@horst-dieter.(none)>
+Dennis Friis <peavey@inspircd.org>
+Falkreon <Falkreon@.(none)>
+Ira Rice <irarice@gmail.com>
+Majin Sniper <sniper@livecd.janhome.net>
+Maximilian Philipps <turmfalke@Turmfalke.(none)>
+remoitnane <remoit(DOT)nane(AT)gmail(DOT)com>
+Victor Fury <frictor@unknown>
+Andrei Karas <akaras@inbox.ru>
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 000000000..749e72ce1
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,71 @@
+-----------------------
+-- Mana Contributors --
+-----------------------
+
+ This file lists all contributors up to the current release. Check the wiki
+ for the currently active development team.
+
+== Contributors to client/server development ==
+
+Aaron Marks <nymacro gmail.com>
+Alexander Baldeck (Shura) <alexander archlinux.org>
+Andreas Habel <mail exceptionfault.de>
+Andrei Karas (4144) <akaras inbox.ru>
+Andrej Sinicyn <andrej4000 gmail.com>
+Bernd Wachter (Aard) <bwachter-tmw lart.info>
+Blue Sans Douze (Blue112) <bluesansdouze gmail.com>
+Bjrn Steinbrink (Doener) <b.steinbrink gmx.de>
+Cedric Borgese (moi1392) <cedric.borgese gmail.com>
+Chuck Miller (Kage) <shadowmil gmail.com>
+Daniel Bradshaw <daniel+commits the-cell.co.uk>
+David Athay (trapdoor) <ko2fan gmail.com>
+Dennis Friis <peavey placid.dk>
+Douglas Boffey <dougaboffey netscape.net>
+Duane Bailey <nayryeliab gmail.com>
+Eugenio Favalli <elvenprogrammer gmail.com>
+Eric Scrivner <zenogais gmail.com>
+Fate <fate.tmw googlemail.com>
+Fredrik Reveny <chetic gmail.com>
+Freeyorp <Freeyorp101 NOSPAM hotmail.com>
+Guillaume Melquiond (Silene) <guillaume.melquiond gmail.com>
+Ira Rice (Tametomo) <irarice gmail.com>
+Jan-Fabian Humann (Mra) <malastare gmx.net>
+Jared Adams <jaxad0127 gmail.com>
+Jos vila <linux javila.net>
+Joshua Langley <joshlangley optusnet.com.au>
+Kess Vargavind <vargavind gmail.com>
+Kiyoshi Kyokai <kiyoshi.kyokai gmail.com>
+Krzysztof Daszuta <irukard gmail.com>
+Lloyd Bryant <lloyd_bryant netzero.net>
+Marcel W. Wysocki <maci satgnu.org>
+Mateusz Kaduk (Usiu) <mateusz.kaduk gmail.com>
+Matthias Hartmann <hartmann.matthias gmail.com>
+Philipp Sehmisch (Crush) <tmw crushnet.org>
+Roderic Morris (rodge) <roderic ccs.neu.edu>
+Rogier Polak <rogier.l.a.polak gmail.com>
+Scott Ellis <quiche_on_a_leash hotmail.co.uk>
+Simon Edwardsson <simon crossnet.se>
+Stefan Dombrowski <stefan uni-bonn.de>
+Steve Cotton <steve s.cotton.clara.co.uk>
+Thorbjrn Lindeijer <thorbjorn lindeijer.nl>
+Maximilian Philipps <Turmfalke2007 web.de>
+Yohann Ferreira <bertram cegetel.net>
+
+== Translators ==
+
+Alexander Breidenbroich (German) <metast gmx.de>
+Blue Sans Douze (French) <bluesansdouze gmail.com>
+Eugenio Favalli (Italian) <elvenprogrammer gmail.com>
+Jonathan Kolberg (German) <bulldog98 freenet.de>
+Jumpy (French) <antoinebcn@hotmail.com>
+Kess Vargavind (Swedish) <vargavind gmail.com>
+Leif Kildelund (Danish) <gonzo.dark gmail.com>
+Matthias Hartmann (German) <hartmann.matthias gmail.com>
+Thorbjrn Lindeijer (Dutch) <thorbjorn lindeijer.nl>
+
+== Other contributors ==
+
+Jean-Francois Lampron <sull.kf gmail.com>
+Rodney Dawes <dobey novell.com>
+Ultramichy
+Zuzanna K. Filutowska <platyna users.sourceforge.net>
diff --git a/CMake/Modules/FindENet.cmake b/CMake/Modules/FindENet.cmake
new file mode 100644
index 000000000..98da51a3d
--- /dev/null
+++ b/CMake/Modules/FindENet.cmake
@@ -0,0 +1,52 @@
+# - Try to find enet
+# Once done this will define
+#
+# ENET_FOUND - system has enet
+# ENET_INCLUDE_DIR - the enet include directory
+# ENET_LIBRARIES - the libraries needed to use enet
+# ENET_DEFINITIONS - Compiler switches required for using enet
+
+IF (ENet_INCLUDE_DIR AND ENet_LIBRARY)
+ SET(ENet_FIND_QUIETLY TRUE)
+ENDIF (ENet_INCLUDE_DIR AND ENet_LIBRARY)
+
+# for Windows we rely on the environement variables
+# %INCLUDE% and %LIB%; FIND_LIBRARY checks %LIB%
+# automatically on Windows
+IF(WIN32)
+ FIND_PATH(ENet_INCLUDE_DIR enet/enet.h
+ $ENV{INCLUDE}
+ )
+ FIND_LIBRARY(ENet_LIBRARY
+ NAMES enet
+ )
+ELSE()
+ FIND_PATH(ENet_INCLUDE_DIR enet/enet.h
+ /usr/include
+ /usr/local/include
+ )
+ FIND_LIBRARY(ENet_LIBRARY
+ NAMES enet
+ PATHS /usr/lib /usr/local/lib
+ )
+ENDIF()
+
+IF (ENet_INCLUDE_DIR AND ENet_LIBRARY)
+ SET(ENET_FOUND TRUE)
+ SET(ENET_INCLUDE_DIR ${ENet_INCLUDE_DIR})
+ SET(ENET_LIBRARIES ${ENet_LIBRARY})
+ELSE ()
+ SET(ENET_FOUND FALSE)
+ENDIF ()
+
+IF (ENET_FOUND)
+ IF (NOT ENet_FIND_QUIETLY)
+ MESSAGE(STATUS "Found enet: ${ENet_LIBRARY}")
+ ENDIF (NOT ENet_FIND_QUIETLY)
+ELSE (ENET_FOUND)
+ IF (ENet_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could NOT find enet")
+ ENDIF (ENet_FIND_REQUIRED)
+ENDIF (ENET_FOUND)
+
+MARK_AS_ADVANCED(ENet_INCLUDE_DIR ENet_LIBRARY)
diff --git a/CMake/Modules/FindGuichan.cmake b/CMake/Modules/FindGuichan.cmake
new file mode 100644
index 000000000..dbc863e2f
--- /dev/null
+++ b/CMake/Modules/FindGuichan.cmake
@@ -0,0 +1,100 @@
+# - Try to find Guichan
+# Once done this will define
+#
+# GUICHAN_FOUND - system has Guichan
+# GUICHAN_INCLUDE_DIR - the Guichan include directory
+# GUICHAN_LIBRARIES - the libraries needed to use Guichan
+#
+# Supported components: SDL OpenGL
+#
+# TODO: Clean up the components stuff and try to add all known
+# components when none are specified. May not bail out for not found
+# components then, set some var instead...
+
+# Be quiet if Guichan was already found
+# We need an extra variable to have the check per component
+
+IF (Guichan_INCLUDE_DIR AND Guichan_LIBRARY)
+ SET(Guichan_QUIET TRUE)
+ENDIF ()
+
+FIND_PATH(Guichan_INCLUDE_DIR
+ NAMES guichan.hpp
+ PATHS /usr/include /usr/local/include
+ )
+
+FIND_LIBRARY(Guichan_LIBRARY
+ NAMES guichan
+ PATHS /usr/lib /usr/local/lib
+ )
+
+MARK_AS_ADVANCED(Guichan_INCLUDE_DIR Guichan_LIBRARY)
+
+IF (Guichan_INCLUDE_DIR AND Guichan_LIBRARY)
+ SET(GUICHAN_FOUND TRUE)
+ SET(GUICHAN_INCLUDE_DIR ${Guichan_INCLUDE_DIR})
+ SET(GUICHAN_LIBRARIES ${Guichan_LIBRARY})
+
+ IF (NOT Guichan_FIND_QUIETLY AND NOT Guichan_QUIET)
+ MESSAGE(STATUS "Found Guichan: ${Guichan_LIBRARY}")
+ ENDIF ()
+ENDIF ()
+
+# Bail out if Guichan is not found but required
+IF (NOT GUICHAN_FOUND AND Guichan_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could NOT find Guichan library ${GUICHAN_INCLUDE_DIR}")
+ENDIF ()
+
+# Check for guichan components
+FOREACH (COMPONENT ${Guichan_FIND_COMPONENTS})
+ SET(COMPONENT_FOUND FALSE)
+
+ IF (COMPONENT STREQUAL "SDL")
+ SET(COMPONENT_FOUND TRUE)
+ SET(Guichan_HEADER "guichan/sdl.hpp")
+ SET(Guichan_LIBRARY "guichan_sdl")
+ ENDIF ()
+
+ IF (COMPONENT STREQUAL "OpenGL")
+ SET(COMPONENT_FOUND TRUE)
+ SET(Guichan_HEADER "guichan/opengl.hpp")
+ SET(Guichan_LIBRARY "guichan_opengl")
+ ENDIF ()
+
+ IF (NOT COMPONENT_FOUND)
+ MESSAGE(FATAL_ERROR "Invalid Guichan component: ${COMPONENT}")
+ ENDIF (NOT COMPONENT_FOUND)
+
+ # Check if we already found this component
+ IF (Guichan_LIBRARY_${COMPONENT})
+ SET(Guichan_QUIET TRUE)
+ ELSE ()
+ SET(Guichan_QUIET FALSE)
+ ENDIF ()
+
+ FIND_LIBRARY(Guichan_LIBRARY_${COMPONENT}
+ NAMES ${Guichan_LIBRARY}
+ PATHS /usr/lib /usr/local/lib
+ )
+
+ MARK_AS_ADVANCED(Guichan_LIBRARY_${COMPONENT})
+
+ IF (NOT EXISTS ${Guichan_INCLUDE_DIR}/${Guichan_HEADER} OR
+ NOT Guichan_LIBRARY_${COMPONENT})
+ SET(GUICHAN_FOUND FALSE)
+ MESSAGE(FATAL_ERROR "Could NOT find Guichan component ${COMPONENT}")
+ ENDIF ()
+
+ # Check guichan >= 0.8.0 by searching for the widgetlistener.hpp file.
+ SET(Guichan_HEADER "guichan/widgetlistener.hpp")
+ IF (NOT EXISTS ${Guichan_INCLUDE_DIR}/${Guichan_HEADER})
+ SET(GUICHAN_FOUND FALSE)
+ MESSAGE(FATAL_ERROR "Guichan version is less than 0.8.0")
+ ENDIF()
+
+ IF (NOT Guichan_FIND_QUIETLY AND NOT Guichan_QUIET)
+ MESSAGE(STATUS "Found Guichan ${COMPONENT}: ${Guichan_LIBRARY_${COMPONENT}}")
+ ENDIF ()
+
+ SET(GUICHAN_LIBRARIES ${GUICHAN_LIBRARIES} ${Guichan_LIBRARY_${COMPONENT}})
+ENDFOREACH()
diff --git a/CMake/Modules/FindLibIntl.cmake b/CMake/Modules/FindLibIntl.cmake
new file mode 100644
index 000000000..e75960525
--- /dev/null
+++ b/CMake/Modules/FindLibIntl.cmake
@@ -0,0 +1,46 @@
+# Try to find the libintl library. Explicit searching is currently
+# only required for Win32, though it might be useful for some UNIX
+# variants, too. Therefore code for searching common UNIX include
+# directories is included, too.
+#
+# Once done this will define
+#
+# LIBINTL_FOUND - system has libintl
+# LIBINTL_LIBRARIES - the library needed for linking
+
+IF (LibIntl_LIBRARY)
+ SET(LibIntl_FIND_QUIETLY TRUE)
+ENDIF ()
+
+# for Windows we rely on the environement variables
+# %INCLUDE% and %LIB%; FIND_LIBRARY checks %LIB%
+# automatically on Windows
+IF(WIN32)
+ FIND_LIBRARY(LibIntl_LIBRARY
+ NAMES intl
+ )
+ELSE()
+ FIND_LIBRARY(LibIntl_LIBRARY
+ NAMES intl
+ PATHS /usr/lib /usr/local/lib
+ )
+ENDIF()
+
+IF (LibIntl_LIBRARY)
+ SET(LIBINTL_FOUND TRUE)
+ SET(LIBINTL_LIBRARIES ${LibIntl_LIBRARY})
+ELSE ()
+ SET(LIBINTL_FOUND FALSE)
+ENDIF ()
+
+IF (LIBINTL_FOUND)
+ IF (NOT LibIntl_FIND_QUIETLY)
+ MESSAGE(STATUS "Found libintl: ${LibIntl_LIBRARY}")
+ ENDIF ()
+ELSE ()
+ IF (LibIntl_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could NOT find libintl")
+ ENDIF ()
+ENDIF ()
+
+MARK_AS_ADVANCED(LibIntl_LIBRARY)
diff --git a/CMake/Modules/FindSDL_gfx.cmake b/CMake/Modules/FindSDL_gfx.cmake
new file mode 100644
index 000000000..74c1c6c74
--- /dev/null
+++ b/CMake/Modules/FindSDL_gfx.cmake
@@ -0,0 +1,39 @@
+# - Try to find SDL_gfx
+# Once done this will define
+#
+# SDLGFX_FOUND - system has SDL_gfx
+# SDLGFX_INCLUDE_DIR - the SDL_gfx include directory
+
+# Be quiet if SDL_gfx was already found
+IF (SDL_gfx_INCLUDE_DIR AND SDL_gfx_LIBRARY)
+ SET(SDL_gfx_QUIET TRUE)
+ENDIF (SDL_gfx_INCLUDE_DIR AND SDL_gfx_LIBRARY)
+
+
+FIND_PATH(SDL_gfx_INCLUDE_DIR
+ NAMES SDL_rotozoom.h
+ PATH_SUFFIXES SDL
+ )
+
+FIND_LIBRARY(SDL_gfx_LIBRARY
+ NAMES SDL_gfx
+ PATHS /usr/lib /usr/local/lib
+ )
+
+MARK_AS_ADVANCED(SDL_gfx_INCLUDE_DIR SDL_gfx_LIBRARY)
+
+
+IF (SDL_gfx_INCLUDE_DIR AND SDL_gfx_LIBRARY)
+ SET(SDLGFX_FOUND TRUE)
+ SET(SDLGFX_INCLUDE_DIR ${SDL_gfx_INCLUDE_DIR})
+ SET(SDLGFX_LIBRARIES ${SDL_gfx_LIBRARY})
+
+ IF (NOT SDL_gfx_FIND_QUIETLY AND NOT SDL_gfx_QUIET)
+ MESSAGE(STATUS "Found SDL_gfx: ${SDL_gfx_LIBRARY}")
+ ENDIF (NOT SDL_gfx_FIND_QUIETLY AND NOT SDL_gfx_QUIET)
+ENDIF (SDL_gfx_INCLUDE_DIR AND SDL_gfx_LIBRARY)
+
+# Bail out if SDL_gfx is not found but required
+IF (NOT SDLGFX_FOUND AND SDL_gfx_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could NOT find SDL_gfx library ${SDLGFX_INCLUDE_DIR}")
+ENDIF (NOT SDLGFX_FOUND AND SDL_gfx_FIND_REQUIRED)
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000..3939854c5
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,74 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+CMAKE_POLICY(VERSION 2.6)
+
+PROJECT(MANAPLUS)
+
+IF (NOT VERSION)
+ SET(VERSION 1.0.0)
+ENDIF()
+
+STRING(REPLACE "." " " _VERSION ${VERSION})
+SEPARATE_ARGUMENTS(_VERSION)
+LIST(LENGTH _VERSION _LEN)
+IF(NOT _LEN EQUAL 4 AND NOT _LEN EQUAL 3)
+ MESSAGE(FATAL_ERROR "Version needs to be in the form MAJOR.MINOR.RELEASE[.BUILD]")
+ENDIF()
+
+LIST(GET _VERSION 0 VER_MAJOR)
+LIST(GET _VERSION 1 VER_MINOR)
+LIST(GET _VERSION 2 VER_RELEASE)
+IF(_LEN EQUAL 4)
+ LIST(GET _VERSION 3 VER_BUILD)
+ELSE()
+ SET(VER_BUILD 0)
+ENDIF()
+
+# where to look for cmake modules
+SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
+
+FIND_PACKAGE(Gettext)
+
+OPTION(WITH_OPENGL "Enable OpenGL support" ON)
+OPTION(ENABLE_NLS "Enable building of tranlations" ON)
+
+IF (WIN32)
+ SET(PKG_DATADIR ".")
+ SET(PKG_BINDIR ".")
+ SET(LOCALEDIR ".")
+ CONFIGURE_FILE(src/winver.h.in src/winver.h)
+ELSE (WIN32)
+ IF (!OSX)
+ OPTION(USE_X11 "Use X11 Clipboard functionality" ON)
+ ENDIF (!OSX)
+ SET(PKG_DATADIR ${CMAKE_INSTALL_PREFIX}/share/manaplus)
+ SET(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
+ SET(PKG_BINDIR ${CMAKE_INSTALL_PREFIX}/bin)
+ENDIF (WIN32)
+
+ADD_SUBDIRECTORY(data)
+ADD_SUBDIRECTORY(src)
+
+IF (GETTEXT_FOUND AND ENABLE_NLS)
+ ADD_SUBDIRECTORY(po)
+ENDIF()
+
+If(UNIX)
+ INSTALL(FILES manaplus.desktop DESTINATION share/applications)
+ENDIF()
+
+SET(CPACK_PACKAGE_NAME "manaplus")
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ManaPlus")
+SET(CPACK_PACKAGE_VENDOR "Mana Development Team")
+SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
+SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
+SET(CPACK_PACKAGE_INSTALL_DIRECTORY "ManaPlus")
+SET(CPACK_PACKAGE_VERSION_MAJOR ${VER_MAJOR})
+SET(CPACK_PACKAGE_VERSION_MINOR ${VER_MINOR})
+SET(CPACK_PACKAGE_VERSION_PATCH ${VER_RELEASE})
+IF(WIN32)
+ SET(CPACK_NSIS_DISPLAY_NAME "ManaPlus")
+ SET(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/data/icons/manaplus.ico")
+ SET(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/packaging/windows/setup_welcome.bmp")
+ SET(CPACK_NSIS_URL_INFO_ABOUT "http://www.manasource.org")
+ENDIF()
+INCLUDE(CPack)
diff --git a/COPYING b/COPYING
new file mode 100644
index 000000000..5b6e7c66c
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 000000000..f3f8fb179
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,6267 @@
+=== ChangeLog discontinued ===
+
+ With the move to git, The Mana World has switched from a ChangeLog
+ file to relying on commit messages to provide change history.
+
+2008-10-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/skil.cpp: fixed two broken include paths.
+
+2008-11-08 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/utils/strprintf.cpp: Fixed compile error with GCC 4.4 reported
+ by Martin Michlmayr.
+
+2008-11-06 Dennis Friis <peavey@placid.dk>
+
+ * src/game.cpp: Do not activate shortcuts if tradewindow is visible.
+ * src/equipment.cpp: Remove an extra include and arrange headers like
+ the trunk client for easier merging.
+ * src/localplayer.cpp, src/gui/equipmentwindow.cpp,
+ src/gui/equipmentwindow.h, src/equipment.h,
+ src/net/equipmenthandler.cpp, src/equipment.cpp: Have equipment tied
+ into player inventory instead of keeping its own list of pointers to
+ items. This ensures the ressource is up-to-date and avoids crashes on
+ stale item pointers.
+
+2008-11-04 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/gui.cpp, data/graphics/gui/sansserif8.png: Applied more
+ changes by vargavind, adding the complete ISO-8859-15 character set to
+ the sans-serif font.
+
+2008-11-01 Fate <fate.tmw@googlemail.com>
+
+ * src/gui/skill.cpp (class SkillGuiTableModel): Report unmapped
+ skill names as `Mystery Skill' (rather than random garbage)
+
+ * src/being.cpp (initializeHair): Read hair colours from external
+ `hair.xml' file (clientdata)
+ (initializeHair): Auto-detect number of hair colours
+
+ * src/gui/skill.cpp (SkillDialog): Display skills using a table
+ and using an external `skills.xml' file
+ (SkillDialog::update): No longer segfault when skills beyond 199
+ are reported
+
+ * src/gui/table_model.cpp: Several fixes to tables and table
+ models to better handle `NULL' widgets and `NULL' models during
+ initialisation.
+
+ * src/main.cpp (charLogin): Send client protocol version to
+ character server (this is ignored in vanilla eAthena).
+
+ * src/net/network.h (TMW_CLIENT_PROTOCOL_VERSION): Record client
+ protocol version
+
+ * src/net/beinghandler.cpp (BeingHandler::handleMessage): Properly
+ decode whether character is dead
+ (BeingHandler::handleMessage): for SMSG_PLAYER_MOVE et al., ignore
+ shoe and glove updates-- they are incorrect and not needed (we get
+ them correctly when the PC is spawned for the client and they are
+ updated as needed by other packages.)
+
+2008-10-31 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/gui.cpp: Applied patch by vargavind which adds more special
+ characters to the font. Somehow they were already part of the font
+ image, but not used.
+
+2008-10-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/beinghandler.cpp: Added particle effect on critical hits.
+
+2008-10-30 Dennis Friis <peavey@placid.dk>
+
+ * src/net/beinghandler.cpp: Do not set shoe sprite on player move
+ packet unless supported by eAthena.
+
+2008-10-28 Dennis Friis <peavey@placid.dk>
+
+ * src/net/npchandler.cpp: Handle NPC script close. Fixes client input
+ freeze on no-dialog NPCs.
+
+2008-10-28 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp: Fixed trade window being visible on client startup
+ when it was visible on shutdown.
+
+2008-10-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/net/beinghandler.cpp: Since we somehow did end up depending on a
+ hacked eAthena instead of supporting existing features decently,
+ assign the shoes and gloves IDs.
+
+2008-10-26 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particleemitter.cpp, src/particleemitter.h,
+ src/particleemitterprop.h, src/utils/minmax.h: Implemented particle
+ emitters with properties which change over time according to wave
+ functions.
+ * src/Makefile.am, src/CMakeLists.txt, tmw.cbp: Updated project files.
+
+2008-10-23 Dennis Friis <peavey@placid.dk>
+
+ * src/net/tradehandler.cpp: Add support for new athena trade-add
+ failure condition; no free slot.
+
+2008-10-22 David Athay <ko2fan@gmail.com>
+
+ * src/gui/ok_dialog.cpp, src/net/loginhandler.cpp: Now shows ban time.
+
+2008-10-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/updatewindow.cpp, src/particleemitter.cpp,
+ src/simpleanimation.cpp, src/resources/spritedef.cpp: Fixed some
+ compiler warnings. This probably also fixed the logging of several
+ error messages.
+
+2008-10-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/resources/mapreader.cpp: Added support for object groups that
+ have an offset.
+
+2008-10-02 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/engine.cpp: The "name" property of the map is now used as caption
+ of minimap window when it exists.
+
+2008-09-11 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/setup_video.cpp: Only require a restart to switch to full
+ screen with OpenGL on Windows, since it works fine in Linux without
+ having to reinitialize the OpenGL state. Adapted change by kraant from
+ Aethyra.
+ * src/net/network.cpp: Fixed the name of a variable (fix by Scraggy).
+
+2008-08-29 David Athay <ko2fan@gmail.com>
+
+ * src/monster.cpp, src/resources/monsterinfo.h,
+ src/resources/monsterdb.cpp, src/resources/monsterinfo.cpp: Mantis #406
+ by jaxad0127 to implement layered sprites.
+
+2008-08-28 Douglas Boffey <DougABoffey@netscape.net>
+
+ * src/localplayer.cpp, src/text.h, src/gui/viewport.cpp, src/npc.cpp,
+ src/textmanager.h, src/player.cpp, src/monster.h, src/textmanager.cpp,
+ src/being.cpp, src/npc.h, src/monster.cpp, src/player.h,
+ src/localplayer.h, src/player_relations.cpp, src/text.cpp,
+ src/Makefile.am, src/being.h: Move any chat, character names, NPC
+ names or targetted mob names so that no text will obscure any other
+ text. If there is no decent place for the text, it will default to
+ overlapping.
+
+2008-08-28 Fate <fate.tmw@googlemail.com>
+
+ * src/engine.h, src/gui/ministatus.cpp, src/engine.cpp,
+ src/particle.h, src/being.cpp, src/player.h, src/net/beinghandler.cpp,
+ src/net/protocol.h, src/net/playerhandler.cpp, src/being.h: Added
+ support for being effects through the eAthena levelup message, and
+ check whether the being exists before referencing it. Re-enabled
+ proper MP bar display. Improved handling of a warp to the same map.
+
+2008-08-28 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/net/beinghandler.cpp,
+ src/net/charserverhandler.cpp, src/net/protocol.h,
+ src/net/beinghandler.h, src/net/playerhandler.cpp, src/being.h:
+ Applied patch put together by Jaxad0127 with changes from the Aethyra
+ project. Improves compatibility with the newer version of eAthena and
+ works around an initialization bug.
+ * data/help/index.txt, data/help/windows.txt: Included some
+ documentation for the shortcut window by Vq.
+ * src/resources/mapreader.cpp: Fixed crash when map layer has too many
+ tiles.
+ * AUTHORS, src/winver.h, README, configure.ac, data/help/changes.txt,
+ data/help/header.txt, NEWS, CMakeLists.txt: Updated the version to
+ 0.0.26 and updated the AUTHORS file. If you have contributed and I
+ forgot you, please contact me as soon as possible!
+
+2008-08-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/loginhandler.cpp: Removed the usually incorrect "for 5
+ minutes" clause from the message displayed to banned users.
+ * src/particleemitter.cpp: Added output-pause to copy constructor.
+
+2008-08-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/particleemitter.h, src/particle.h, src/particleemitter.cpp,
+ src/particle.cpp: Renamed "randomnes" to "randomness", so that it
+ won't show up as part of Fate's patch.
+
+2008-08-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particleemitter.cpp, src/particleemitter.h: Added new particle
+ emitter property "output-pause" which allows to define a fixed (or
+ random) interval between two outputs.
+
+2008-08-06 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/window.cpp: Make sure only to save the window state when a
+ window name is set, and fail when loadWindowState() is called without
+ setting a window name.
+
+2008-08-05 David Athay <ko2fan@gmail.com>
+
+ * src/gui/setup_video.cpp, src/net/charserverhandler.cpp: Fixed
+ alignment issue with fps limit field (patch by Scraggy #384. Also
+ fixed small spelling error.
+
+2008-08-04 Dennis Friis <peavey@placid.dk>
+
+ * src/main.cpp: Fix typo in updatehost reported by Jaxad.
+
+2008-07-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp: Target the nearest monster on joystick button 3.
+
+2008-07-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/winver.h, README, configure.ac, data/help/changes.txt,
+ data/help/header.txt, NEWS, CMakeLists.txt: Updated the version to
+ 0.0.25, release planned this Sunday.
+ * README, data/help/commands.txt: Added documentation for F8 to toggle
+ shortcut window.
+
+2008-07-24 Eugenio Favalli <elvenprogrammer@themanaworld.org>
+
+ * src/game.cpp: Fixed visibility of buy and sell dialogs.
+ * src/gui/buy.cpp: Properly update price after buying.
+
+2008-07-23 Eugenio Favalli <elvenprogrammer@themanaworld.org>
+
+ * src/game.cpp, src/gui/buy.cpp, src/gui/itemshortcutwindow.cpp,
+ src/gui/sell.cpp, src/gui/window.cpp: Remember windows visibility.
+
+2008-07-22 David Athay <ko2fan@gmail.com>
+
+ * src/game.cpp: Revert the Alt-Gr fix as it did not work.
+ * src/game.cpp, src/keyboardconfig.cpp, src/keyboardconfig.h: User can
+ now configure which modifier key is used for smilies.
+
+2008-07-21 David Athay <ko2fan@gmail.com>
+
+ * src/game.cpp: Initial attempt at fixing Alt-Gr issue for Rotonen,
+ this commit is just for him!
+
+2008-07-18 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp: Remove possible trailing slash at the end of the
+ update host, since otherwise there'll be two of them.
+
+2008-07-16 Lloyd Bryant <lloyd_bryant@netzero.net>
+
+ * src/logindata.h, src/gui/char_server.cpp, src/gui/char_server.h,
+ src/serverinfo.h, src/main.cpp, src/net/loginhandler.cpp,
+ src/net/loginhandler.h, src/net/network.cpp: Added support for
+ handling the custom eAthena packet that sends the update host.
+
+2008-07-10 Eugenio Favalli <elvenprogrammer@themanaworld.org>
+
+ * tmw.cbp: Restored executable icon.
+
+2008-07-08 David Athay <ko2fan@gmail.com>
+
+ * src/gui/chat.cpp, src/gui/chat.h: Mantis #359 patch by Scraggy.
+
+2008-06-30 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/CMakeLists.txt: Updated CMake file to fix compilation. Patch by
+ darkKnight.
+
+2008-06-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Added particle property "follow-parent" which
+ makes the particle move when its parent particle is moved.
+
+2008-06-23 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/imageparticle.cpp, src/particle.cpp, src/particle.h,
+ src/particleemitter.cpp, src/particleemitter.h, src/textparticle.cpp:
+ Implemented "alpha" particle property.
+
+2008-06-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/player_relations.h: Fixed warning about missing virtual
+ destructor.
+
+2008-06-17 Fate <fate.tmw@googlemail.com>
+
+ * src/net/tradehandler.cpp: bug #333: Suppress `trade with X cancelled'
+ messages for ignored players.
+
+2008-06-16 Fate <fate.tmw@googlemail.com>
+
+ * player_relations.h: Allow whispers by default.
+
+2008-06-14 David Athay <ko2fan@gmail.com>
+
+ * src/gui/shop.cpp, src/gui/browserbox.cpp, src/net/tradehandler.cpp:
+ Fixed compilation errors. Fixed trade bug (although a little hacky
+ right now).
+ * src/net/tradehandler.cpp: Changed bug fix as requested by Bjørn.
+
+2008-06-08 Fate <fate.tmw@googlemail.com>
+
+ * src/gui/table.cpp: Invalidate mTopWidget whenever the model is
+ regenerated to reflect that we have no current valid selection.
+ * src/player_relations.cpp: Proper handling of case where player, to
+ apply ignore strategy to, is NULL.
+
+2008-06-05 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/gui/setup_video.cpp: Lowered default particle
+ detail level.
+
+2008-06-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/updatewindow.cpp, src/gui/updatewindow.h, src/main.cpp,
+ src/resources/buddylist.cpp, src/resources/spritedef.cpp,
+ src/resources/resourcemanager.cpp: Added command line argument to
+ specify the update host (-H). Also, to avoid problems when files with
+ the same name are served by different update hosts, the updates are
+ now stored in an update host specific directory. Based on a patch by
+ Sanga.
+
+2008-06-04 Lloyd Bryant <lloyd_bryant@netzero.net>
+
+ * src/net/charserverhandler.cpp: Display shield sprite also in
+ character select window.
+
+2008-05-30 Lloyd Bryant <lloyd_bryant@netzero.net>
+
+ * src/net/equipmenthandler.cpp, src/net/beinghandler.cpp,
+ src/net/protocol.h, src/being.h: Merged handling for eAthena packets
+ 0x00c3 and 0x01d7 and added support for displaying a shield sprite.
+
+2008-05-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp: Changed the way particle emitter skip is handled
+ to make linear and circular emitters work with particleEmitterSkip
+ enabled.
+ * src/gui/setup.cpp, src/gui/setup_video.cpp, src/gui/setup_video.h:
+ Added slider for controlling particleEmitterSkip (overall quality of
+ particle effects) to video setup menu.
+
+2008-05-28 Dennis Friis <peavey@placid.dk>
+
+ * src/being.cpp: Change order of direction to up/down/right/left in
+ Being::getSpriteDirection to fix inconsistancy of facing direction
+ when walking diagonally.
+
+2008-05-27 David Athay <ko2fan@gmail.com>
+
+ * src/main.cpp, src/player_relations.cpp: Changed OSX tmw directory to
+ a more suitable location, and fixed compile error.
+
+2008-05-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/Makefile.am, src/CMakeLists.txt: Fixed linker error caused by
+ missing module.
+
+2008-05-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/setup_players.cpp, src/gui/popup_box.h, src/gui/viewport.h,
+ src/gui/popup_box.cpp, src/gui/setup_players.h, src/Makefile.am:
+ Removed the PopupBox class and used gcn::DropDown instead. It has
+ clipping issues, but it would be better to fix those instead of using
+ this complicated workaround.
+
+2008-05-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/beinghandler.cpp: Implemented interpretation of names for
+ NPCs and monsters.
+ * src/npc.cpp, src/resources/npcdb.cpp, src/resources/npcdb.hpp: Added
+ the possibility to add particle effects to NPCs in npcs.xml.
+
+2008-05-16 David Athay <ko2fan@gmail.com>
+
+ * src/gui/popupmenu.cpp: Applied QOAL's patch to fix popup bug.
+
+2008-05-14 Fate <fate.tmw@googlemail.com>
+
+ * src/configuration.cpp, src/game.cpp, src/player_relations.h,
+ src/beingmanager.h, src/gui/setup_players.cpp, src/gui/setup.cpp,
+ src/gui/table_model.h, src/gui/table_model.cpp, src/gui/popup_box.h,
+ src/gui/popup_box.cpp, src/gui/table.h, src/gui/setup.h,
+ src/gui/table.cpp, src/gui/setup_players.h, src/gui/popupmenu.cpp,
+ src/beingmanager.cpp, src/player.cpp, src/main.cpp, src/being.cpp,
+ src/player.h, src/net/tradehandler.h, src/net/beinghandler.cpp,
+ src/net/tradehandler.cpp, src/net/chathandler.cpp,
+ src/configuration.h, src/player_relations.cpp, src/Makefile.am,
+ src/being.h, data/graphics/gui/emotions.png,
+ data/graphics/gui/Makefile.am, data/help/commands.txt: Added ability
+ to define friends, players you want to ignore or disregard and
+ configure whether trading is allowed. Based on new popup code,
+ configuration improvements to store hierarchical data and a table
+ model.
+
+2008-05-08 Dennis Friis <peavey@placid.dk>
+
+ * src/game.cpp: Make F8 toggle shortcut window as suggested by And1
+ and fate.
+ * src/game.cpp, src/gui/chat.h, src/gui/chat.cpp: Allow page up and
+ page down to scroll the chat window, based on patch by fate.
+
+2008-05-06 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/itemshortcutcontainer.cpp: Don't allow dragging of empty
+ placeholders.
+
+2008-04-29 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/gui/chat.h, src/gui/chat.cpp: Fixed issue with
+ determining whether chat input is focused (method no longer virtual).
+ * src/gui/itemshortcutcontainer.cpp: Fixed sometimes rendering with
+ the wrong font.
+ * src/gui/window.h, src/gui/window.cpp: Fixed warnings about hiding
+ virtual method, Window now always deletes its children (the option not
+ to do so was never used anyway).
+ * src/gui/gccontainer.h, src/gui/gccontainer.cpp: Removed unused
+ option from GCContainer to not delete a child, fixing warnings about
+ hiding virtual method gcn::Container::add.
+ * src/log.h, src/resources/imageset.cpp: When compiling with GCC, use
+ the printf format attribute for the log method so that the compiler
+ checks the type of its parameters.
+
+2008-04-28 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/inventorywindow.h, src/gui/itemcontainer.h,
+ src/gui/inventorywindow.cpp, src/gui/scrollarea.h,
+ src/gui/itemcontainer.cpp, src/gui/scrollarea.cpp: Properly fix
+ problems with ItemContainer in InventoryWindow not resizing properly
+ since upgrade to Guichan 0.8.0.
+
+2008-04-28 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/scrollarea.h, src/gui/scrollarea.cpp: Add methods to get
+ width and height adjusted for any visible scrollbars.
+ * src/gui/itemcontainer.cpp: Fix buildup of whitespace by using
+ correct gridHeight and adding just 4px space to bottom.
+ * src/gui/inventorywindow.h, src/gui/inventorywindow.cpp: Switch to
+ use our extended ScrollArea and use adjusted width to proper calculate
+ the grid for itemcontainer.
+ * src/game.cpp: Tweak keyboard input handling a bit. This fixes using
+ emoticons triggering shortcut items to be used.
+ * src/game.cpp: Remove check for KMOD_NONE since this is not working
+ uniformly across systems.
+
+2008-04-27 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/inventorywindow.cpp: Fix ItemContainer not being resized
+ properly when resizing inventory window.
+
+2008-04-26 Dennis Friis <peavey@placid.dk>
+
+ * src/inventory.cpp: Avoid stacking equipment other than arrows. Based
+ on similar fix in inventoryhandler.
+ * src/gui/trade.cpp: Text fix, z => GP.
+ * src/net/playerhandler.cpp: When picking up GP from trade or quest,
+ tell the user in the chat window like with items.
+
+2008-04-24 Dennis Friis <peavey@placid.dk>
+
+ * src/itemshortcut.h, src/gui/itemshortcutcontainer.cpp,
+ src/gui/itemcontainer.cpp, src/net/inventoryhandler.cpp,
+ src/itemshortcut.cpp: Make shortcut container ID based instead of slot
+ based. Fixes items shifting around often causing equipment to be lost.
+ * data/help/commands.txt: Document anti-trade function.
+
+2008-04-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/beingmanager.cpp: Fixed a bug, thanks GCC 4.3!
+
+2008-04-20 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp: Added --data parameter to be used to specify where to
+ get the data from when using --skipupdate.
+
+2008-04-18 David Athay <ko2fan@gmail.com>
+
+ * src/game.cpp, src/openglgraphics.cpp: Mac now uses Apple key for
+ emoticons, so alt can be used for alternate characters. Disable vsync
+ on mac.
+
+2008-04-17 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/sell.cpp: Fix shop list not to scroll to top when selling.
+ Redo of revision 3801 due to changes in guichan 0.8.0.
+ * src/gui/minimap.cpp: Draw NPCs in yellow on minimap and skip drawing
+ of warps. Based on idea by leeor_net.
+
+2008-04-16 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/browserbox.cpp: Fix a basic_string::at sometimes being out
+ of range in BrowserBox::draw when checking for line separators and
+ color codes.
+ * src/localplayer.cpp: Cancel walking to a clicked monster if the
+ target is lost while getting to it (killed or otherwise removed).
+
+2008-04-16 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/npc_text.h, src/gui/textbox.cpp, src/gui/npc_text.cpp,
+ src/gui/scrollarea.h, src/gui/textbox.h: Restored the text wrapping in
+ TextBox, since it was based on overriding a method that is no longer
+ virtual in Guichan 0.8.0.
+ * src/gui/viewport.cpp: Fixed compilation warning.
+
+2008-04-15 David Athay <ko2fan@gmail.com>
+
+ * src/gui/viewport.cpp, src/beingmanager.cpp, tmw.cbp: Fixed clicking
+ near player.
+
+2008-04-14 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/chat.cpp: Tweaked /whisper command to allow quoting of nicks
+ with spaces in them.
+
+2008-04-14 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/resources/dye.cpp: Fixed multi-channel dyeing (patch by fate)
+ * src/gui/chat.h: Changed prefix of received whisper messages from
+ "says:" to "whispers:"
+
+2008-04-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/itemshortcutcontainer.h, src/gui/itemshortcutcontainer.cpp,
+ src/gui/itemshortcutwindow.cpp, src/gui/scrollarea.h,
+ src/gui/scrollarea.cpp, src/gui/itemshortcutwindow.h: Fixed display of
+ item shortcut container. gcn::Widget::setWidth is no longer virtual.
+
+2008-04-11 David Athay <ko2fan@gmail.com>
+
+ * src/localplayer.cpp, src/beingmanager.h, src/gui/viewport.cpp,
+ src/beingmanager.cpp, src/localplayer.h, tmw.cbp: Players now need to
+ click on the monster sprites rather than the tile. Players will now
+ move to the target before attacking it.
+
+2008-04-10 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/chat.h, src/gui/chat.cpp, src/net/protocol.h,
+ src/net/chathandler.cpp: Implemented support for whispering to other
+ players.
+
+2008-04-10 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/beinghandler.cpp: Critical hits are now displayed.
+
+2008-04-09 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/shoplistbox.cpp, src/gui/shoplistbox.h: Fixed problem with
+ row height in shop list box.
+ * src/game.cpp, src/gui/menuwindow.cpp, src/gui/itemcontainer.cpp,
+ src/main.cpp, src/CMakeLists.txt, src/net/inventoryhandler.cpp,
+ src/Makefile.am: Re-enabled non-functional item shortcut window,
+ planned to be fixed for 0.0.25.
+
+2008-04-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/widgets/layout.h, src/gui/skill.cpp, src/gui/trade.h,
+ src/log.h, src/resources/mapreader.cpp, src/resources/spritedef.cpp:
+ Fixed some compiler warnings and don't try to load particle effects
+ when no file is set.
+
+2008-04-08 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/map.cpp, src/gui/viewport.cpp, src/tileset.h, src/map.h,
+ src/resources/imageset.cpp, src/resources/mapreader.cpp,
+ src/resources/imageset.h, src/resources/mapreader.h,
+ data/maps/new_3-1.tmx, data/maps/new_1-1.tmx: Implemented support for
+ an arbitrary number of map layers. The only layer requirement for map
+ layers are now that the fringe layer is called "Fringe" and that the
+ collision layer is called "Collision".
+
+2008-04-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/particle.cpp, src/utils/xml.cpp, src/utils/xml.h,
+ src/resources/mapreader.cpp, src/resources/spritedef.cpp,
+ src/resources/npcdb.h, src/resources/monsterdb.cpp,
+ src/resources/itemdb.cpp, src/resources/npcdb.cpp,
+ src/resources/spritedef.h: Added XML::Document class which simplifies
+ parsing an XML document and automatically cleans it up again.
+ * src/resources/spritedef.cpp, src/resources/spritedef.h,
+ data/graphics/sprites/item008.xml: Added support for basing one sprite
+ definition on another by including it.
+ * src/being.cpp: Fixed crash on trying to show out of range emoticon.
+ * src/winver.h, README, configure.ac, data/help/changes.txt,
+ data/help/header.txt, NEWS, CMakeLists.txt: Updated version, release
+ date and changes.
+
+2008-04-03 David Athay <ko2fan@gmail.com>
+
+ * src/game.cpp: Tweaked disconnect dialog, hoping to fix a crash bug.
+
+2008-03-31 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/main.cpp, src/npc.cpp, src/npc.h, src/resources/npcdb.h,
+ src/resources/npcdb.cpp, data/npcs.xml, src/Makefile.am, tmc.cbp:
+ Implemented NPC XML database which maps NPC IDs to one or more
+ animation files and thus enables animated NPCs.
+
+2008-03-30 Dennis Friis <peavey@placid.dk>
+
+ * configure.ac: Updated for tmwdata split.
+
+2008-03-27 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/progressbar.cpp, src/gui/scrollarea.cpp: Revert progress bar
+ changes and initialize mWalkTime.
+
+2008-03-26 Dennis Friis <peavey@placid.dk>
+
+ * src/gui/progressbar.cpp, src/localplayer.cpp: Initialized some
+ uninitialized variables.
+
+2008-03-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/engine.h, src/gui/viewport.h, src/engine.cpp,
+ src/net/playerhandler.cpp: Removed unnecessary forwarding method.
+
+2008-03-16 Dennis Friis <peavey@placid.dk>
+
+ * The Mana World.dev: Updated Dev-C++ project file.
+
+2008-03-11 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/gui/CMakeLists.txt, data/graphics/gui/Makefile.am:
+ Removed unused image here too.
+
+2008-03-11 Eugenio Favalli <elvenprogrammer@themanaworld.org>
+
+ * data/graphics/gui/attack_target.png: Removed unused image.
+
+2008-03-09 Dennis Friis <peavey@placid.dk>
+
+ * src/game.cpp: Pressing escape in the quit dialog closes the dialog.
+ * src/gui/chat.cpp, src/gui/chat.h: Fixed a bug with chat messages
+ without a sender which include semicolons.
+ * src/chat.cpp: Added "/clear" command to clear chat window.
+
+2008-03-08 Philipp Sehmisch <tmw@crushnet.org>
+
+ * tools/tmxcopy/main.cpp, tools/tmxcopy/main.map.cpp,
+ tools/tmxcopy/zlibutils.cpp: Fixed some width/height mixups in
+ TMXCopy.
+
+2008-03-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/*: Moved dynamically released data to its own module (tmwdata).
+
+2008-03-07 Eugenio Favalli <elvenprogrammer@themanaworld.org>
+
+ * data/equipment.xml, data/graphics/items/armor-legs-chaps.png,
+ data/graphics/items/armour-head-cowboyblack.png,
+ data/graphics/items/armour-head-cowboywhite.png,
+ data/graphics/items/generic-snakeskin.png,
+ data/graphics/sprites/head-cowboyblack.png,
+ data/graphics/sprites/head-cowboyblack.xml,
+ data/graphics/sprites/head-cowboywhite.png,
+ data/graphics/sprites/head-cowboywhite.xml,
+ data/graphics/sprites/leg-chaps-female.png,
+ data/graphics/sprites/leg-chaps-female.xml,
+ data/graphics/sprites/leg-chaps-male.png,
+ data/graphics/sprites/leg-chaps-male.xml,
+ data/graphics/sprites/monster-snake.png,
+ data/graphics/sprites/monster-snake.xml,
+ data/graphics/sprites/npcs.png, data/items.xml, data/monsters.xml:
+ Added new items by Black Don, new xml definitions by Peavey.
+
+2008-03-02 Eugenio Favalli <elvenprogrammer@themanaworld.org>
+
+ * tmw.cbp: Upgraded project file to latest C::B release.
+
+2008-03-02 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/leg-jeans-female.png: fixed transparency issue.
+
+2008-02-26 Eugenio Favalli <elvenprogrammer@themanaworld.org>
+
+ * src/gui/minimap.cpp: Keep minimap status. Based on a patch by Knivey.
+ * data/graphics/tiles/tulimshar1.png, data/maps/new_3-1.tmx: Added
+ Modanung's mud tileset and applyed to some houses in Tulimshar.
+
+2008-02-26 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/maps/new_14-1.tmx: Fixed some monster traps on
+ southwest woodland.
+
+2008-02-23 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/items/generic-ironore.png, data/items.xml:
+ Implemented iron ore item.
+ * data/maps/new_10-1.tmx, data/maps/new_11-1.tmx,
+ data/maps/new_12-1.tmx, data/maps/new_21-1.tmx: Map fixes by
+ QOAL.
+ * data/graphics/sprites/head-mask.xml,
+ data/graphics/sprites/head-warlordhelm.xml:
+ Animaton fixes by QOAL.
+
+2008-02-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_22-1.tmx: Map fixes at snake dungeon by QOAL.
+
+2008-02-18 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/hairstyle7-female.xml, src/sound.cpp,
+ src/utils/strprintf.cpp, tmw.cbp: Fixed image name.
+
+2008-02-13 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/equipment.xml, data/items.xml,
+ data/graphics/items/armor-head-crusaderhelm.png,
+ data/graphics/items/armor-head-infantryhelm.png,
+ data/graphics/items/armor-head-knighthelm.png,
+ data/graphics/items/armor-head-warlordhelm.png,
+ data/graphics/sprites/head-crusaderhelm.png,
+ data/graphics/sprites/head-infantryhelm.png,
+ data/graphics/sprites/head-knighthelm.png,
+ data/graphics/sprites/head-warlordhelm.png,
+ data/graphics/sprites/head-crusaderhelm.xml,
+ data/graphics/sprites/head-infantryhelm.xml,
+ data/graphics/sprites/head-knighthelm.xml,
+ data/graphics/sprites/head-warlordhelm.xml: Added new headgears by
+ Black Don (thanks to QOAL for testing and implementation)
+
+2008-02-12 Dennis Friis <peavey@placid.dk>
+
+ * src/localplayer.cpp, src/map.cpp, src/gui/viewport.cpp, src/being.cpp
+ src/map.h: Made pathfinding not halt on collision destination tile,
+ made moving around with mouse smoother. Added possibility to pass
+ through players with key controls.
+
+2008-02-11 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_22-1.tmx: Added music and overlay to snake dungeon.
+
+2008-02-10 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_23-1.tmx: Added Dimonds Cove outdoor map by MerlinX420.
+
+2008-02-08 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_14-1.tmx, data/maps/new_22-1.tmx: Added Dimonds Cove
+ outdoor map by MerlinX420. Fixed some map bugs in snake dungeon.
+ * data/items.xml: Added chicken leg meta information.
+
+2008-01-28 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/sell.cpp, src/gui/window.cpp, src/gui/inventorywindow.h,
+ src/gui/buy.h, src/gui/itemshortcutwindow.cpp,
+ src/gui/inventorywindow.cpp, src/gui/buy.cpp, src/gui/sell.h,
+ src/gui/window.h, src/gui/windowlistener.h,
+ src/gui/itemshortcutwindow.h, src/CMakeLists.txt, src/Makefile.am:
+ Used the gcn::WidgetListener instead of our WindowListener.
+
+2008-01-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/trade.h, src/game.h, src/being.h: Fixed a GCC 4.3 compile
+ error and constified the usage of auto_ptr, since that's the way in
+ which we are using them.
+
+2008-01-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/char_server.cpp, src/gui/window.cpp, src/gui/checkbox.h,
+ src/gui/playerbox.h, src/gui/button.cpp, src/gui/chat.cpp,
+ src/gui/slider.cpp, src/gui/tabbedcontainer.cpp, src/gui/textfield.h,
+ src/gui/shoplistbox.cpp, src/gui/register.cpp,
+ src/gui/radiobutton.cpp, src/gui/textbox.cpp, src/gui/login.cpp,
+ src/gui/setup_audio.cpp, src/gui/setup_video.cpp,
+ src/gui/textfield.cpp, src/gui/playerbox.cpp,
+ src/gui/setup_joystick.cpp, src/gui/scrollarea.h,
+ src/gui/windowlistener.h, src/gui/checkbox.cpp,
+ src/gui/scrollarea.cpp: Compile against Guichan 0.8.0. Some issues
+ with ShopListBox left and not trying to use their new TabbedArea,
+ SelectionListener and WidgetListener yet. Also needs more testing.
+ * src/gui/trade.cpp, src/gui/sell.cpp, src/gui/inventorywindow.h,
+ src/gui/selectionlistener.h, src/gui/itemcontainer.h,
+ src/gui/shoplistbox.cpp, src/gui/shoplistbox.h, src/gui/listbox.h,
+ src/gui/buy.h, src/gui/inventorywindow.cpp, src/gui/buy.cpp,
+ src/gui/itemcontainer.cpp, src/gui/sell.h, src/gui/trade.h,
+ src/gui/listbox.cpp, src/CMakeLists.txt, src/Makefile.am: Used the
+ gcn::SelectionListener instead of our own.
+
+2008-01-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_10-1.tmx, data/maps/new_11-1.tmx: Map fixes by 5t3v3 at
+ the new snow maps. Added hot spring particle effect to pond south of
+ snow village.
+ * data/graphics/particles/bubbles_32px,
+ data/graphics/particles/bubbles_12px,
+ data/graphics/particles/bubbles_8px,
+ data/graphics/particles/whirlpool.particle.xml: Added bubble particle
+ effect.
+
+2008-01-14 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_10-1.tmx, data/maps/new_11-1.tmx: Added new versions of
+ snow maps by 5t3v3.
+ * src/sound.cpp: Fixed an error in Davids last commit (couldn't compile
+ that way).
+
+2008-01-13 David Athay <ko2fan@gmail.com>
+
+ * src/resources/resourcemanager.h, src/resources/resourcemanager.cpp,
+ src/main.cpp, src/sound.cpp, src/engine.cpp: Fixed music loading from
+ non-default location.
+
+2008-01-03 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_1-1.tmx, data/maps/new_3-1.tmx: Some map bugs reported
+ by Strump, fixed by Zipon.
+
+2007-12-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/viewport.cpp: Added config options to set the scroll center.
+ * src/engine.cpp, src/engine.h, src/gui/viewport.h,
+ src/net/playerhandler.cpp: Retained scroll offset during map change for
+ smoother map transitions.
+
+2007-12-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_22-1.tmx: Some mapping fixes at snake dungeon map.
+ * src/game.cpp, src/beingmanager.cpp, src/beingmanager.h,
+ src/keyboardconfig.cpp, src/keyboardconfig.h: Added a key for targeting
+ the nearest player character based on patches by Trinexx.
+
+2007-12-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_7-1.tmx, data/maps/new_22-1.tmx: Added new map by 5t3v3
+ (east desert cave) and enhanced version of eastern desert by Len.
+
+2007-12-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_3-1.tmx: Some mapping errors fixed by Zipon.
+ * src/being.cpp, src/monster.cpp, src/resources/monsterinfo.cpp,
+ src/resources/monsterinfo.h: Added the possibility to assign particle
+ effects to monsters in the monster database.
+ * data/monsters.xml: Added flame particle effect to fire goblin as a
+ proof of concept.
+
+2007-12-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * README: Fixed year here too...
+
+2007-12-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/help/header.txt: Fixed year. :)
+ * debian/rules: Fixed missing backslash.
+ * src/CMakeLists.txt: Updated CMake file.
+
+2007-12-24 David Athay <ko2fan@gmail.com>
+
+ * src/game.cpp: Fixed dialog for disconnections, so it says Ok, not
+ yes/no.
+ * src/openglgraphics.cpp: Changed type so it would compile on Leopard.
+
+2007-12-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * README, data/help/changes.txt, data/help/header.txt, NEWS: Updated
+ release date.
+ * src/game.cpp, src/gui/menuwindow.cpp, src/gui/itemcontainer.cpp,
+ src/main.cpp, src/CMakeLists.txt, src/net/inventoryhandler.cpp,
+ src/Makefile.am: Disabled non-functional item shortcut window.
+ * src/particleemitter.cpp: Fix compile warning.
+
+2007-12-23 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particleemitter.cpp, src/particleemitter.h: Particle images
+ are now reference-counted properly.
+ * src/resources/spritedef.cpp: Error placeholder is now used when
+ attempting to load a sprite definition file that doesn't exist.
+ * src/monster.cpp, src/player.cpp: Avoided attempts to load
+ "data/graphics/" when a monster or equipment piece has no sprite.
+ * data/graphics/particles/cookingfire.particle.xml: Removed some
+ particle properties that did nothing because they were misspelled.
+
+2007-12-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/winver.h, README, configure.ac, INSTALL, data/help/header.txt,
+ NEWS, CMakeLists.txt: Updated version to 0.0.24.
+ * src/net/chathandler.cpp, NEWS: Make sure chat messages are also
+ trimmed for the local player.
+
+2007-12-21 David Athay <ko2fan@gmail.com>
+
+ * src/game.cpp, src/gui/updatewindow.cpp: Attempted to fix client
+ freeze when unable to connect to update host, and added exit dialog
+ when client loses connection.
+
+2007-12-21 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/shoplistbox.cpp: Fixed shop list box not to scroll up when
+ the selection is removed.
+ * src/resources/resourcemanager.h, src/resources/resourcemanager.cpp:
+ Added logging of error on PHYSFS_addToSearchPath.
+ * src/localplayer.cpp, src/inventory.h, src/gui/inventorywindow.cpp,
+ src/inventory.cpp, src/localplayer.h: Fixed inventory size not
+ matching the size assumed by eAthena, and related memory corruption.
+ * src/main.cpp: Increased default chat log length.
+
+2007-12-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_18-1.tmx: Fixed a map bug (monster trap) on
+ map 18 (woodland village surrounding)
+
+2007-12-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * tools/upalyzer/analyse.php: Fixed association of entries to update,
+ added no-cache headers, added a bit of error reporting in case of
+ invalid zip files, kept original ordering of the update list and
+ sorted the list of entries on their filename.
+ * tools/upalyzer/analyse.php: Added list of files in each update with
+ indication on whether they are still used.
+
+2007-12-18 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp: Remember to delete the progressbar and label also when
+ the game was not started.
+ * tools/upalyzer/analyse.php: Added initial version of the update
+ analysis tool upalyzer.
+ * tools/upalyzer/analyse.php: Optimized with single loop approach and
+ nicer printing calls, inspired by doener's version. Also added list of
+ update entries and their respective update.
+
+2007-12-14 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/head-mask.png,
+ data/graphics/sprites/head-mask.xml,
+ data/graphics/sprites/head-mushroom.xml,
+ data/graphics/sprites/head-shroom.xml,
+ data/items.xml, data/equipment.xml:
+ Fixed some problems with the new items.
+
+2007-12-12 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/cave.png, data/graphics/tiles/cave_x2.png:
+ Fixed the blurred outlines of the new tiles.
+
+2007-12-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/tiles/cave.png, data/graphics/tiles/cave_x2.png,
+ data/maps/new_4-1.tmx: Added two new cave tiles by yosuhara.
+
+2007-12-12 Philipp Sehmisch <tmw@crushnet.org>
+
+ * tools/tmxcopy/base64.cpp,
+ tools/tmxcopy/base64.h, tools/tmxcopy/main.cpp,
+ tools/tmxcopy/map.cpp, tools/tmxcopy/map.hpp,
+ tools/tmxcopy/readme.txt, tools/tmxcopy/tmxcopy.cbp,
+ tools/tmxcopy/tostring.h, tools/tmxcopy/xmlutils.cpp,
+ tools/tmxcopy/xmlutils.h, tools/tmxcopy/zlibutils.cpp,
+ tools/tmxcopy/zlibutils.h: Added my tmxcopy tool for copying
+ parts of maps to other maps.
+
+2007-12-10 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/being.cpp: Include cassert header.
+
+2007-12-10 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/being.cpp, src/being.h, src/net/beinghandler.cpp,
+ src/net/charserverhandler.cpp, src/net/equipmenthandler.cpp,
+ src/player.cpp, src/player.h, data/items.xml: Simplified player
+ subsprite handling by treating equipment, hairstyle and base
+ sprites alike. This also enables gender-specific hairstyles.
+ * src/game.cpp, src/gui/chat.cpp, src/gui/chat.h, src/log.cpp,
+ src/log.h: Added an option to show log messages in the chat console.
+ * data/items.xml,
+ data/graphics/sprites/hairstyle1.png,
+ data/graphics/sprites/hairstyle1.xml,
+ data/graphics/sprites/hairstyle1-male.png,
+ data/graphics/sprites/hairstyle1-male.xml,
+ data/graphics/sprites/hairstyle1-female.png,
+ data/graphics/sprites/hairstyle1-female.xml,
+ data/graphics/sprites/hairstyle2.png,
+ data/graphics/sprites/hairstyle2.xml,
+ data/graphics/sprites/hairstyle2-male.png,
+ data/graphics/sprites/hairstyle2-male.xml,
+ data/graphics/sprites/hairstyle2-female.png,
+ data/graphics/sprites/hairstyle2-female.xml,
+ data/graphics/sprites/hairstyle3.png,
+ data/graphics/sprites/hairstyle3.xml,
+ data/graphics/sprites/hairstyle3-male.png,
+ data/graphics/sprites/hairstyle3-male.xml,
+ data/graphics/sprites/hairstyle3-female.png,
+ data/graphics/sprites/hairstyle3-female.xml,
+ data/graphics/sprites/hairstyle4.png,
+ data/graphics/sprites/hairstyle4.xml,
+ data/graphics/sprites/hairstyle4-male.png,
+ data/graphics/sprites/hairstyle4-male.xml,
+ data/graphics/sprites/hairstyle4-female.png,
+ data/graphics/sprites/hairstyle4-female.xml,
+ data/graphics/sprites/hairstyle5.png,
+ data/graphics/sprites/hairstyle5.xml,
+ data/graphics/sprites/hairstyle5-male.png,
+ data/graphics/sprites/hairstyle5-male.xml,
+ data/graphics/sprites/hairstyle5-female.png,
+ data/graphics/sprites/hairstyle5-female.xml,
+ data/graphics/sprites/hairstyle6.png,
+ data/graphics/sprites/hairstyle6.xml,
+ data/graphics/sprites/hairstyle6-male.png,
+ data/graphics/sprites/hairstyle6-male.xml,
+ data/graphics/sprites/hairstyle6-female.png,
+ data/graphics/sprites/hairstyle6-female.xml,
+ data/graphics/sprites/hairstyle7.png,
+ data/graphics/sprites/hairstyle7.xml,
+ data/graphics/sprites/hairstyle7-male.png,
+ data/graphics/sprites/hairstyle7-male.xml,
+ data/graphics/sprites/hairstyle7-female.png,
+ data/graphics/sprites/hairstyle7-female.xml:
+ Implemented female hairstyles.
+
+2007-12-09 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/head-funkywinter.png,
+ data/graphics/sprites/head-funkywinter.xml,
+ data/graphics/sprites/head-xmaself.png,
+ data/graphics/sprites/head-xmaself.xml: New versions of funky hat
+ and elf hat by QOAL.
+
+2007-12-04 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/items/generic-santacookie.png,
+ data/items.xml: Added a new drop item for the christmas event.
+
+2007-12-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/map.cpp, src/map.h: Fix drawing of very high fringe tiles by
+ keeping track of the maximum tile height.
+ * src/itemshortcut.h, src/gui/itemshortcutcontainer.h,
+ src/gui/itemshortcutcontainer.cpp, src/gui/itemshortcutwindow.cpp,
+ src/gui/itemshortcutwindow.h, src/itemshortcut.cpp: Random cleanups.
+
+2007-12-04 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/head-funkywinter.png,
+ data/graphics/sprites/head-funkywinter.xml,
+ data/graphics/sprites/head-mask.png,
+ data/graphics/sprites/head-mask.xml,
+ data/graphics/sprites/head-mushroom.png,
+ data/graphics/sprites/head-mushroom.xml,
+ data/graphics/sprites/head-shroom.png,
+ data/graphics/sprites/head-shroom.xml,
+ data/graphics/sprites/head-tophat.png,
+ data/graphics/sprites/head-tophat.xml,
+ data/graphics/sprites/head-xmaself.png,
+ data/graphics/sprites/head-xmaself.xml,
+ data/graphics/items/armor-head-xmaself.png,
+ data/graphics/items/armor-head-mask.png,
+ data/items.xml: Added/renamed some headgears for the christmas event.
+
+2007-11-20 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/maps/new_1-1.tmx,
+ data/graphics/maps/new_3-1.tmx,
+ data/graphics/maps/new_15-1.tmx: Updated desert maps with new
+ tiles by Len.
+
+2007-11-16 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/floor_item.cpp, src/localplayer.cpp, src/item.cpp,
+ src/inventory.h, src/gui/sell.cpp, src/gui/equipmentwindow.cpp,
+ src/gui/shop.cpp, src/gui/shoplistbox.cpp, src/gui/shop.h,
+ src/gui/itemshortcutcontainer.cpp, src/gui/buy.cpp,
+ src/gui/itemcontainer.cpp, src/inventory.cpp, src/item.h,
+ src/equipment.h, src/shopitem.cpp, src/CMakeLists.txt,
+ src/floor_item.h, src/net/inventoryhandler.cpp, src/equipment.cpp,
+ src/localplayer.h, src/Makefile.am, src/resources/iteminfo.h,
+ src/resources/itemdb.cpp, src/resources/iteminfo.cpp, src/shopitem.h:
+ Moved item icon from ItemInfo class to the Item class, so that it can
+ be loaded on demand. Results in faster startup time and reduced memory
+ usage.
+
+2007-11-16 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/resources/resourcemanager.h, src/resources/resource.h,
+ src/resources/resourcemanager.cpp, src/resources/resource.cpp: Delayed
+ resource deletion by 30 seconds.
+ * src/resources/image.cpp: Sped up recoloring of transparent pixels.
+
+2007-11-16 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/log.cpp, src/utils/wingettimeofday.h: Removed useless win32
+ implementation of gettimeofday.
+ * src/log.cpp, tmw.cbp: Fixed minor issues.
+
+2007-11-11 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/item_amount.cpp, src/gui/item_amount.h,
+ src/gui/inventorywindow.cpp: Moved check on dropping 1 item to the
+ inventory dialog.
+
+2007-11-09 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/chest-chainmail-male,
+ data/graphics/sprites/chest-chainmail-female,
+ data/graphics/sprites/chest-cotton-male,
+ data/graphics/sprites/chest-cotton-female,
+ data/graphics/sprites/chest-leather-male,
+ data/graphics/sprites/chest-leather-female,
+ data/graphics/sprites/chest-tnecksweater-male,
+ data/graphics/sprites/chest-tnecksweater-female,
+ data/graphics/sprites/chest-vnecksweater-male,
+ data/graphics/sprites/chest-vnecksweater-female:
+ Modifications at the back shading of shirt sprites by Pauan.
+
+2007-11-04 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/resources/dye.cpp, src/resources/resourcemanager.cpp: Moved
+ palette qualifiers to the right as the code appends things on the left.
+ * src/resources/spritedef.cpp, src/resources/spritedef.h,
+ src/resources/resourcemanager.h: Added propagation of palettes through
+ sprite resource names.
+ * data/monsters.xml, data/graphics/sprites/monster-scorpion.xml: Used
+ palettes on sprite names.
+ * data/graphics/sprites/monster-scorpion-black.xml,
+ data/graphics/sprites/monster-scorpion-red.xml: Removed obsolete files.
+ * src/player.cpp: Added hair colors.
+ * data/graphics/sprites/hairstyle*.xml: Removed sprite variants. Set
+ replaceable color.
+ * data/graphics/sprites/hairstyle*.png: Reduced image sizes.
+ * data/monsters.xml, data/graphics/sprites/monster-slime.xml,
+ data/graphics/sprites/monster-slime.png: Added generic slime.
+ * data/graphics/sprites/monster-slime-{green,red,yellow}.png,
+ data/graphics/sprites/monster-slime-{green,red,yellow}.xml: Removed
+ obsolete files.
+
+2007-11-03 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/player.cpp, src/player.h, src/gui/char_select.cpp: Factored code.
+ * src/net/beinghandler.cpp, src/net/charserverhandler.cpp: Fixed double
+ load of hair graphics.
+ * src/Makefile.am, src/resources/dye.cpp, src/resources/dye.h: Added
+ palette holder and linear interpolator of colors.
+ * src/resources/image.h, src/resources/image.cpp: Added palette-based
+ recoloring of images.
+ * src/resources/resourcemanager.h, src/resources/resourcemanager.cpp:
+ Added automatic recoloring of images depending on their names.
+ * data/graphics/sprites/monster-scorpion.png: Flattened colors.
+ * data/graphics/sprites/monster-scorpion-black.png,
+ data/graphics/sprites/monster-scorpion-red.png: Removed obsolete files.
+ * data/graphics/sprites/monster-scorpion.xml,
+ data/graphics/sprites/monster-scorpion-black.xml,
+ data/graphics/sprites/monster-scorpion-red.xml: Added automatic
+ recoloring of scorpions.
+
+2007-11-01 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/particles/aniblaze.png,
+ data/graphics/particles/cookingfire.particle.xml,
+ data/graphics/particles/fireplace.particle.xml,
+ data/graphics/particles/flame.particle.xml: Improved fire particle
+ effects by using animated particles.
+
+2007-10-31 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/items.xml, data/graphics/sprites/leg-skirt.png,
+ data/graphics/sprites/leg-skirt.xml,
+ data/graphics/items/armor-leg-skirt.png: Added skirt by Saphy.
+ ViewID is 26, item ID is 632, item properties are c&p from jeans
+ shorts.
+
+2007-10-27 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/properties.h, src/game.cpp, src/channel.h, src/log.cpp,
+ src/gui/window.cpp, src/gui/setup.cpp, src/gui/button.cpp,
+ src/gui/chat.h, src/gui/widgets/dropdown.cpp, src/gui/chat.cpp,
+ src/gui/tabbedcontainer.cpp, src/gui/windowcontainer.cpp,
+ src/gui/skill.cpp, src/gui/serverdialog.cpp, src/gui/textfield.cpp,
+ src/gui/playerbox.cpp, src/gui/scrollarea.cpp, src/beingmanager.cpp,
+ src/flooritemmanager.cpp, src/channelmanager.cpp, src/main.cpp,
+ src/particle.cpp, src/net/messageout.cpp, src/channel.cpp,
+ src/localplayer.h, src/resources/imageset.cpp,
+ src/resources/buddylist.cpp, src/resources/monsterinfo.h,
+ src/resources/iteminfo.h, src/resources/monsterdb.cpp,
+ src/resources/monsterinfo.cpp, src/resources/itemdb.cpp: Fixed missing
+ dependencies, spurious const qualifiers, and weak brackets, so that it
+ compiles with GCC 4.3.
+
+2007-10-26 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/item_ammount.cpp: Item amount dialog is now skipped
+ when there is only one item on the stack.
+ * src/browserbox.cpp, src/browserbox.h, src/chat.h, src/main.cpp:
+ Added possibility of length limitation to browserbox and used it
+ for the chatlog (length set by the config option "ChatLogLength").
+ * src/chat.cpp, src/chat.h: Removed some completely useless code
+ from the chat class.
+ * src/monster.cpp, src/monster.h, data/sfx/logmonster-hurt1.ogg,
+ data/sfx/logmonster-hurt2.ogg, data/sfx/logmonster-hurt3.ogg,
+ data/sfx/logmonster-hurt4.ogg, data/sfx/logmonster-hurt5.ogg:
+ Implemented monster hurt sounds and added new sound effects by
+ Cosmostrator.
+
+2007-10-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/items.xml, data/graphics/items/generic-darkcrystal.png:
+ Added a new quest loot item for the halloween event.
+
+2007-10-22 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/particle.cpp: Plugged memory leak.
+ * src/configuration.cpp, src/main.cpp: Plugged memory leak. Cleaned
+ code.
+
+2007-10-21 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/gui/window.cpp, src/gui/window.h: Removed redundant resizable
+ flag. Factored moving/resizing code, so that events are fired only
+ once per size change.
+ * src/resources/spritedef.cpp: Plugged memory leak in sprites.
+ * src/resources/action.cpp: Fixed double-free of sprite actions.
+ * src/resources/iteminfo.cpp, src/resources/iteminfo.h: Plugged memory
+ leak in equipment sound.
+ * src/resources/monsterdb.cpp: Plugged memory leak in database reader.
+ * src/engine.cpp, src/engine.h, src/game.cpp: Fixed current map not
+ deleted on server change.
+ * src/gui/trade.cpp: Added persistent positioning.
+ * src/gui/menuwindow.cpp: Fixed missing pixels at bottom and right.
+ * src/gui/window.cpp, src/gui/window.h: Changed to use default values
+ when restoring missing settings.
+ * src/gui/shoplistbox.cpp, src/gui/listbox.cpp: Fixed invisible text.
+
+2007-10-20 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/gui/playerbox.cpp: Centered sprite inside selection box.
+
+2007-10-19 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/resources/resource.cpp, src/resources/resource.h,
+ src/resources/imageset.cpp, src/resources/imageset.h: Removed mandatory
+ identifier path.
+ * src/resources/resourcemanager.cpp, src/resources/resourcemanager.h:
+ Factored code between resource handlers.
+ * src/resources/soundeffect.h, src/resources/soundeffect.cpp,
+ src/resources/music.h, src/resources/music.cpp, src/resources/image.h,
+ src/resources/image.cpp: Reworked resource loaders.
+ * src/resources/spritedef.h, src/resources/spritedef.cpp: Implemented
+ a failure-friendly loader.
+ * src/gui/truetypefont.cpp, src/resources/imageloader.cpp,
+ src/tileset.h: Removed dummy parameter.
+
+2007-10-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/images/ambient/fog.png: Added fog effect overlay
+ graphic.
+
+2007-10-18 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/resources/iteminfo.h, src/resources/itemdb.cpp: Removed unused
+ slot field.
+ * src/localplayer.cpp, src/localplayer.h: Removed specific type.
+ * src/gui/viewport.cpp, src/gui/minimap.cpp: Changed identification of
+ local player to a check of player_node.
+ * src/animatedsprite.cpp, src/animatedsprite.h, src/npc.cpp,
+ src/player.cpp, src/monster.cpp, src/resources/resourcemanager.cpp:
+ Prevented client from exiting on missing sprites.
+ * src/resources/spritedef.cpp: Added filename to fatal error messages.
+ * src/resources/iteminfo.cpp, src/resources/iteminfo.h,
+ src/resources/itemdb.cpp, data/items.xml: Merged weapon_type and
+ attacktype field.
+
+2007-10-18 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/hairstyle7-male.png,
+ data/graphics/sprites/hairstyle7-female.png: Readded hairstyle number
+ 7.
+
+2007-10-18 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/net/tradehandler.h, src/net/tradehandler.cpp:
+ Implemented automatic denying of trade requests based on a patch
+ submitted by Quiche_on_a_leash.
+
+2007-10-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/maps/new_18-1.tmx: Fixed some collision layer problems.
+
+2007-10-01 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/player.cpp, data/graphics/sprites/hairstyle*:
+ Added support for different hairstyles for male and female characters
+ (current female hairstyles are copies of the male ones until the
+ real female ones are finished)
+
+2007-09-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/desert_x3.png: Removed the purple line from the
+ ruin tile.
+
+2007-09-27 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/desert2.png, data/graphics/tiles/desert_x3.png,
+ data/graphics/tiles/desert_x5.png: Added new desert tiles by Len.
+
+2007-09-20 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/equipment.xml, data/graphics/items/armor-head-funkyhat.png,
+ data/graphics/items/armor-head-mushroomhat.png,
+ data/graphics/items/armor-head-shroomhat.png,
+ data/graphics/items/armor-head-tophat.png,
+ data/graphics/sprites/item019.png, data/graphics/sprites/item019.xml,
+ data/graphics/sprites/item020.png, data/graphics/sprites/item020.xml,
+ data/graphics/sprites/item021.png, data/graphics/sprites/item021.xml,
+ data/graphics/sprites/item022.png, data/graphics/sprites/item022.xml,
+ data/items.xml, data/maps/new_21-1.tmx: Added 4 new items and a new ice
+ cave map.
+
+2007-09-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/items.xml, data/equipment.xml: Added temporary weapon IDs below
+ 256 to use as view-ID in eAthena's item DB.
+ * src/gui/shoplistbox.cpp, src/gui/buy.h, src/gui/buy.cpp: Allowed
+ selection of items that cannot be afforded, so that their descriptions
+ are still accessible. Also made sure the player's money value of
+ ShopItemList gets updated.
+
+2007-09-11 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/chat.cpp, tmw.cbp: Fixed admin commands.
+
+2007-09-08 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/particles/aniblaze.png,
+ data/graphics/particles/cookingfire.particle.xml,
+ data/graphics/particles/fireplace.particle.xml,
+ data/graphics/particles/flame.particle.xml: Improved fire effects by
+ using animated particles.
+
+2007-09-06 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/animationparticle.cpp, src/imageparticle.cpp: Fixed animated
+ particles.
+
+2007-09-01 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/Makefile.am: Fixed the entry for windowlistener.h.
+
+2007-08-30 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/localplayer.cpp, src/player.cpp, src/main.cpp, src/being.cpp,
+ src/CMakeLists.txt, src/Makefile.am, src/resources/iteminfo.h,
+ src/resources/equipmentdb.h, src/resources/equipmentinfo.h,
+ src/resources/itemdb.cpp, src/resources/iteminfo.cpp,
+ src/resources/equipmentdb.cpp, src/resources/equipmentinfo.cpp,
+ src/resources/spritedef.h, src/being.h, data/items.xml,
+ data/equipment.xml: Merged equipment database with items database and
+ got rid of the unused item art attribute.
+ * src/net/beinghandler.cpp, src/net/charserverhandler.cpp: Removed the
+ now unnecessary multiplication of weapon IDs with 10000.
+ * src/resources/iteminfo.cpp, data/graphics/items/unknown.png: Added
+ fallback item icon and use it for unknown items or when item image
+ fails to load.
+ * NEWS: Updated with changes since last update.
+ * data/items.xml, data/equipment.xml: Reverted equipment database and
+ included original low-ID items in items.xml for compatibility with
+ eAthena, which doesn't support View ID to come above 255.
+ * src/resources/itemdb.cpp: Accept items without a name.
+
+2007-08-29 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/sell.cpp, src/gui/inventorywindow.cpp, src/gui/sell.h: Made
+ sell dialog resizable and tweaked inventory resize code a bit.
+ * data/items.xml: Fixed typo in chainmail description.
+
+2007-08-28 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/window.cpp, src/gui/inventorywindow.h,
+ src/gui/selectionlistener.h, src/gui/buy.h,
+ src/gui/itemshortcutwindow.cpp, src/gui/inventorywindow.cpp,
+ src/gui/buy.cpp, src/gui/window.h, src/gui/windowlistener.h,
+ src/gui/itemshortcutwindow.h, src/CMakeLists.txt, src/Makefile.am:
+ Made buy dialog resizable and added a WindowListener class for
+ listening for window resize and move events.
+ * src/textparticle.h, src/particle.h, src/CMakeLists.txt,
+ src/particle.cpp, src/imageparticle.cpp, src/vector.h,
+ src/textparticle.cpp, src/Makefile.am: Added Vector class and used it
+ in the particle engine.
+
+2007-08-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/engine.cpp, src/resources/mapreader.cpp: Made client search for
+ both compressed and non-compressed map files.
+
+2007-08-27 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp: Assigned unused emotions to Alt +/-. (applied a patch
+ by Quiche_on_a_leash).
+ * data/maps/new_1-1.tmx, data/maps/new_1-1.tmx.gz,
+ data/maps/new_10-1.tmx, data/maps/new_10-1.tmx.gz,
+ data/maps/new_11-1.tmx, data/maps/new_11-1.tmx.gz,
+ data/maps/new_12-1.tmx, data/maps/new_12-1.tmx.gz,
+ data/maps/new_13-1.tmx, data/maps/new_13-1.tmx.gz,
+ data/maps/new_14-1.tmx, data/maps/new_14-1.tmx.gz,
+ data/maps/new_15-1.tmx, data/maps/new_15-1.tmx.gz,
+ data/maps/new_16-1.tmx, data/maps/new_16-1.tmx.gz,
+ data/maps/new_17-1.tmx, data/maps/new_17-1.tmx.gz,
+ data/maps/new_18-1.tmx, data/maps/new_18-1.tmx.gz,
+ data/maps/new_19-1.tmx, data/maps/new_19-1.tmx.gz,
+ data/maps/new_2-1.tmx, data/maps/new_2-1.tmx.gz,
+ data/maps/new_20-1.tmx, data/maps/new_20-1.tmx.gz,
+ data/maps/new_3-1.tmx, data/maps/new_3-1.tmx.gz,
+ data/maps/new_4-1.tmx, data/maps/new_4-1.tmx.gz,
+ data/maps/new_5-1.tmx, data/maps/new_5-1.tmx.gz,
+ data/maps/new_6-1.tmx, data/maps/new_6-1.tmx.gz,
+ data/maps/new_7-1.tmx, data/maps/new_7-1.tmx.gz,
+ data/maps/new_8-1.tmx, data/maps/new_8-1.tmx.gz,
+ data/maps/new_9-1.tmx, data/maps/new_9-1.tmx.gz: Replaced compressed
+ maps with layer compressed maps.
+
+2007-08-26 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/updatewindow.cpp, src/main.cpp, tmw.cbp: Removed home dir
+ from config file to avoid encoding issues.
+
+2007-08-26 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/gui/button.cpp: Fixed incorrect button dimensions, as they mess
+ OpenGL display with rectangle textures.
+ * src/graphics.cpp, src/openglgraphics.h, src/graphics.h,
+ src/openglgraphics.cpp: Fixed fonts not being recolored by adding an
+ explicit parameter to require it.
+
+2007-08-25 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * configure.ac: Removed dependency on Guichan's OpenGL library.
+ * src/Makefile.am, src/resources/sdlimageloader.cpp,
+ src/resources/sdlimageloader.h, src/resources/openglsdlimageloader.h,
+ src/resources/openglsdlimageloader.cpp, src/resources/imageloader.cpp,
+ src/resources/imageloader.h, src/gui/gui.cpp, src/gui/gui.h: Replaced
+ Guichan's image loaders with our owns, so that we have control over all
+ the images used as textures.
+ * src/resources/image.cpp, src/openglgraphics.h, src/resources/image.h,
+ src/openglgraphics.cpp, src/graphics.cpp, src/graphics.h: Added support
+ for rectangle OpenGL textures when available, in order to reduce video
+ memory usage.
+
+2007-08-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/gui.h, src/gui/gui.cpp: Removed useless logic method and
+ reverted mouse cursor to non-static since there can be only one Gui
+ instance so there is no point in supporting a shared resource.
+ * src/gui/window.cpp, src/gui/gui.h: Removed unnecessary
+ Gui::isCustomCursor method.
+ * src/gui/char_select.h, src/gui/char_select.cpp, src/utils/trim.h:
+ Added trimming of name for new character creation.
+ * src/net/chathandler.cpp: Added trimming of chat messages appearing
+ above players.
+ * src/gui/window.cpp, src/gui/window.h: Improved resize mouse cursor
+ indication, removing duplicated code and fixing indicator above resize
+ grip.
+
+2007-08-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/viewport.h, src/gui/viewport.cpp: Removed two useless popup
+ related methods.
+ * src/gui/debugwindow.h, src/gui/debugwindow.cpp: Use generic close
+ button functionality.
+ * src/particle.h, src/particleemitter.cpp, src/particle.cpp: Renamed
+ Particle::mVector to Particle::mVelocity for clarity.
+ * src/localplayer.cpp, src/gui/ministatus.cpp, src/gui/status.cpp,
+ src/being.cpp, src/net/charserverhandler.cpp,
+ src/net/playerhandler.cpp, src/localplayer.h, src/being.h: Changed XP
+ gaining effect to appear on the player instead.
+ * data/graphics/gui/hits_yellow.png: Restored shadow of yellow font.
+
+2007-08-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/itemshortcutcontainer.h: Fixed compiler warning.
+ * src/CMakeLists.txt, src/Makefile.am: Updated source lists.
+ * data/graphics/gui/CMakeLists.txt, data/graphics/gui/Makefile.am:
+ Added close button and item shortcut backgrounds to files that will be
+ installed.
+ * src/gui/itemshortcutcontainer.cpp: Make sure mGridWidth and
+ mGridHeight are initialized properly (fixes arithmetic exception in
+ ItemShortcutContainer::draw).
+ * src/keyboardconfig.cpp: Changed default sitting key back to 's'.
+ * src/net/equipmenthandler.cpp: Removed a line that attempted to set
+ the player's weapon sprite with each kind of equipment. Seems to work
+ fine without as well.
+ * src/gui/chat.cpp, src/utils/trim.h, src/CMakeLists.txt,
+ src/Makefile.am: Added trimming of chat messages.
+
+2007-08-22 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/chest-lightplatemail-male.png,
+ data/graphics/sprites/chest-lightplatemail-female.png,
+ data/graphics/items/armor-chest-lightplatemail.png,
+ data/graphics/tiles/woodland_indoor_x2.png: Another color correction
+ at the light platemail (looks more metalic now)
+ * data/maps/new_18-1.tmx.gz, data/maps/new_19-1.tmx.gz,
+ data/images/minimap_new_18-1.png, data/images/minimap_new_19-1.png:
+ Removed a tree that prevented people from sitting on one of the
+ benches properly. Added correct minimap to woodland village and
+ surrounding.
+
+2007-08-22 Joshua Langley <joshlangley[at]optusnet.com.au>
+
+ * data/graphics/gui/item_shortcut_bgr.png, src/game.cpp,
+ src/gui/gui.cpp, src/gui/itemcontainer.cpp,
+ src/gui/itemshortcutcontainer.cpp, src/gui/itemshortcutcontainer.h,
+ src/gui/itemshortcutwindow.cpp, src/gui/itemshortcutwindow.h,
+ src/gui/menuwindow.cpp, src/gui/setup_keyboard.cpp, src/gui/window.h,
+ src/itemshortcut.cpp, src/itemshortcut.h, src/keyboardconfig.cpp,
+ src/keyboardconfig.h, src/localplayer.cpp, src/localplayer.h,
+ src/main.cpp, src/net/inventoryhandler.cpp, src/utils/tostring.h,
+ tmw.cbp: Added item shortcut bar.
+
+2007-08-20 Joshua Langley <joshlangley[at]optusnet.com.au>
+
+ * data/graphics/gui/mouse.png, src/gui/equipmentwindow.cpp,
+ src/gui/gui.cpp, src/gui/gui.h, src/gui/inventorywindow.cpp,
+ src/gui/setup.cpp, src/gui/skill.cpp, src/gui/skill.h,
+ src/gui/status.cpp, src/gui/window.cpp, src/gui/window.h,
+ data/graphics/gui/close_button.png: Added close button functionality,
+ resize cursor cues.
+ * data/graphics/gui/hits_yellow.png, src/being.cpp, src/being.h,
+ src/gui/gui.cpp, src/localplayer.cpp, src/localplayer.h,
+ src/net/charserverhandler.cpp, src/net/playerhandler.cpp,
+ src/particle.cpp, src/particle.h: Added monster killed xp notification
+ effect.
+
+2007-08-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/equipment.xml: Fixed typo in female light plate mail.
+ * NEWS: Updated with changes since 0.0.23.
+
+2007-08-19 Joshua Langley <joshlangley[at]optusnet.com.au>
+
+ * src/keyboardconfig.cpp, src/keyboardconfig.h: Minor cleanup.
+ * src/gui/buy.cpp, src/gui/sell.cpp: Buy/sell fixed minimum quantity.
+ * src/gui/setup_keyboard.cpp, src/gui/setup_keyboard.h: Fixed bug -
+ reverts unassigned key.
+
+2007-08-17 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * tools/adler32.c: Added little program for calculating adler32
+ checksums of files.
+ * src/gui/setup_keyboard.cpp: Fixed compile issue related to array
+ bound not being an integer constant.
+
+2007-08-15 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/npcs.png, data/graphics/sprites/npc.xml:
+ Added farmer NPC for woodland village.
+
+2007-08-14 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/popupmenu.cpp, src/gui/viewport.cpp, src/gui/viewport.h,
+ tmw.cbp: Fixed popup menu requiring one more click after being used.
+
+2007-08-09 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/chest-lightplatemail-male.png,
+ data/graphics/sprites/chest-lightplatemail-female.png,
+ data/graphics/items/armor-chest-lightplatemail.png,
+ data/graphics/tiles/woodland_indoor_x2.png: Gave the platemail
+ armor a blue tint. Looks less boring and makes recoloring through
+ hue shifting possible.
+
+2007-08-08 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/particles/cookingfire.particle.xml,
+ data/graphics/particles/fireplace.particle.xml,
+ data/maps/new_20-1.tmx.gz: Added particle effects and music to the
+ woodland village indoor map.
+ * data/maps/new_19-1.tmx.gz: Added overlay effect and music to
+ woodland village outdoor map.
+ * data/maps/new_18-1.tmx.gz: Fixed some collision map errors and added
+ music and overlay effect to the surrounding of the woodland village.
+
+2007-08-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/npcs.png: Added two new NPCs and gave some
+ of the older NPCs a makeover to look more like the style of the new
+ playerset.
+ * data/maps/new_20-1.tmx.gz: Corrected a few mapping errors in the
+ new woodland village.
+ * data/items.xml: Tweaked description and values of the scythe.
+
+2007-08-06 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/Makefile.am, src/utils/strprintf.h, src/utils/strprintf.cpp:
+ Added a helper function for printf-formatting a (gettext) C string
+ into a dynamically-sized C++ string.
+
+2007-08-05 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/woodland_indoor.png,
+ data/graphics/tiles/woodland_indoor_x2.png,
+ data/graphics/tiles/woodland_indoor_x3.png: Added woodland
+ village indoor tilesets.
+ * data/maps/new_20-1.tmx.gz: Added woodland village indoor map.
+
+2007-07-29 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * CMake/Modules/FindLibXml2.cmake, CMake/Modules/FindLibcurl.cmake,
+ src/CMakeLists.txt: Switch to upstream CMake modules for libxml2 and
+ curl.
+
+2007-07-27 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/resources/image.cpp: Added support for subimages of subimages.
+ * src/gui/equipmentwindow.cpp, src/gui/button.cpp, src/gui/slider.cpp,
+ src/gui/widgets/resizegrip.cpp, src/gui/widgets/dropdown.cpp,
+ src/gui/progressbar.cpp, src/gui/browserbox.cpp, src/gui/gui.cpp,
+ src/gui/radiobutton.cpp, src/gui/textfield.cpp, src/gui/playerbox.cpp,
+ src/gui/itemcontainer.cpp, src/gui/checkbox.cpp, src/gui/minimap.cpp,
+ src/gui/scrollarea.cpp, src/gui/popupmenu.cpp: Removed useless yet
+ costly dynamic casts.
+
+2007-07-25 Joshua Langley <joshlangley[at]optusnet.com.au>
+
+ * src/gui/setup.cpp, src/gui/setup_keyboard.cpp,
+ src/gui/setup_keyboard.h, src/keyboardconfig.cpp,
+ src/keyboardconfig.h, src/main.cpp: Minor changes to keyboard config,
+ keyboard setup gui re-designed.
+
+2007-07-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/CMakeLists.txt, src/Makefile.am: Added setup_keyboard.* and
+ keyboardconfig.* to the list of source files.
+ * src/keyboardconfig.h: Fixed initialization order.
+
+2007-07-17 Joshua Langley <joshlangley[at]optusnet.com.au>
+
+ * src/game.cpp: Only one key per function.
+ * src/main.cpp: Keyboard configuration included.
+ * src/gui/button.cpp, src/gui/button.h: Default constructor and
+ init function added.
+ * src/gui/setup.cpp: Keyboard setup tab added.
+ * src/gui/setup_keyboard.cpp, src/gui/setup_keyboard.h: Add to project
+ file, it is the keyboard setup tab.
+ * src/keyboardconfig.cpp, src/keyboardconfig.h: Add to project file,
+ the main keyboard config operations.
+
+2007-07-16 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/items.xml: Fixed description of silk headband.
+
+2007-07-11 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/resources/monsterdb.cpp, src/resources/monsterinfo.cpp,
+ src/resources/monsterinfo.h, src/monster.cpp: Renamed SoundEvent
+ to MonsterSoundEvent.
+ * src/resources/equipmentdb.cpp, src/resources/equipmentinfo.cpp,
+ src/resources/equipmentinfo.h: EquipmentDB now holds the type of
+ attack animation and the sounds of weapons.
+ * src/being.cpp. src/being.h, src/localplayer.cpp,
+ src/net/beinghandler.cpp, src/net/charserverhandler.cpp,
+ src/net/equipmenthandler.cpp, src/player.cpp, src/player.h: The
+ type of weapon player characters are using is now set using
+ setVisibleEquipment() instead of setWeapon() or setWeaponById().
+ * src/CMakeLists.txt, src/Makefile.AM, tmw.cbp, The Mana World.dev:
+ Updated project files and buildscripts.
+ * data/graphics/images/login-wallpaper.png: Replaced login wallpaper
+ with a new one by Irukard.
+
+2007-07-11 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/window.cpp: Fixed resizing windows by their resize grip.
+
+2007-07-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/gui.cpp, src/gui/chatinput.h, src/gui/chatinput.cpp,
+ INSTALL: Ported to Guichan 0.7.0. Unfortunately, since Guichan 0.6.x
+ didn't have a FocusListener, compatibility with older versions is
+ broken.
+
+2007-06-29 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particleemitter.cpp: Corrected some perspective
+ issues of the particle engine and fixed a crash caused by particles
+ with child emitters that have an image than isn't used elsewhere.
+ * data/maps/new-3-1.tmx.gz: Added a particle effect at the spawn point
+ in Tulimshar.
+
+2007-06-21 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/monsters.xml, data/graphics/sprites/monster-logmonster.png,
+ data/graphics/sprites/monster-logmonster.xml: Added logmonster by
+ Enigmatik (Monster ID is 23).
+ * data/items.xml, data/equipment.xml,
+ data/graphics/items/armor-chest-lightplatemail.png,
+ data/graphics/sprites/chest-lightplatemail-male.xml,
+ data/graphics/sprites/chest-lightplatemail-male.png,
+ data/graphics/sprites/chest-lightplatemail-female.png,
+ data/graphics/sprites/chest-lightplatemail-female.xml:
+ Added light platemail (see entry in items.xml for proposed specs).
+
+2007-06-16 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/resources/image.cpp: Set GL texture index to zero when an image
+ uses the SDL backend.
+
+2007-06-13 Philipp Sehmisch <tmw@crushnet.org>
+
+ * The Mana World.dev: Updated DevCpp project file.
+
+2007-06-13 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/main.cpp: Added logging of version number.
+
+2007-06-12 David Athay <ko2fan@gmail.com>
+
+ * src/net/playerhandler.cpp: Fixed bug with DEF_BONUS not updating
+ Mantis id: 0000087
+ * data/icons/The Mana World.icns: Added Mac OSX icon.
+
+2007-06-11 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.h, src/being.cpp: Fixed a bug that prevented
+ being-controlled particles from being deleted (thanks to tuchs for
+ reporting).
+
+2007-06-06 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/items.xml: Fixed defense of silk headband.
+
+2007-06-04 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/maps/new_17-1.tmx.gz: Changed the minimap image of the
+ lamp snake cave to the correct one.
+
+2007-06-03 David Athay <ko2fan@gmail.com>
+
+ * src/main.cpp, src/game.cpp: Fixed screenshot taking on OSX.
+
+2007-06-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/CMakeLists.txt, src/Makefile.am, docs/Makefile.am: Added some
+ files to be included with the release.
+ * src/utils/fastsqrt.h: Fixed warning about strict-aliasing rules.
+ * src/Makefile.am: Don't die on warnings by default.
+ * src/resources/image.cpp: Fixed image loading in software mode to not
+ check for alpha layer when images aren't 32-bit.
+ * src/graphics.cpp, src/graphics.h, src/imageparticle.cpp: Removed
+ drawImageTransparent from Graphics class, should be set on image.
+ * src/imageparticle.h, src/particleemitter.h, src/particle.h,
+ src/particleemitter.cpp, src/particle.cpp, src/imageparticle.cpp: Have
+ ParticleEmitter load a possible particle image early on and don't
+ cause a crash when the image can't be found.
+
+2007-06-02 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/winver.h, README, NEWS, CMakeLists.txt, configure.ac,
+ data/help/changes.txt, data/help/header.txt: Updated version and
+ release date and summarized changes.
+ * src/gui/chat.h, src/gui/chat.cpp: Changed color of chat messages in
+ OpenGL mode from orange to black.
+ * src/gui/sell.cpp, src/gui/buy.h, src/gui/buy.cpp, src/gui/sell.h:
+ Some cleanup of buy/sell dialog code.
+
+2007-06-01 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/gui/CMakeLists.txt, data/graphics/gui/Makefile.am:
+ Added target cursors to installed files.
+
+2007-05-31 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_16-1.tmx.gz: Fixed an inconsistency with the neighbor
+ map (no new walkmap required).
+
+2007-05-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/sell.cpp, src/gui/buy.cpp, src/being.cpp: A bunch of
+ lingering syntactical changes.
+ * src/gui/viewport.cpp: Added a missing include and fixed a bug with
+ cleaning up target cursor animations.
+
+2007-05-23 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/viewport.cpp,
+ data/graphics/gui/target-cursor-blue-s.png,
+ data/graphics/gui/target-cursor-blue-m.png,
+ data/graphics/gui/target-cursor-blue-l.png,
+ data/graphics/gui/target-cursor-red-s.png,
+ data/graphics/gui/target-cursor-red-m.png,
+ data/graphics/gui/target-cursor-red-l.png: Replaced target cursor
+ graphics with higher quality ones by Pauan.
+ * src/particle.cpp: Made bouncing particles immune against death by
+ ground contact and removed a nonsensical debugging log message. Made
+ text splash effects fade out.
+ * src/textparticle.cpp: Implemented fading in and out for text
+ particles.
+ * src/being.cpp, src/particle.cpp, src/particle.h,
+ src/textparticle.cpp, src/textparticle.h: The color values of text
+ particles are now stored in 3 integers instead of a Guichan color
+ structure.
+
+2007-05-20 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * tmw.cbp: Updated Code::Blocks project file.
+
+2007-05-20 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/buy.cpp, src/gui/sell.cpp: Unified some differences between
+ buy and sell dialog. Money label now shows money after transaction
+ instead of current money.
+ * src/gui/sell.cpp: Fixed the amount-not-reset-when-using-scrollwheel
+ bug.
+ * src/being.h, src/gui/viewport.cpp, src/gui/viewport.h: Added 3
+ different target cursor sizes.
+ * src/monster.h, src/monster.cpp, src/resources/monsterdb.cpp,
+ scr/resources/monsterinfo.h, data/monsters.xml: Target cursor size for
+ monster is read from the monsters.xml.
+ * data/graphics/gui/target-cursor-blue-s.png,
+ data/graphics/gui/target-cursor-blue-m.png,
+ data/graphics/gui/target-cursor-blue-l.png,
+ data/graphics/gui/target-cursor-red-s.png,
+ data/graphics/gui/target-cursor-red-m.png,
+ data/graphics/gui/target-cursor-red-l.png: Added temporary
+ placeholders for small and large target cursors until better versions
+ based on the original SVG are available.
+
+2007-05-08 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/monster-bat.png,
+ data/graphics/sprites/monster-bat.xml,
+ data/graphics/sprites/monster-flower.xml,
+ data/graphics/sprites/monster-fluffy.xml,
+ data/graphics/sprites/monster-fluffy.png,
+ data/graphics/sprites/monster-goblin-fire.xml,
+ data/graphics/sprites/monster-maggot-giant.xml,
+ data/graphics/sprites/monster-maggot.xml,
+ data/graphics/sprites/monster-mountsnake.xml,
+ data/graphics/sprites/monster-mushroom-red.xml,
+ data/graphics/sprites/monster-mushroom-spiky.xml,
+ data/graphics/sprites/monster-pinkie.xml,
+ data/graphics/sprites/monster-scorpion-black.xml,
+ data/graphics/sprites/monster-scorpion-red.png,
+ data/graphics/sprites/monster-scorpion-red.xml,
+ data/graphics/sprites/monster-skull-poison.xml,
+ data/graphics/sprites/monster-slime-green.xml,
+ data/graphics/sprites/monster-slime-red.xml,
+ data/graphics/sprites/monster-slime-rudolph.xml,
+ data/graphics/sprites/monster-slime-santa.png,
+ data/graphics/sprites/monster-slime-santa.xml,
+ data/graphics/sprites/monster-slime-yellow.xml,
+ data/graphics/sprites/monster-snake-cave.png,
+ data/graphics/sprites/monster-snake-cave.xml,
+ data/graphics/sprites/monster-snake.xml,
+ data/graphics/sprites/monster-spider.xml:
+ Adjusted offsets of monster sprites (thanks to Pauan for finding out
+ the correct offsets - I just subtracted 6 of all x offsets to take the
+ new position of the target circle in account) and committed some
+ modifications at some monster graphics by Pauan.
+
+2007-05-02 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/sprite.h, src/being.cpp, src/being.h, src/animatedsprite.cpp,
+ src/animatedsprite.h: Added methods to get the width and height of the
+ graphical representation of a sprite.
+ * src/gui/viewport.cpp: Fixed positioning of monster names and target
+ circles.
+
+2007-05-02 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp: Fixed a compiler warning.
+
+2007-05-02 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am: Add the new particle subclasses to the automake
+ configuration.
+ * src/imageparticle.h, src/textparticle.h, src/particle.h,
+ src/animationparticle.h, src/CMakeLists.txt, src/particleemitter.cpp,
+ src/animationparticle.cpp, src/particle.cpp, src/imageparticle.cpp,
+ src/textparticle.cpp, src/utils/xml.cpp, src/utils/xml.h: Split the
+ particle class into subclasses based on their appearance.
+
+2007-04-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h: Some minor code cleanups, speed
+ optimizations and a bit of documentation.
+
+2007-04-23 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/particles/flame.particle.xml,
+ data/graphics/particles/blaze.png: Added two files I forgot with the
+ last commit.
+ * src/resources/mapreader.cpp, src/particle.cpp,
+ src/particleemitter.cpp: Using XML child node iteration macro.
+
+2007-04-22 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/configuration.cpp, src/utils/xml.h, src/resources/mapreader.cpp,
+ src/resources/spritedef.cpp, src/resources/monsterdb.cpp,
+ src/resources/itemdb.cpp, src/resources/equipmentdb.cpp: Added a macro
+ for XML child node iterations to make the code more terse and easier
+ to read.
+ * src/resources/itemdb.cpp: Made the parameter checks more terse and
+ manageable.
+
+2007-04-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/resources/mapreader.cpp: Emitter positions are now read from map
+ files.
+ * src/engine.cpp: Removed the player follow effect used for testing.
+ * data/maps/new_4-1.tmx.gz, data/maps/new_5-1.tmx.gz: Added flame
+ effect to all lamps on the cave maps
+ * data/maps/new_9-1.tmx.gz: Added waterfall effect to the upper right
+ corner of NW woodland map.
+
+2007-04-15 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/openglgraphics.cpp: Rely on default 0 value for z axis.
+ * src/CMakeLists.txt, src/gui/window.cpp, src/gui/widgets,
+ src/gui/widgets/resizegrip.cpp, src/gui/widgets/resizegrip.h,
+ src/gui/inventorywindow.cpp, src/gui/window.h, src/Makefile.am:
+ Reimplemented window resizing. It is now once again possible to resize
+ windows using their borders (except for the top one, since that's the
+ title bar for Guichan) and the resize grip in the bottom right is much
+ easier to grab.
+ * src/gui/window.cpp: Increased minimum window height and fixed a
+ problem with setting window content size which was introduced with the
+ new resize grip.
+
+2007-04-13 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * data/graphics/gui/CMakeLists.txt: Added target cursor graphics to
+ the set of files to be installed.
+
+2007-03-25 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Improved programming style and documentation
+ and added some small tweaks.
+ * src/engine.cpp, src/map.cpp, src/map.h, src/resources/mapreader.cpp:
+ Prepared getting the emitter positions from the map file by storing
+ them in the Map class and setting them up from the MapReader.
+
+2007-03-22 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/simpleanimation.cpp, src/simpleanimation.h: Added new
+ constructor for simple animation that allows to build the animation
+ based on an xmlNodePtr pointing to an <animation> node.
+ * src/particle.cpp, src/particle.h: Added support for <image> and
+ <animation> childtags for effect root particles.
+ * data/graphics/particles/playerglow.particle.xml: New player follow
+ effect that demonstrates an animated root particle with an emitter.
+
+2007-04-05 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/main.cpp: Unified storage of configuration, updates and
+ screenshots in home directory.
+
+2007-04-03 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/items/generic-easteregg-blue.png,
+ data/graphics/items/generic-easteregg-green.png,
+ data/graphics/items/generic-easteregg-pink.png,
+ data/graphics/items/generic-easteregg-red.png,
+ data/graphics/items/generic-easteregg-teal.png,
+ data/graphics/items/generic-easteregg-yellow.png,
+ data/items.xml: Added six different easter egg item graphics for the
+ easter event. Item IDs are 1208 - 1213.
+ * data/graphics/sprites/npcs.png: Added bunny girl npc for the easter
+ event.
+
+2007-04-01 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/game.cpp: Screenshots are no longer saved directly in the users
+ home directory on UNIX systems but in the sub folder /.tmw/. A chatlog
+ message about the success of the screenshot saving does appear now.
+ Based on a patch by Patrick "the-me" Matthäi.
+
+2007-03-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp: Icon loading doesn't necessarily succeed, so better
+ not crash when it doesn't.
+
+2007-03-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp: Changed the order of network message handling and
+ logic, in order to prevent an incoming character delete message from
+ deleting the player character that was about to be drawn.
+ * src/gui/char_select.cpp: Removed useless lock/unlock calls.
+ * src/logindata.h, src/main.cpp, src/gui/login.cpp: Go back to login
+ or register state on error, depending on what the user was doing.
+ * src/gui/register.cpp: Actually use the server that is filled in.
+ * src/net/loginhandler.cpp: Fixed error message.
+ * src/net/charserverhandler.cpp: Fixed crash since now logic is called
+ after non-selected characters are deleted, by properly setting deleted
+ instances to 0 and going back to initial selection.
+ * src/main.cpp, src/net/network.h, src/net/network.cpp: Make sure that
+ when a network error occurs, the error message is available and shown
+ to the user.
+ * src/gui/register.h, src/gui/register.cpp: Only enable Register
+ button when all necessary fields are filled in.
+
+2007-03-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/char_select.cpp, src/gui/char_select.h,
+ src/net/charserverhandler.h, src/net/charserverhandler.cpp: Clarified
+ the error message when character creation fails and made sure the
+ character creation dialog doesn't close when creation failed.
+
+2007-03-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/login.cpp, src/gui/login.h, src/gui/register.h,
+ src/gui/register.cpp: Only enable login button when a username,
+ password and server are filled in. Pass username, password and server
+ on to the register dialog. Go back to login dialog when canceling
+ registration. Fixed a crash caused by deleting an OkDialog twice (it
+ also deletes itself). Made the register dialog a bit wider. Register
+ dialog no longer clears username field when it is invalid.
+ * src/main.cpp, data/icons/CMakeLists.txt, data/icons/Makefile.am,
+ data/icons/tmw-32x32.png: Use a 32x32 non-alpha layered window icon.
+ * tmw.cbp: Updated project file.
+ * data/icons/CMakeLists.txt, data/icons/Makefile.am, src/main.cpp,
+ data/icons/tmw-32x32.png: Removed 32x32 non-alpha layered window icon
+ again, and instead used the icon in the executable on Windows.
+
+2007-03-21 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp, src/gui/viewport.cpp, src/resources/image.h,
+ src/resources/image.cpp: Reduced amount of useless logging, calculate
+ nearest power of two in a function and only do the alpha check in
+ software mode.
+ * src/gui/login.cpp: Fixed small issue where default server didn't fit
+ in the server entry field properly.
+ * src/main.cpp: Display a progress bar and connecting status for each
+ server and display the version using a gcn::Label.
+ * src/gui/viewport.cpp, src/monster.h: Avoiding magic numbers where
+ possible (1002) and also display the target when other players are
+ targeted.
+ * src/floor_item.cpp, src/being.cpp, src/main.cpp, src/CMakeLists.txt,
+ src/gui/equipmentwindow.cpp, src/gui/viewport.cpp,
+ src/gui/itemcontainer.cpp, src/gui/viewport.h, src/engine.cpp,
+ src/animatedsprite.cpp, src/tileset.h, src/npc.cpp, src/Makefile.am,
+ src/being.h, src/resources/imageset.cpp, src/resources/animation.h,
+ src/resources/spritedef.cpp, src/resources/resourcemanager.h,
+ src/resources/spriteset.h, src/resources/imageset.h,
+ src/resources/resourcemanager.cpp, src/resources/spriteset.cpp,
+ src/resources/spritedef.h: Renamed Spriteset to ImageSet.
+
+2007-03-20 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/updatewindow.cpp: Cancel button is now disabled after
+ downloading is finished.
+
+2007-03-20 David Athay <ko2fan@gmail.com>
+
+ * src/gui/viewport.cpp: Fixed target cursor animation, and changed
+ which layer it is drawn after.
+ * src/gui/viewport.cpp, src/gui/viewport.h: Split drawing the target
+ cursor and target name into functions.
+
+2007-03-20 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/gui/mouse.png: Positioned the cursor image more
+ accurate.
+
+2007-03-19 David Athay <ko2fan@gmail.com>
+
+ * src/localplayer.cpp, src/gui/viewport.cpp, src/gui/viewport.h,
+ src/net/equipmenthandler.cpp, src/localplayer.h,
+ src/net/protocol.h: Added target cursor.
+
+2007-03-18 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * docs/Makefile.am, docs/tmw.6: Added man page by Patrick Matthäi.
+ * src/resources/image.cpp: Restored alpha layer check, since it should
+ be more efficient in software mode when SDL knows an image doesn't use
+ the alpha layer.
+ * data/graphics/gui/thickborder.png,
+ data/graphics/gui/vscroll_grey.png, data/graphics/gui/slider.png,
+ data/graphics/gui/vscroll_blue.png, data/graphics/gui/vscroll_red.png,
+ data/graphics/gui/deepbox.png,
+ data/graphics/sprites/monster-slime-red.png,
+ data/graphics/sprites/monster-scorpion-black.png,
+ data/graphics/sprites/monster-scorpion.png,
+ data/graphics/sprites/monster-slime-rudolph.png,
+ data/graphics/sprites/monster-snake.png,
+ data/graphics/sprites/monster-slime-santa.png,
+ data/graphics/sprites/monster-maggot.png,
+ data/graphics/sprites/monster-spider.png,
+ data/graphics/sprites/monster-scorpion-red.png,
+ data/graphics/sprites/monster-slime-yellow.png,
+ data/graphics/sprites/monster-slime-green.png,
+ data/graphics/sprites/monster-maggot-giant.png: Replaced pink pixels
+ with transparent ones.
+
+2007-03-18 Rogier Polak <rogier.l.a.polak@gmail.com>
+
+ * src/main.cpp: Added (-v) version to the arguments. (Applied a patch
+ by Patrick Matthäi).
+ * src/resources/image.cpp: Deleted the "pink code", which added
+ transparancy with SDL_SetColorKey.
+
+2007-03-18 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * icons/tmw.ico, icons/tmw.png, icons/tmw.xpm: Replaced icons with the
+ green globe that is also used on the website.
+
+2007-03-14 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp, src/tmw.rc, data/icons/tmw-icon.png,
+ data/icons/tmw-icon.xpm, data/icons/tmw.ico, data/icons/tmw-icon.ico,
+ data/icons/Makefile.am, data/icons/tmw.png, data/icons/tmw.xpm,
+ data/icons/CMakeLists.txt: Renamed icons to make things easier for
+ Debian packaging, and the "-icon" part was superfluous anyway.
+
+2007-03-12 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/simpleanimation.cpp, src/simpleanimation.h, src/CmakeLists.txt,
+ src/Makefile.am: Added a simple animation class that hosts a looping
+ animation without the action and direction stuff from AnimatedSprite.
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp: Used said
+ simple animation class for animated particles.
+
+2007-03-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/items/armor-head-rangerhat.png: New version of ranger
+ hat icon by Pauan.
+
+2007-03-11 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/map.cpp, src/gui/viewport.cpp: Fixed a bug that made the engine
+ not draw the last row and column of the map.
+
+2007-03-09 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp: Reimplemented physics mode that uses the default
+ square root function as fallback for systems where the fastInvSqrt
+ function doesn't work properly.
+ * src/particle.cpp, src/particle.h: Some performance optimizations
+ suggested by Rogier "Avaniel" Polak.
+
+2007-03-09 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/gui/target-cursor-blue.png,
+ data/graphics/gui/target-cursor-red.png: Added targeting cursors by
+ Pauan.
+ * data/graphics/sprites/chest-cotton-male.png,
+ data/graphics/sprites/chest-cotton-female.png: Replaced cotton shirt
+ with improved version by Pauan.
+
+2007-02-27 Philipp Sehmisch <tmw@crushnet.org>
+
+ * gui/button.cpp, src/guibutton.h,
+ src/gui/tabbedcontainer.cpp, src/gui/tabbedcontainer.h:: Tabbed
+ containers now display the button of the active tab pressed all
+ the time.
+
+2007-02-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac: Made OpenGL enabled by default.
+
+2007-02-26 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/sfx/maggot-dying1.ogg, data/sfx/maggot-hit1.ogg,
+ data/sfx/maggot-hit2.ogg, data/sfx/maggot-miss1.ogg,
+ data/sfx/pinkie-hit1.ogg, data/sfx/pinkie-miss1.ogg,
+ data/monsters.xml: New sound effects by Cosmostrator.
+
+2007-02-25 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.h, src/particleemitter.h: Just some documentation work.
+
+2007-02-22 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Added new particle property "bounce" that makes
+ particles bounce off the ground and use it with the damage numbers.
+
+
+2007-02-21 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/char-server.cpp, src/gui/updatewindow.cpp, src/gui/main.cpp,
+ src/gui/main.h: Added a new state "LOADDATA_STATE" that loads the XML
+ databases.
+ * src/resourcemanager.cpp, src/resourcemanager.h, src/main.cpp,
+ customdata/: Added a customdata dir that allows to add custom user
+ data easily. Just create a zip file with the same structure like the
+ update archives and drop it in the customdata folder and the files in
+ it override the default data and the updates.
+
+2007-02-15 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/engine.cpp: The name conflict problem with Guichan seems to be
+ solved with version 0.6.1.
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Added support for animated particles.
+ * data/graphics/particles/playerglow.particle.xml: Created a new
+ player follow particle that spawns a swarm of animated bats that
+ follow the player.
+
+2007-02-09 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp: Fixed a misspelled include and another
+ optimisation at the vector calculation.
+
+2007-02-08 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/utils/fastsqrt.h: Added a faster function to
+ calculate square roots and using it for hypotenuse calculations.
+ Thanks to Rogier aka Avaniel for finding the function.
+
+2007-02-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp: Renamed
+ Particle::MAX_PARTICLES to Particle::maxCount and read the value from
+ config ("particleMaxCount")
+ * src/particle.cpp: Added fast physics mode that replaces the
+ trigonometric calculations made for calculating the acceleration by
+ much less cpu intense but also less accurate formulas. To enable it
+ set the config option "particleFastPhysics" to "1".
+ * src/particle.cpp: Added the config option "particleEmitterSkip" that
+ allows to reduces the output of the emitters by making them spawn
+ particles only every n-th game tick.
+ * src/graphics.cpp, src/graphics.h: Added a new method
+ "drawImageTransparent" to the graphic engine that blits an image with
+ an alpha factor.
+ * src/particle.cpp: Using new drawImageTransparent method.
+
+2007-02-01 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Implemented die-distance (particles are deleted
+ when they reached a certain proximity to their target)
+ * src/particle.cpp: Fixed a bug in the acceleration vector calculation.
+ * src/particle.cpp, src/particle.h: Fixed a problem with particles with
+ unlimited lifetime and fade-in.
+ * data/graphics/particles/playerglow.particle.xml: And again a new
+ player follow particle. This time it demonstrates die-distance and the
+ fixed acceleration vector calculation.
+ * src/engine.cpp, data/graphics/particles/snow.particle.xml,
+ data/graphics/particles/snowflake.png: I can't stand the begging
+ anymore. Now it snows in the snow area... and the forest... and the
+ desert... and under the earth... and indoors... Are you happy now,
+ Rotonen and Elven? ;-)
+ * src/particle.cpp: Removed some debug log messages.
+ * src/being.cpp: Avoided crash when attempting to control an invalid
+ particle.
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Cleaned the includes up.
+
+2007-01-31 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Changed some variable names.
+ * data/graphics/particles/waterfall.particle.xml,
+ data/graphics/particles/waterfall-a.png: New waterfall with Modanungs
+ waterfall particle.
+ * src/particle.cpp: forgot to remove a svn conflict marker and changed
+ the order of initialisations to fix some compiler warnings.
+
+2007-01-30 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * tmw.cbp: Updated Code::blocks project file.
+
+2007-01-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/beinghandler.cpp,
+ data/graphics/particles/skillup.particle.xml: Added different particle
+ effect for job levelup.
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Renamed "alphafade" to "fade-out", added new
+ property "fade-in".
+ * data/graphics/particles/playerglow.particle.xml: Added a new player
+ effect (a fire) demonstrating how to use fade-in and fade-out to fade
+ one color into another.
+
+2007-01-29 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Added a new particle property "alphafade" that
+ makes the particles fade into alpha before their lifetime ends.
+ * src/particle.cpp, src/particle.h: fixed an issue with particles that
+ have a lifetime of 0 and an issue with the momentum property.
+ * data/graphics/particles/waterfall.particle.xml,
+ data/graphics/particles/fog-medium-white-a.png,
+ data/graphics/particles/fog-medium-white-b.png,
+ data/graphics/particles/fog-medium-white-c.png: Added fog to the
+ waterfall effect demonstrating the new alphafade feature.
+
+2007-01-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/utils/xml.cpp, src/utils/xml.h, src/particleemitter.cpp: Most
+ values are now read as floating point values from the emitter files.
+ * data/graphics/particles/fountain.particle.xml,
+ data/graphics/particles/hit.particle.xml,
+ data/graphics/particles/playerglow.particle.xml: Changed some values
+ as floating point values. Made the player follow effect magenta to
+ improve the visibility of the hit effects.
+ * src/engine.cpp, data/graphics/particles/waterfall.particle.xml:
+ Removed the fountain and added a waterfall instead.
+ * src/particle.h: Corrected the drawing order of the particles in
+ relation to the other sprites.
+ * src/gui/debugwindow.cpp, src/gui/debugwindow.h: Added particle count
+ to debug window.
+ * src/particle.cpp: Allowed momentum without acceleration and
+ implement the acceleration properly.
+ * src/utils/minmax.h, src/particleemitter.cpp, src/particleemitter.h:
+ Added a structure to hold a pair of numeric minimum and maximum values
+ and used it to store all numeric emitter properties.
+ * src/utils/randbetween.h: Removed (the functionality is now in struct
+ MinMax)
+
+2007-01-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/shoplistbox.cpp: Fixed compilation against Guichan 0.6.1.
+ * src/utils/randbetween.h: Fixed integer overflow causing the
+ randBetween function not to work properly on Linux.
+
+2007-01-27 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/beinghandler.cpp: Fixed a compiler issue.
+
+2007-01-27 Philipp Sehmisch <tmw@crushnet.org>
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h, src/engine.cpp: Emitter data is read from
+ external xml files. Reimplemented target-based particles with the
+ difference that they don't target beings or locations but other
+ particles (at the moment the host particle of the effect).
+ * src/being.cpp: Beings now move controlled particles to their center
+ instead of their upper left corner.
+ * data/graphics/particles/orb*: Added a bunch of new particles.
+ * data/graphics/particles/fountain.particle.xml: Reimplementation of
+ the fountain effect in XML.
+ * data/graphics/particles/playerglow.particle.xml: New effect that
+ spawns orbs that orbit around the origin.
+ * src/being.cpp, data/graphics/particles/hit.particle.xml: Added
+ particle effect on hit.
+ * src/net/beinghandler.cpp,
+ data/graphics/particles/levelup.particle.xml: Added particle effect on
+ levelup (own or other player).
+
+2007-01-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp: Initialized all variables of the particles in the
+ constructor.
+ * src/particleemitter.cpp, src/particleemitter.h: minor cleanups.
+
+2007-01-22 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/being.cpp, src/being.h, src/particle.cpp, src/particle.h
+ src/particleemitter.cpp, src/particleemitter.h, src/engine.cpp:
+ Particle effects are now created in child particles of the root
+ particle. Particle emitters have no longer a being they check every
+ frame. Instead beings have the ability to take control of particles.
+
+2007-01-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h, src/particleemitter.cpp,
+ src/particleemitter.h: Implemented emitters that follow a being.
+ * src/engine.cpp: Added an emitter that follows the local player.
+ * src/particle.cpp: Fixed the crash on exit (reason was that the
+ mSpriteIterator wasn't initialized in every case)
+
+2007-01-18 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/particle.h, src/particle.cpp, src/CMakeLists.txt,
+ src/Makefile.am: Fixed compilation issues on Linux.
+
+2007-01-15 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/game.cpp, src/particle.cpp, src/particle.h,
+ src/particleemitter.h: Made the particle count global and more
+ performant.
+
+2007-01-14 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/main.cpp, src/gui/trade.cpp, src/gui/sell.cpp,
+ src/gui/connection.cpp, src/gui/buddywindow.cpp, src/gui/browserbox.h,
+ src/gui/char_server.cpp, src/gui/window.cpp, src/gui/login.cpp,
+ src/gui/inttextbox.h, src/gui/viewport.cpp, src/gui/button.h,
+ src/gui/shoplistbox.h, src/gui/skill.h, src/gui/item_amount.h,
+ src/gui/setup_audio.h, src/gui/newskill.cpp, src/gui/listbox.h,
+ src/gui/register.h, src/gui/setup.cpp, src/gui/npclistdialog.h,
+ src/gui/updatewindow.cpp, src/gui/button.cpp, src/gui/char_select.cpp,
+ src/gui/login.h, src/gui/setup_audio.cpp, src/gui/item_amount.cpp,
+ src/gui/setup_joystick.h, src/gui/chat.h, src/gui/npc_text.cpp,
+ src/gui/setup_video.cpp, src/gui/ok_dialog.cpp,
+ src/gui/inventorywindow.h, src/gui/gccontainer.cpp,
+ src/gui/newskill.h, src/gui/buy.h, src/gui/setup.h,
+ src/gui/itemcontainer.h, src/gui/confirm_dialog.cpp,
+ src/gui/debugwindow.cpp, src/gui/chat.cpp, src/gui/setup_joystick.cpp,
+ src/gui/updatewindow.h, src/gui/char_select.h, src/gui/buysell.h,
+ src/gui/tabbedcontainer.cpp, src/gui/inventorywindow.cpp,
+ src/gui/help.cpp, src/gui/status.h, src/gui/npc_text.h,
+ src/gui/setup_video.h, src/gui/menuwindow.cpp, src/gui/browserbox.cpp,
+ src/gui/ok_dialog.h, src/gui/buy.cpp, src/gui/itemcontainer.cpp,
+ src/gui/gccontainer.h, src/gui/buddywindow.h, src/gui/sell.h,
+ src/gui/trade.h, src/gui/inttextbox.cpp, src/gui/char_server.h,
+ src/gui/window.h, src/gui/shoplistbox.cpp, src/gui/skill.cpp,
+ src/gui/buysell.cpp, src/gui/confirm_dialog.h, src/gui/debugwindow.h,
+ src/gui/status.cpp, src/gui/listbox.cpp, src/gui/register.cpp,
+ src/gui/viewport.h, src/gui/tabbedcontainer.h,
+ src/gui/npclistdialog.cpp, src/gui/help.h, src/gui/chatinput.h,
+ src/gui/chatinput.cpp, src/net/tradehandler.cpp,
+ src/net/playerhandler.cpp: Upgraded to Guichan 0.6.0 (merge from
+ guichan-0.6.0 branch).
+ * src/winver.h, configure.ac, data/help/header.txt, NEWS, README,
+ CMakeLists.txt: Updated version to 0.0.22.1.
+
+2007-01-14 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/particle.cpp, src/particle.h; src/particleemitter.cpp,
+ src/particleemitter.h, src/utils/randbetween.h:
+ Implemented particle engine.
+ * src/engine.cpp, src/game.cpp: added calls to the particle engine
+ * data/graphics/particles/*: added a bunch of particle graphics for
+ testing purpose.
+ * particleengine-todo.txt: Added particle engine todo list (please
+ omit when merging)
+
+2007-01-13 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/CMakeLists.txt: Updated with regard to renaming
+ of cotton equipment.
+
+2006-01-13 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/debugwindow.cpp, src/gui/viewport.h: Fixed mouse coordinates
+ display in debug window.
+
+2007-01-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/viewport.cpp: Fixed initialization of mPlayerFollowMouse,
+ the lack of which sometimes caused the player to start walking when
+ clicking on the GUI.
+
+2007-01-09 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/icecave.png: Added new tiles and fixes by Nickman and
+ made some other cosmetical corrections.
+
+2007-01-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/sprites/monster-mountsnake.xml,
+ data/graphics/sprites/monster-mountsnake.png, data/monsters.xml: Added
+ brown snake by Pauan.
+
+2007-01-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/chest-cottonshirt-male.png,
+ data/graphics/chest-cottonshirt-male.xml,
+ data/graphics/chest-cottonshirt-female.png,
+ data/graphics/chest-cottonshirt-female.xml,
+ data/graphics/item001.png, data/equipment.xml: Added female
+ cottonshirt sprites.
+ * data/equipment.xml: Fixed some wrong armor values.
+
+2007-01-05 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/CMakeLists.txt, data/graphics/images/ambient/Makefile.am,
+ data/graphics/sprites/CMakeLists.txt: Synchronized build files.
+
+2006-12-12 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * tools/Purger.java: Removed purger tool.
+
+2006-12-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/tiles/christmastree.png, data/maps/new_11-1.tmx.gz:
+ Added Christmas tree by Pauan.
+ * data/graphics/sprites/head-christmastree.xml: Fixed name of image.
+ * src/resources/spriteset.cpp: Fixed index check to prevent crashing.
+ * data/graphics/sprites/head-christmastreehat.png,
+ data/graphics/sprites/head-rangerhat.png,
+ data/graphics/sprites/head-christmastree.xml,
+ data/graphics/sprites/head-antlerhat.xml,
+ data/graphics/sprites/head-santabeardhat.xml,
+ data/graphics/sprites/head-santabeardhat.png,
+ data/graphics/sprites/head-rangerhat.xml: Updates to Pauan's recent
+ sprites by Pauan.
+ * data/items.xml: Fixes to descriptions and weights by Pauan.
+
+2006-12-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/shoplistbox.cpp: Don't try to draw an icon when it is not
+ defined or failed to load properly.
+ * src/resources/image.cpp: Major rendering performance increase in
+ software mode, by not using RLE compression on loaded images while
+ most of the time, we're only drawing a small subimage of them.
+ * README, data/help/header.txt, NEWS: Filled in release dates.
+
+2006-12-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac, data/graphics/items/Makefile.am,
+ data/graphics/items/CMakeLists.txt, data/graphics/images/Makefile.am,
+ data/graphics/images/CMakeLists.txt,
+ data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/CMakeLists.txt, data/graphics/Makefile.am,
+ data/graphics/CMakeLists.txt, data/maps/Makefile.am,
+ data/maps/CMakeLists.txt, data/sfx/Makefile.am,
+ data/sfx/CMakeLists.txt, data/Makefile.am, data/CMakeLists.txt:
+ Removed database files, minimaps, items, monster sprites, maps and
+ sounds from the release. They will be released dynamically only.
+ * data/graphics/tiles/snow_x3.png: Added bottom of Christmas tree by
+ pauan.
+ * src/main.cpp, src/resources/itemdb.h, src/resources/monsterdb.cpp,
+ src/resources/itemdb.cpp, src/resources/equipmentdb.cpp: Load the
+ databases at the start of the LOGIN state, after the updates are
+ loaded.
+
+2006-12-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/items/armor-head-rangerhat.png,
+ data/graphics/items/generic-redstocking.png,
+ data/graphics/items/armor-head-christmastree.png,
+ data/graphics/items/armor-head-antlerhat.png,
+ data/graphics/items/armor-head-santabeardhat.png,
+ data/graphics/sprites/head-christmastreehat.png,
+ data/graphics/sprites/head-rangerhat.png,
+ data/graphics/sprites/head-christmastree.xml,
+ data/graphics/sprites/head-antlerhat.xml,
+ data/graphics/sprites/head-santabeardhat.xml,
+ data/graphics/sprites/head-antlerhat.png,
+ data/graphics/sprites/head-santabeardhat.png,
+ data/graphics/sprites/head-rangerhat.xml, data/items.xml,
+ data/equipment.xml, data/monsters.xml: Added new Christmas themed
+ headwear by Pauan.
+ * data/graphics/items/Makefile.am, data/graphics/items/CMakeLists.txt,
+ data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/CMakeLists.txt, data/Makefile.am,
+ data/CMakeLists.txt: Updated Makefiles.
+
+2006-12-21 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac, CMakeLists.txt, README, data/help/header.txt: Updated
+ version to 0.0.22.
+
+2006-12-18 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/items/armor-chest-vnecksweater.png: New version of
+ the inventory icon for the V-neck sweater by Saphy.
+
+2006-12-17 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/sell.cpp, src/gui/shoplistbox.h, src/gui/listbox.h,
+ src/gui/shop.cpp, src/gui/buy.cpp, src/gui/shoplistbox.cpp,
+ src/gui/listbox.cpp: Subclassed ShopListBox from ListBox to get rid of
+ some duplicated code, and fixed a problem with scrolling to the
+ current selection. Also aligned the text a bit better and put the
+ price in parenthesis.
+
+2006-12-16 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/connection.cpp, src/gui/chargedialog.cpp: Fixed dialog
+ visibility.
+ * src/localplayer.cpp, src/game.cpp, src/localplayer.h: Fixed issues
+ with walking one tile too many and changing direction towards an
+ obstacle.
+
+2006-12-15 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/desert1.png: Removed some unused legacy tiles and
+ added variant tiles for the cliffs.
+
+2006-12-14 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/engine.h, src/engine.cpp: Removed the rather
+ useless remaining draw function from the engine class.
+ * src/being.cpp, src/being.h: Fixed an issue with fading out damage
+ texts (they were sometimes fully opaque at the end of fading out).
+
+2006-12-12 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, tmw.cbp: Updated project files.
+ * src/gui/updatewindow.cpp, src/gui/updatewindow.h, src/main.cpp:
+ Added Adler32 checksum for updates.
+ * src/net/playerhandler.cpp: Fixed crash when selecting an item after
+ death.
+ * data/items.xml: Fixed defense values for sweaters.
+ * src/net/playerhandler.cpp: Hide all NPC dialogs after death.
+
+2006-12-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/animatedsprite.h, src/CMakeLists.txt, src/animatedsprite.cpp,
+ src/resources/action.h, src/resources/animation.h,
+ src/resources/spritedef.cpp, src/resources/action.cpp,
+ src/resources/animation.cpp, src/resources/spritedef.h: Moved
+ Action, Animation and Frame (renamed from AnimationPhase) classes into
+ the resources directory, since they are part of the SpriteDef class.
+ * src/CMakeLists.txt, src/utils/base64.cpp, src/utils/base64.h,
+ src/Makefile.am, src/resources/mapreader.cpp: Moved base64 module into
+ utils directory.
+ * src/engine.cpp, src/npc.cpp: Cleaned up some unused stuff.
+
+2006-12-12 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/sfx/bat-dying1.ogg, data/sfx/bat-hit1.ogg,
+ data/sfx/bow_shoot_1.ogg, data/sfx/fire-goblin-hit1.ogg
+ data/sfx/fire-goblin-hit2.ogg, data/sfx/fire-goblin-miss1.ogg,
+ data/sfx/fist-swish.ogg, data/sfx/flower-hit1.ogg,
+ data/sfx/flower-hit2.ogg, data/sfx/flower-miss1.ogg,
+ data/sfx/fluffy-hit1.ogg, data/sfx/fluffy-hit2.ogg,
+ data/sfx/fluffy-hit3.ogg, data/sfx/fluffy-hurt1.ogg,
+ data/sfx/fluffy-miss1.ogg, data/sfx/knife-hit1.ogg,
+ data/sfx/knife-miss1.ogg, data/sfx/levelup.ogg
+ data/sfx/scorpion-hit1.ogg, data/sfx/scorpion-hit2.ogg
+ data/sfx/scorpion-hit3.ogg, data/sfx/scorpion-hit4.ogg
+ data/sfx/scorpion-miss1.ogg, data/sfx/short-sword-hit1.ogg
+ data/sfx/short-sword-miss1.ogg, data/sfx/shroom-hit1.ogg
+ data/sfx/slime-hit1.ogg:
+ Normalized versions of sound effects by Cosmostrator.
+
+2006-12-11 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/updatewindow.cpp: Fixed visibility of the update window.
+
+2006-12-11 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/equipment.xml, data/items.xml,
+ data/graphics/sprites/chest-tnecksweater-male.png,
+ data/graphics/sprites/chest-tnecksweater-female.png,
+ data/graphics/sprites/chest-vnecksweater-male.png,
+ data/graphics/sprites/chest-vnecksweater-female.png,
+ data/graphics/sprites/chest-tnecksweater-male.xml,
+ data/graphics/sprites/chest-tnecksweater-female.xml,
+ data/graphics/sprites/chest-vnecksweater-male.xml,
+ data/graphics/sprites/chest-vnecksweater-female.xml,
+ data/graphics/sprites/Makefile.AM,
+ data/graphics/sprites/CMakeLists.txt,
+ data/graphics/items/armor-chest-vnecksweater.png,
+ data/graphics/items/armor-chest-tnecksweater.png,
+ data/graphics/items/armor-chest-woolsweater.png,
+ data/graphics/items/Makefile.AM, data/graphics/items/CMakeLists.txt:
+ Added new sweaters by Saphy. Info for server admins: Item IDs are 564
+ for turtleneck (should already be in there) and 624 for v-neck. The
+ visible sprite IDs are 19 for turtleneck and 20 for v-neck.
+
+2006-12-11 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/main.h, src/tmw.rc, src/winver.h, The Mana World.dev, tmw.cbp:
+ Fixed windows binary version.
+
+2006-12-10 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * docs/INSTALL/win32.txt: Added more detailed instructions for Dev-C++
+ users.
+
+2006-12-09 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/npcs.png: Added pirate NPC.
+
+2006-12-09 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/sprite.h, src/gui/playerbox.h, src/gui/char_select.cpp,
+ src/gui/playerbox.cpp, src/gui/passwordfield.h, src/gui/char_select.h,
+ src/main.cpp, src/being.cpp, src/player.h, src/floor_item.h,
+ src/being.h: Use new animation system in character selection/creation.
+ Shows equipment and allowed for some cleanup. Had a bit of help from
+ the patch by VictorSan.
+
+2006-12-08 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/base64.cpp, src/base64.h, src/resources/mapreader.cpp:
+ Downgraded to base64 codec from PHP 3 to resolve licensing issues.
+
+2006-12-06 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, tmw.cbp: Updated project files.
+
+2006-12-06 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/beinghandler.cpp: Fixed crashs when changing equipment.
+ * data/graphics/tiles/desert1.png, data/graphics/tiles/desert2.png:
+ More tiling related fixes at the cliffs.
+
+2006-12-06 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/item_amount.cpp: Fixed visibility of item amount window.
+
+2006-12-05 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/desert1.png: Improved the tiling behavior
+ of the cliffs (still not gridless but at least the edges fit
+ together in the most common situations)
+
+2006-12-04 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/engine.h, src/gui/windowcontainer.h,
+ src/gui/viewport.cpp, src/gui/gui.cpp, src/gui/gui.h,
+ src/gui/debugwindow.cpp, src/gui/inventorywindow.cpp,
+ src/gui/viewport.h, src/engine.cpp, src/CMakeLists.txt,
+ src/Makefile.am: Introduced a new class Viewport which combines the
+ drawing code from Engine with the (rather misplaced) input handling
+ from the Gui class. Also, it's a Container itself which should allow
+ for extending it to show Guichan widgets on map coordinates.
+
+2006-12-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/sound.cpp, src/monster.cpp, src/sound.h,
+ src/resources/soundeffect.cpp, src/resources/resourcemanager.cpp:
+ Don't try to play empty strings as sounds, and don't return a
+ SoundEffect instance when Mix_Chunk loading failed.
+ * src/beingmanager.cpp, src/npc.cpp, src/npc.h: Show NPC names.
+ * src/game.cpp, src/gui/char_server.cpp, src/gui/window.cpp,
+ src/gui/login.cpp, src/gui/char_select.cpp, src/gui/ok_dialog.cpp,
+ src/gui/confirm_dialog.cpp, src/gui/ok_dialog.h, src/gui/window.h,
+ src/gui/confirm_dialog.h, src/gui/register.cpp: Windows now default
+ to invisible, since this seems the most common case.
+
+2006-12-02 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/chest-leather-female.png: A little correction
+ at the female leather shirt by mangamaniac.
+
+2006-12-01 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/net/beinghandler.cpp, src/being.h, src/being.cpp, src/monster.h,
+ src/gui/gui.cpp: Visible equipment slot numbers are now converted by
+ the beinghandler from eAthena to our system. No more distinction
+ between monster attacking and player attacking between beinghandler
+ and the being classes.
+ * src/being.cpp, src/monster.cpp, src/being.h, src/monster.h: Moved
+ the monster specific action handling into the monster class.
+ * monster.cpp, mosterinfo.cpp, monsterinfo.h: Monsters now make sounds
+ when they attack, gett hurt or die.
+ * src/being.cpp: Delayed the damage numbers a bit to synchronize them
+ better with the hurt sounds.
+ * data/monsters.xml, data/sfx//bat-dying1.ogg, data/sfx/bat-hit1.ogg,
+ data/sfx/bow_shoot_1.ogg, data/sfx/fire-goblin-hit1.ogg,
+ data/sfx/fire-goblin-hit2.ogg, data/sfx/fire-goblin-miss1.ogg,
+ data/sfx/fist-swish.ogg, data/sfx/flower-hit1.ogg,
+ data/sfx/flower-hit2.ogg, data/sfx/flower-miss1.ogg,
+ data/sfx/fluffy-hit1.ogg, data/sfx/fluffy-hit2.ogg,
+ data/sfx/fluffy-hit3.ogg, data/sfx/fluffy-hurt1.ogg,
+ data/sfx/fluffy-miss1.ogg, data/sfx/knife-hit1.ogg,
+ data/sfx/knife-miss1.ogg, data/sfx/levelup.ogg,
+ data/sfx/scorpion-hit1.ogg, data/sfx/scorpion-hit2.ogg,
+ data/sfx/scorpion-hit3.ogg, data/sfx/scorpion-hit4.ogg,
+ data/sfx/scorpion-miss1.ogg, data/sfx/short-sword-hit1.ogg,
+ data/sfx/short-sword-miss1.ogg, data/sfx/shroom-hit1.ogg,
+ data/sfx/slime-hit1.ogg, data/sfx/Makefile.AM,
+ data/sfx/CMakeLists.txt: Added a lot of sound effects by Cosmostrator.
+
+2006-11-30 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/maps/Makefile.am: Fixed small trailing slash issue.
+ * src/player.cpp: Optimized setSex and setWeapon by first loading the
+ new sprite and then deleting the old one (prevents potentially
+ unnecessary reload).
+ * src/net/beinghandler.cpp: Optimized handling of player walk
+ messages, by first setting the gender right and then setting the
+ equipment. Gets rid of reload of complete equipment in the case of
+ female.
+
+2006-11-30 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, tmw.cbp: Updated project files.
+
+2006-11-29 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/monster.cpp: Small fix to resource path.
+
+2006-11-29 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/resources/equipment.h: Made getSprite return a constant
+ reference.
+ * src/resources/monsterdb.cpp, src/resources/monsterdb.h,
+ src/resources/monsterinfo.cpp, src/resources/monsterinfo.h,
+ src/Makefile.AM, src/CMakeLists.txt, src/main.cpp:
+ Added the MonsterDB namespace that reads the monsters.xml
+ and maps monster IDs to names, sprite definitions and sound effects.
+ * src/monster.cpp: Get sprite definition filenames from MonsterDB.
+ * src/engine.cpp: Show monster name when targeting a monster.
+ * data/monsters.xml, data/graphics/sprites/Makefile.AM,
+ data/graphics/sprites/CMakeLists.txt, data/graphics/sprites/monster*:
+ Renamed all monster sprites to more associative names (whew, we got to
+ train some monkeys for tasks like that).
+
+2006-11-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * tmw.cbp: Updated Code::Blocks project file.
+
+2006-11-27 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/log.cpp, src/util/wingettimeofday.h: Added implementation of
+ gettimeofday() for windows machines.
+
+2006-11-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/log.cpp: Higher precision log timestamps.
+ * src/graphics.cpp, src/gui/gui.cpp, src/openglgraphics.cpp,
+ src/main.cpp, src/resources/equipmentdb.cpp,
+ src/resources/resourcemanager.cpp: Added some additional log
+ statements.
+ * src/resources/itemdb.cpp: Removed usage of READ_PROP in favour of
+ XML::getProperty and updated log statements.
+ * src/resources/image.cpp: Added support for loading TGA images.
+
+2006-11-26 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/resources/resourcemanager.cpp: Remove unnecessary check for
+ file existance, loading will just fail with the correct error message.
+
+2006-11-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/being.cpp, src/net/beinghandler.cpp, src/being.h:
+ Made Being::mDirection protected, forcing the use of setDirection.
+ * src/npc.cpp, src/player.cpp, src/animatedsprite.h, src/monster.cpp,
+ src/resources/resourcemanager.h: Defaulted variant argument to 0 since
+ this is the most common situation.
+ * src/resources/spritedef.cpp, src/resources/spritedef.h: Some
+ refactoring, splitting up the loading into several methods, in
+ preparation of adding support for including other sprites.
+ * src/main.cpp: ItemDB needs to be unloaded before deleting the
+ resource manager instance, since ItemInfo refers to an Image.
+
+2006-11-26 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/being.cpp, src/being.h, src/engine.cpp, src/main.cpp,
+ src/player.cpp, src/player.h, src/resources/equipmentdb.h,
+ src/resources/equipmentdb.cpp, src/resources/equipmentinfo.h,
+ src/resources/itemdb.cpp, src/resources/itemdb.h,
+ data/graphics/images/error.png, data/graphics/sprites/error.xml:
+ Added the EquipmentDB namespace that reads the equipment.xml, maps
+ equipment IDs to sprite definition files and thus allows gender
+ specific equipment sprites.
+ * data/graphics/sprites/chest-leather-female.png,
+ data/graphics/sprites/chest-leather-male.png,
+ data/graphics/sprites/chest-leather-female.xml,
+ data/graphics/sprites/chest-leather-male.xml,
+ data/equipment.xml: Added and defined male and female leather shirt as
+ proof of concept of the gender specific equipment.
+ * data/graphics/images/Makefile.am, data/graphics/sprites/Makefile.am,
+ data/Makefile.am, src/Makefile.am,
+ data/graphics/images/CMakeLists.txt,
+ data/graphics/sprites/CMakeLists.txt, data/CMakeLists.txt,
+ src/CMakeLists.txt: Updated Makefiles and CMake Lists.
+
+2006-11-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/engine.cpp, src/floor_item.cpp, src/item.h, src/main.cpp,
+ src/gui/buy.cpp, src/gui/popupmenu.cpp, src/gui/sell.cpp,
+ src/gui/shop.cpp, src/net/inventoryhandler.cpp,
+ src/resources/itemdb.cpp, src/resources/itemdb.h,
+ src/resources/iteminfo.h, src/resources/itemmanager.cpp,
+ src/resources/itemmanager.h: Refactored the Itemmanager class to an
+ ItemDB namespace.
+
+2006-11-23 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, tmw.cbp: Updated project files.
+
+2006-11-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/setup_joystick.cpp: Fixed joystick option to show enabled
+ when the joystick is enabled.
+ * src/localplayer.cpp, src/game.cpp, src/action.h, src/action.cpp,
+ src/player.cpp, src/animatedsprite.h, src/being.cpp, src/animation.h,
+ src/monster.cpp, src/CMakeLists.txt, src/player.h,
+ src/animatedsprite.cpp, src/localplayer.h, src/animation.cpp,
+ src/Makefile.am, src/being.h, src/resources/resourcemanager.cpp,
+ src/resources/spritedef.cpp, src/resources/resourcemanager.h,
+ src/resources/spriteset.h, src/resources/spritedef.cpp: Separated
+ sprite definition from playback.
+
+2006-11-17 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * data/graphics/sprites/CMakeLists.txt: Fixed some filenames.
+
+2006-11-17 Wai Ling Tsang <simotsa@gmail.com>
+
+ * src/gui/gui.cpp: Added mouse following ability/feature under
+ logic().
+ * src/gui/gui.h: Added mouseMotion(), mouseRelease() and private
+ variables for mouse following.
+
+2006-11-15 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/Woodland_village.png,
+ data/graphics/tiles/Woodland_village_x2.png,
+ data/graphics/tiles/Woodland_x2.png,
+ data/graphics/tiles/Makefile.AM,
+ data/graphics/tiles/CMakeList.txt,
+ data/maps/new_9-1.tmx.gz, data/maps/new_14-1.tmx.gz,
+ data/maps/new_15-1.tmx.gz, data/maps/new_16-1.tmx.gz,
+ data/maps/new_17-1.tmx.gz, data/maps/new_18-1.tmx.gz,
+ data/maps/new_19-1.tmx.gz, data/maps/CMakeList.txt,
+ data/maps/Makefile.AM:
+ Added woodland village outdoor tileset and maps. Modified gates on
+ the nearby maps.
+
+2006-11-15 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/animatedsprite.h, src/CMakeLists.txt, src/animatedsprite.cpp,
+ src/utils/xml.cpp, src/utils/xml.h, src/Makefile.am,
+ src/resources/mapreader.cpp: Separated getProperty method to an XML
+ utility namespace.
+
+2006-11-15 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, tmw.cbp: Updated project files.
+ * The Mana World.dev, tmw.cbp: Fixed dynamic linking of libcurl.
+
+2006-11-14 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/action.h, src/action.cpp, src/animation.h, src/CMakeLists.txt,
+ src/animatedsprite.cpp, src/animation.cpp, src/Makefile.am: Separated
+ Action class to its own module.
+ * src/action.h, src/action.cpp, src/animatedsprite.h, src/animation.h,
+ src/animatedsprite.cpp, src/animation.cpp: Resolve Image* of animation
+ phase at load time instead of storing just the spriteset index and
+ looking it up later (checking validity should still be added). Also
+ calculate animation length during loading instead of summing it up
+ each time it is requested.
+
+2006-11-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/map.cpp, src/map.h: Made pathfinding algorithm cope better with
+ beings blocking the road. This is done by allowing walking over other
+ beings, but at an additional cost so that it is preferable to walk
+ around them.
+ * src/game.cpp: Worked around a Guichan exception thrown for mice with
+ many buttons (patch by Roel van Dijk).
+
+2006-11-09 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/main.cpp, src/net/network.cpp, src/net/network.h,
+ The Mana World.dev, tmw.cbp: Fixed a conflict with Windows headers and
+ updated project files.
+
+2006-11-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/trade.cpp: Fixed money field to no longer hide below the
+ bottom of the window.
+ * src/CMakeLists.txt: Added shoplistbox.h/cpp files.
+ * src/gui/updatewindow.cpp: Fixed percentage indicator of update
+ window.
+ * src/main.cpp, src/net/beinghandler.cpp, src/net/skillhandler.cpp,
+ src/net/network.cpp: Changed some printf statements to log statements.
+
+2006-11-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/images/login_wallpaper.png: Reverted to standard
+ wallpaper.
+ * src/resources/resourcemanager.cpp: More useful logging about
+ resources that are being loaded (including source).
+ * src/graphics.cpp, src/gui/window.cpp, src/gui/button.cpp,
+ src/gui/widgets/dropdown.cpp, src/gui/textfield.cpp,
+ src/gui/playerbox.cpp, src/gui/progressbar.cpp,
+ src/gui/scrollarea.cpp, src/graphics.h, src/CMakeLists.txt,
+ src/Makefile.am, src/graphic, src/graphic/imagerect.h: Merged the
+ definition of ImageRect into graphics.h.
+
+2006-11-05 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/Makefile.am, src/gui/buy.cpp, src/gui/buy.h, src/gui/shop.h,
+ src/gui/shop.cpp, src/gui/sell.cpp, src/gui/shoplistbox.h,
+ src/gui/shoplistbox.cpp: Added pictures to items in buy dialogs.
+ Also too expensive items are highlighted in gray and can't be
+ selected.
+ * src/gui/shop.cpp, src/gui/shop.h, src/gui.sell.h, src/gui/sell.cpp,
+ src/net/buysellhandler.cpp, src/gui/shoplistbox.h,
+ src/gui/shoplistbox.cpp: Added item's pictures in sell dialogs, and
+ precisions about the total money in it.
+ * src/gui/shop.h, src/gui/shop.cpp, src/gui/sell.cpp: Fixes to Sell
+ dialog.
+ * src/gui/sell.cpp: Fixes the money value after selling something.
+
+2006-11-05 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * data/graphics/sprites/Makefile.am: Use tabs instead of spaces as
+ required by automake (AFAIK).
+
+2006-11-05 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/weapon0.png,
+ data/graphics/sprites/weapon2.png,
+ data/graphics/sprites/weapon-bow.xml,
+ data/graphics/sprites/weapon-dagger.xml,
+ data/graphics/sprites/weapon-fist.xml,
+ data/graphics/sprites/weapon-scythe.xml,
+ data/graphics/items/weapon-polearm-scythe.png, src/player.cpp,
+ src/player.h, src/being.cpp, src/being.h, data/items.xml: Added scythe
+ as a permanent weapon (ID: 623)
+
+2006-11-04 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/updatewindow.cpp, src/gui/updatewindow.h: Removed useless
+ addRow method.
+
+2006-11-04 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/maps/new_1-1.tmx.gz, data/maps/new_10-1.tmx.gz,
+ data/maps/new_11-1.tmx.gz, data/maps/new_14-1.tmx.gz,
+ data/maps/new_15-1.tmx.gz, data/maps/new_16-1.tmx.gz,
+ data/maps/new_3-1.tmx.gz, data/maps/new_7-1.tmx.gz,
+ data/maps/new_9-1.tmx.gz: Reverted Halloween map versions, except for
+ map 10 and 11 which include the latest fixes by Crush but now have
+ their night layer removed.
+
+2006-11-04 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_17-1.tmx.gz,
+ data/graphics/images/minimap_new_17-1.png,
+ data/graphics/images/Makefile.am,
+ data/graphics/images/CMakeLists.txt:
+ Added music and minimap to woodland cave level 2.
+ * data/maps/new_10-1.tmx.gz, maps/new_11-1.tmx.gz:
+ Fixed some map bugs (please update server sided walkmap)
+
+2006-11-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/updatewindow.cpp, src/main.cpp: Updated to the new default
+ updatehost.
+
+2006-11-01 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/gui.cpp, src/gui/browserbox.cpp,
+ data/graphics/gui/rpgfont_wider.png,
+ data/graphics/gui/browserfont.png, data/graphics/gui/fixedfont.png:
+ Added support for å and Å (with help of Håkan Rönn).
+
+2006-10-31 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/desert1.png, data/graphics/tiles/desert_x2.png:
+ Adding a bunch of graphical improvements made by VxD.
+
+2006-10-31 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * data/graphics/sprites/item011.png,
+ data/graphics/sprites/item011.xml, data/graphics/sprites/item012.png,
+ data/graphics/sprites/item018.xml,
+ data/graphics/sprites/monster21.xml: Fixed some graphical issues,
+ mostly a cosmetic update.
+
+2006-10-30 Yohann Ferreira <bertram@cegetel.net>
+
+ * debian/changelog: Updated the package's version.
+
+2006-10-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_9-1.tmx.gz: Removed the night effect that accidentally
+ sneaked in with the last map change.
+
+2006-10-30 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/tmw.rc: Updated Windows binary version.
+ * data/help/header.txt, NEWS, README: Fixed some release dates and
+ versions.
+ * data/graphics/items/armor-head-axehat.png,
+ data/graphics/items/armor-head-bandana.png,
+ data/graphics/items/armor-head-circlet.png,
+ data/graphics/items/armor-head-eyepatch.png,
+ data/graphics/items/armor-head-goggles.png,
+ data/graphics/items/armor-head-leathergoggles.png,
+ data/graphics/items/armor-head-piratehat.png,
+ data/graphics/items/armor-head-pumpkinhelmet.png,
+ data/graphics/items/Makefile.am, data/items.xml: Added new items.
+ * data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/monster21.png,
+ data/graphics/sprites/monster21.xml,
+ data/graphics/sprites/monster22.png,
+ data/graphics/sprites/monster22.xml: Added new monsters.
+ * data/graphics/sprites/item011.png, data/graphics/sprites/item011.xml,
+ data/graphics/sprites/item012.png, data/graphics/sprites/item012.xml,
+ data/graphics/sprites/item013.png, data/graphics/sprites/item013.xml,
+ data/graphics/sprites/item014.png, data/graphics/sprites/item014.xml,
+ data/graphics/sprites/item015.png, data/graphics/sprites/item015.xml,
+ data/graphics/sprites/item016.png, data/graphics/sprites/item016.xml,
+ data/graphics/sprites/item017.png, data/graphics/sprites/item017.xml,
+ data/graphics/sprites/item018.png, data/graphics/sprites/item018.xml,
+ data/graphics/sprites/Makefile.am: Added new visible equipments.
+ * data/graphics/images/login_wallpaper.png, data/maps/new_1-1.tmx.gz,
+ data/maps/new_10-1.tmx.gz, data/maps/new_11-1.tmx.gz,
+ data/maps/new_14-1.tmx.gz, data/maps/new_15-1.tmx.gz,
+ data/maps/new_16-1.tmx.gz, data/maps/new_3-1.tmx.gz,
+ data/maps/new_7-1.tmx.gz, data/maps/new_9-1.tmx.gz: Halloween related
+ contents.
+ * data/graphics/items/Makefile.am: Fixed wrong filename.
+ * data/graphics/sprites/Makefile.am: Fixed wrong filenames.
+ * data/graphics/sprites/weapon0.png: Replaced knife with scythe.
+
+2006-10-30 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * data/graphics/items/CMakeLists.txt: Synced with autotools config.
+ * data/graphics/items/CMakeLists.txt: Added new items to CMake config.
+ * src/being.cpp: Properly initialize sprite vector.
+
+2006-10-29 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac, The Mana World.dev, CMakeLists.txt,
+ data/help/header.txt, NEWS: Set version to 0.0.21.1.
+ * src/player.cpp: Fixed excessive unnecessary reloading of sprites.
+
+2006-10-28 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/main.c: Reload wallpaper after updates are fetched.
+ * data/graphics/sprites/Makefile.am: Added monster20.
+
+2006-10-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/monster20.png,
+ data/graphics/sprites/monster20.xml,
+ data/graphics/sprites/CMakeLists.txt:
+ Added pumpkin ghost monster for halloween event.
+ * data/maps/new_9-1.tmx.gz: Fixed a map discrepancy between
+ new_9-1 and new_14-1 (no new walkmap required). Thanks to QOAL
+ for reporting.
+
+2006-10-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/images/ambient/night.png: added graphic for night
+ ambient effect.
+
+2006-10-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac: Added zlib check before PhysFS check. The PhysFS check
+ was failing on MSYS because of a missing -lz.
+
+2006-10-22 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * CMakeLists.txt, src/CMakeLists.txt: Add PACKAGE_VERSION support.
+ * CMakeLists.txt, src/CMakeLists.txt: Setup the binary dir in the main
+ CMakeLists.txt file.
+ * src/main.h: Include config.h only when we have it.
+ * src/CMakeLists.txt: Properly set build flags for the tmw target.
+
+2006-10-18 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/CMakeLists.txt, data/graphics/tiles/CMakeLists.txt,
+ data/graphics/items/CMakeLists.txt, data/graphics/gui/CMakeLists.txt,
+ data/graphics/images/ambient/CMakeLists.txt,
+ data/graphics/images/CMakeLists.txt,
+ data/graphics/sprites/CMakeLists.txt, data/maps/CMakeLists.txt,
+ data/sfx/CMakeLists.txt, data/help/CMakeLists.txt,
+ data/icons/CMakeLists.txt, data/CMakeLists.txt, CMakeLists.txt: Add
+ TMW_DATADIR definition.
+
+2006-10-16 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/CMakeLists.txt: Adjusted path for Windows.
+
+2006-10-16 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * CMakeLists.txt: Enable OpenGL by default.
+ * CMake/Modules/FindLibcurl.cmake: Fix libcurl library not being
+ marked as advanced option.
+ * CMakeLists.txt, src/CMakeLists.txt: Add OpenGL option.
+ * data/CMakeLists.txt: Adjust data destination for Windows.
+ * src/CMakeLists.txt: Adjust binary destination for Windows.
+ * src/CMakeLists.txt, data/graphics/tiles/CMakeLists.txt,
+ data/graphics/items/CMakeLists.txt, data/graphics/gui/CMakeLists.txt,
+ data/graphics/images/ambient/CMakeLists.txt,
+ data/graphics/images/CMakeLists.txt,
+ data/graphics/sprites/CMakeLists.txt, data/graphics/CMakeLists.txt,
+ data/maps/CMakeLists.txt, data/sfx/CMakeLists.txt,
+ data/help/CMakeLists.txt, data/icons/CMakeLists.txt,
+ data/CMakeLists.txt, CMakeLists.txt: Add CMake install support.
+ * CMake/Modules/FindGuichan.cmake, CMake/Modules/FindLibXml2.cmake,
+ CMake/Modules/FindLibcurl.cmake, CMakeLists.txt, src/CMakeLists.txt:
+ Add basic CMake support for building tmw.
+
+2006-10-12 Yohann Ferreira <bertram@cegetel.net>
+
+ * debian/rules, debian/tmw-data.install, debian/tmw-data.dirs,
+ debian/tmw-music.install, debian/changelog: Updating Debian files for
+ bug fixing.
+
+2006-10-12 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * /data/graphics/sprites/npcs.png: Updated the clothes salesman,
+ it was way out of date.
+
+2006-10-12 Cédric Borgese <cedric.borgese@gmail.com>
+
+ * data/graphics/tiles/Woodland_x3.png: Enlarge the trunk and the
+ base of the trees in the woodland tileset.
+
+2006-10-09 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/gui/buysell.cpp, src/gui/buy.cpp : A little tweak to the buy
+ dialogs.
+
+2006-10-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/resources/mapreader.cpp: Added support for gzip compressed map
+ layers.
+ * configure.ac, The Mana World.dev: Increased version to 0.0.22.
+ * src/map.cpp: Removed unused setSize method. Also introduced
+ initializeOverlays method and removed the confusing setOverlay (which
+ actually added one).
+ * src/properties.h: Added convenience method to read a property as a
+ float.
+ * src/map.cpp, src/resources/ambientoverlay.cpp,
+ src/resources/ambientoverlay.h: Resolved some weirdness involving
+ the terms scroll and speed.
+
+2006-10-07 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, tmw.cbp: Updated project files.
+
+2006-10-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/sprites/item006.xml,
+ data/graphics/sprites/item007.xml,
+ data/graphics/sprites/item008.xml,
+ data/graphics/sprites/item009.xml,
+ data/graphics/sprites/item006.png,
+ data/graphics/sprites/item007.png,
+ data/graphics/sprites/item008.png,
+ data/graphics/sprites/item009.png,
+ data/graphics/sprites/item010.xml,
+ data/graphics/sprites/item010.png: Removed empty frames from
+ headgears.
+
+2006-10-03 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/map.cpp, src/map.h, src/Makefile.am,
+ src/resources/mapreader.cpp, src/resources/ambientoverlay.cpp,
+ src/resources/ambientoverlay.h: Turned AmbientOverlay into a class.
+ Cleaned up the associated code.
+
+2006-10-01 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * tools/Purger.java: Added a tool to purge old accounts from eAthena's
+ database files.
+
+2006-10-01 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/gui/trade.cpp, src/gui/inventorywindow.cpp:
+ Accepted patches by GDO and VictorSan that fix problems with hiding
+ windows using h and problems with trade window positioning.
+
+2006-09-28 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/map.cpp: Fix random crashes when map tiles are missing.
+
+2006-09-28 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/maps/new_2-1.tmx.gz: Matt Howe fixed up cave map.
+
+2006-09-26 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/maps/new_6-1.tmx.gz: Alderan fixed a map issue.
+
+2006-09-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/sprites/hairstyle*.png,
+ data/graphics/sprites/hairstyle*.xml, tools/Reorganize.java: Removed
+ unused frames from the hairsets.
+ * src/resources/image.h: Defined NO_SDL_GLEXT to prevent a
+ redefinition when gl.h also tries to define OpenGL extensions (patch
+ accepted from Rogier Polak).
+
+2006-09-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/maps/new_5-1.tmx.gz: Accepted new version by Matt Howe, fixing
+ several mapping issues.
+
+2006-09-21 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/tiles/Makefile.am: Added missing tileset.
+ * src/gui/updatewindow.cpp, src/gui/updatewindow.h: Made canceling the
+ update process non-blocking (Patch by VictorSan).
+
+2006-09-21 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/animation.cpp, src/animation.h, src/animatedsprite.cpp,
+ src/animatedsprite.h: Removed some obsolete code and implemented
+ the posibility to define an <end /> token in the <animation>s
+ that allows to define an animation that doesn't loop and returns
+ to the STAND animation when finished.
+ * data/graphics/sprites/hairstyle*.xml,
+ data/graphics/sprites/item0*.xml,
+ data/graphics/sprites/monster*.xml,
+ data/graphics/sprites/weapons.xml: Used the <end /> token for all
+ attack animations fixing the problem with looping monster attack
+ animations.
+
+2006-09-20 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/items/generic-whitefur.png,
+ data/graphics/items/generic-cavesnakelamp.png,
+ data/graphics/items/generic-hardspike.png,
+ data/graphics/items/generic-pinkantennae.png,
+ data/graphics/items/Makefile.am, data/items.xml: Added drops for new
+ monsters.
+ * src/gui/setup.cpp, src/gui/setup_video.cpp,
+ src/gui/setup_video.h: Added a slider for controlling the overlay
+ detail to the video setup dialog based on a patch by VictorSan.
+ * data/maps/new_14-1.tmx.gz, data/maps/new_16-1.tmx.gz: Added cloud
+ effect and minimap.
+ * data/images/Makefile.am: Updated makefile.
+
+2006-09-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/sprites/Makefile.am: Added missing monster19 sprite.
+
+2006-09-17 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/maps/Makefile.am: Added missing maps.
+ * data/maps/new_10-1.tmx.gz: Disabled layer compression.
+
+2006-09-18 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_9-1.tmx.gz: Fixed some mapping bugs (new walkmap
+ required).
+
+2006-09-17 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/maps/new_10-1.tmx.gz: Fixed transparent snow issue (Fix by
+ Pajarico).
+
+2006-09-17 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp: Stop using the sticky window attribute which is
+ unneeded for the current implementation, instead adjust the set of
+ affected windows by the 'hide' shortcut.
+
+2006-09-17 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_14-1.tmx.gz, data/maps/new_15-1.tmx.gz,
+ data/maps/new_16-1.tmx.gz: fixed some mapping errors.
+
+2006-09-16 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/animatedsprite.cpp, src/animatedsprite.h: Fixed the crash when
+ attacking without a weapon, some additional stability improvements and
+ more descriptive variable names in the parsing algorithmn.
+
+2006-09-16 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/help/changes.txt, data/help/header.txt, NEWS, README,
+ src/tmw.rc: Updated release infos.
+
+2006-09-14 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/animation.h, src/animatedsprite.h,
+ data/graphics/sprites/weapon.xml: Some modifications at the animation
+ system. No more "undefined action foo" warnings in the tmw.log. Not
+ visible actions must now be declared explicitly.
+ * data/graphics/images/ambient/sandstorm.png,
+ data/graphics/images/ambient/clouds.png: Improved quality of the overlay
+ graphics.
+
+2006-09-14 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/char_select.cpp: Remove debug output.
+ * src/gui/char_select.cpp, src/main.cpp: Fix the character name
+ matching loop and add support for saving the last used character
+ (based on a patch by Andrew Harrison).
+ * src/gui/char_select.cpp, src/gui/char_select.h, src/main.cpp: Clean
+ up the player selection stuff, it's a bit nicer now.
+ * src/main.cpp: Fix up the player selection command line option.
+
+2006-09-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/game.h: Simplified fps limiting a bit and added
+ some comments. Now based on ConfigListener so that the fpslimit option
+ doesn't need to be queried the whole time.
+ * NEWS: Updated with some items.
+
+2006-09-11 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp: Fixed more fps issues.
+
+2006-09-09 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/gui.cpp: Removed easy targeting functionality since it
+ interferes with walking around too much. Targeting can still be rather
+ conveniently done with 'a' or the middle mouse button.
+
+2006-09-07 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/resources/image.cpp: Fixed a typo.
+ * src/resources/image.cpp: Worked around a memory leak when using
+ OpenGL.
+
+2006-09-06 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/item010.png, data/graphics/sprites/item010.xml,
+ data/graphics/sprites/Makefile.am: Added santa hat sprites and updated
+ makefile.
+
+2006-09-06 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp, src/gui/setup_video.cpp, src/main.cpp: Fixed fps
+ limiter issues and increased default limit to 60.
+ * src/game.cpp: Fixed fps limiter when disabled.
+
+2006-09-05 Philipp Sehmisch <tmw@crushnet.org>
+ * data/graphics/tiles/Woodland_ground.png,
+ data/graphics/tiles/Woodland_x2.png,
+ data/graphics/tiles/Woodland_x3.png: Some minor improvements and
+ additions at my tilesets.
+ * data/graphics/sprites/monster0.xml,
+ data/graphics/sprites/monster1.xml,
+ data/graphics/sprites/monster2.xml,
+ data/graphics/sprites/monster3.xml,
+ data/graphics/sprites/monster4.xml,
+ data/graphics/sprites/monster5.xml,
+ data/graphics/sprites/monster6.xml,
+ data/graphics/sprites/monster8.xml,
+ data/graphics/sprites/monster9.xml,
+ data/graphics/sprites/monster11.xml,
+ data/graphics/sprites/monster13.xml,
+ data/graphics/sprites/monster0.xml: Adjusted the animation speed of
+ several monsters.
+
+2006-09-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/floor_item.cpp, src/gui/equipmentwindow.cpp, src/gui/sell.cpp,
+ src/gui/trade.cpp, src/gui/inventorywindow.h,
+ src/gui/selectionlistener.h, src/gui/itemcontainer.h,
+ src/gui/inventorywindow.cpp, src/gui/buy.cpp,
+ src/gui/itemcontainer.cpp, src/gui/popupmenu.cpp, src/item.h,
+ src/net/inventoryhandler.cpp, src/Makefile.am,
+ src/resources/itemmanager.h, src/resources/iteminfo.cpp,
+ src/resources/iteminfo.h, src/resources/itemmanager.cpp: Introduced
+ SelectionListener to fix updating problem in inventory window (should
+ also be used to fix similar problem in trade, buy and sell dialogs).
+ Made the ItemInfo be passed around as a reference instead of a pointer,
+ since it is never NULL.
+ * src/gui/trade.cpp, src/gui/trade.h: Fixed updating of labels in
+ trade window.
+ * src/gui/sell.cpp, src/gui/listbox.h, src/gui/inventorywindow.h,
+ src/gui/buy.h, src/gui/buy.cpp, src/gui/sell.h, src/gui/listbox.cpp:
+ Fixed updating of labels in buy and sell dialogs. Also made our
+ listbox respond to mouse dragging to change the selection.
+
+2006-09-02 Bernard Lidicky <bernard@matfyz.cz>
+
+ * src/game.cpp, src/beingmanager.h, src/gui/gui.cpp,
+ src/beingmanager.cpp, src/localplayer.h, README,
+ data/help/commands.txt, NEWS: Added targeting nearest monster with
+ either keyboard or mouse. Also made clicking beings in general a bit
+ easier (patch applied by Bjørn Lindeijer).
+
+2006-09-01 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/monster19.png,
+ data/graphics/sprites/monster19.xml, data/graphics/tiles/arena.png,
+ data/graphics/tiles/cave.png, data/maps/new_17-1.tmx.gz,
+ data/maps/new_6-1.tmx.gz: Added new big cave map, lamp-snake monster,
+ improved arena map.
+
+2006-08-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/item007.png,
+ data/graphics/sprites/item007.xml, data/graphics/sprites/item009.png,
+ data/graphics/sprites/item009.xml:
+ Added sprites for miners helm and standard headband.
+
+2006-08-29 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/map.cpp, src/beingmanager.h, src/gui/minimap.cpp,
+ src/engine.cpp, src/beingmanager.cpp: It's better to use a reference
+ when you don't need a pointer.
+ * NEWS: Updated with addition of config file option.
+
+2006-08-29 Andrew Harrison <atharris@users.sourceforge.net>
+
+ * src/main.cpp: Added command line option to specify which
+ configuration file to use (patch applied by Bjørn Lindeijer).
+
+2006-08-29 Matthias Hartmann <hartmann.matthias@gmail.com>
+
+ * data/graphics/sprites/item006.png,
+ data/graphics/sprites/item006.xml, data/graphics/sprites/item008.xml:
+ Fixed fancy hat + silk headband positions.
+
+2006-08-29 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/item008.png,
+ data/graphics/sprites/item008.xml, data/graphics/sprites/Makefile.am:
+ Added fancy hat sprite.
+
+2006-08-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/gui/setup_video.cpp: Modified the ranges of the ScrollLaziness
+ and ScrollRadius sliders.
+
+2006-08-28 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/items/*: Changed svn properties.
+ * data/graphics/sprites/item001.xml, data/graphics/sprites/item002.xml,
+ data/graphics/sprites/item003.xml, data/graphics/sprites/item004.xml,
+ data/graphics/sprites/item005.xml, data/graphics/sprites/item006.png,
+ data/graphics/sprites/item006.xml, data/graphics/sprites/Makefile.am:
+ Added headband and fixed svn properties.
+
+2006-08-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/net/inventoryhandler.cpp: Applied patch by Andrew Harrison that
+ adds item pickup messages to the chat window.
+ * NEWS: Updated with some recently added and fixed issues. Doesn't
+ mention any of the recent content updates yet.
+
+2006-08-26 Pascal Ganaye <pascalganaye@users.sourceforge.net>
+
+ * src/joystick.h, src/joystick.cpp, src/gui/setup.cpp,
+ src/gui/setup_joystick.h, src/gui/setup_video.cpp,
+ src/gui/setup_joystick.cpp, src/gui/setup_video.h: Added sliders to
+ the video section of the setup window to configure the laziness and
+ radius of the scrolling behaviour. Added a checkbox to the joystick
+ section to allow enabling/disabling the joystick (patch applied by
+ Bjørn Lindeijer).
+
+2006-08-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/ministatus.cpp, src/gui/ministatus.h: Applied patch by mrha
+ (Herbi), adding experience bar to the ministatus in the top left.
+ * configure.ac, data/graphics/items/Makefile.am,
+ data/graphics/Makefile.am: Added Makefile.am to make sure the item
+ icons are installed.
+ * src/player.cpp, src/animation.h, src/player.h,
+ src/animatedsprite.cpp, src/animation.cpp: Applied patch by Bahamut81
+ which implements resetting of Animation, Action and AnimatedSprite.
+ This fixes the animation synchronization issues.
+
+2006-08-25 Matthias Hartmann <hartmann.matthias@gmail.com>
+
+ * src/gui/char_select.cpp, src/gui/char_select.h, src/main.cpp: Added
+ --playername command line option for selecting the character you want
+ to play with (patch applied by Bjørn Lindeijer).
+
+2006-08-25 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/engine.cpp, src/map.h, src/map.cpp: Addded new config variable
+ "OverlayDetail" to control the number of drawn overlays.
+ 2 (or more) = all (default), 1 = only the first one, 0 = none.
+
+2006-08-24 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/help/commands.txt, README, src/game.cpp, src/gui/chat.cpp,
+ src/gui/window.cpp, src/gui/window.h: Added support for sticky windows
+ as discussed with doener. Patch by Andrew Harrison.
+ * data/items.xml: Added jeans shorts.
+
+2006-08-24 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/engine.cpp: Scrolling speed no longer affected by framerate.
+ * src/map.cpp, scr/map.h: Overlay speed no longer affected by
+ framerate.
+ * data/maps/new_1-1.tmx.gz, data/graphics/new_7-1.tmx.gz,
+ data/graphics/images/ambient/sandstorm.png: Redone sandstorm effect
+ (larger and more transparent image, tripple layer parallax scrolling)
+
+2006-08-24 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * data/graphics/sprites/item004.png,
+ data/graphics/sprites/item005.png, data/graphics/sprites/Makefile.am,
+ data/graphics/items/armor-legs-cottonshorts,
+ data/graphics/items/armor-legs-jeanshorts: Added the equip graphics of
+ the short jeans and the cotton shorts and an inventory icon of the
+ cotton shorts. Also added all added files to the makefile.
+
+2006-08-23 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_7-1.tmx.gz: Fixed a minor mapping bug reported on the
+ forum (no new walkmap required).
+ * data/maps/new_9-1.tmx.gz: Fixed two minor mapping bugs (new walkmap
+ required).
+
+2006-08-22 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac, data/graphics/images/ambient,
+ data/graphics/images/ambient/Makefile.am,
+ data/graphics/images/Makefile.am: Updated makefiles to account for new
+ ambient images and changed the version from 0.0.20.1 to 0.0.21.
+
+2006-08-21 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, tmw.cbp: Updated project files.
+
+2006-08-21 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/mapreader.cpp: Added logic for initialisation of the overlays.
+ * src/map.cpp, src/map.h: Code for updating and drawing the overlays.
+ * src/engine.cpp, src/engine.h: Added smooth scrolling and the call
+ to draw the overlays.
+ * data/maps/new_1-1.tmx.gz, data/graphics/new_7-1.tmx.gz,
+ data/graphics/images/ambient/sandstorm.png: Added sandstorm effect
+ to the desert maps outside of the city (feedback, please).
+ * data/maps/new_2-1.tmx.gz, data/maps/new_4-1.tmx.gz,
+ data/maps/new_5-1.tmx.gz, data/graphics/images/ambient/spotlight.png
+ Added spotlight effect to the cave maps (feedback, please)
+ * data/graphics/maps/new_9-1.tmx.gz,
+ data/graphics/images/ambient/clouds.png:
+ Added cloudshadow effect to the woodland map (feedback, please).
+
+2006-08-20 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac: Moved libpng check before SDL_image check, since the
+ latter requires the former.
+
+2006-08-20 Yohann Ferreira <bertram@cegetel.net>
+
+ * data/graphics/sprites/Makefile.am: Following the splitting from
+ Philipp, moved out the items.png file from the Makefile.am.
+ * debian/control, debian/tmw-data.install: Updated debian package
+ creation process.
+ * src/Makefile.am: Added iteminfo.cpp to avoid an undefined reference
+ with gcc 4.1.2. Happy to be back :)
+
+2006-08-17 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/items/*: Splitted the items.png into separate images
+ with more distinctive names. (no, i won't list all 114)
+ * src/itemmanager.cpp, data/items.xml: Replaced indices on the item
+ spriteset with filenames. added names and descriptions for all missing
+ items. Changed names and descriptions of some items.
+ * src/engine.cpp: Removed global item spriteset.
+ * src/floor_item.cpp, src/floor_item.h, src/iteminfo.cpp,
+ src/iteminfo.h, src/equipmentwindow.cpp, src/equipmentwindow.h,
+ src/itemcontainer.cpp, src/itemcontainer.h: The iteminfo class now
+ provides a pointer to the item icon image instead of providing the
+ index on the item spriteset.
+ * data/graphics/tiles/trans_desert-woodland.png: Added transmission
+ tileset between desert and woodland.
+
+2006-08-13 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/monster18.png,
+ data/graphics/sprites/monster18.xml,
+ data/graphics/sprites/npcs.png: Added new monster and npcs.
+ * src/gui.cpp, tmw.cbp, The Mana World.dev: Fixed Guichan 0.5.0
+ compilation issues.
+
+2006-08-13 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/openglgraphics.cpp, src/game.cpp, src/main.cpp,
+ src/gui/buddywindow.cpp, src/gui/connection.cpp, src/gui/sell.cpp,
+ src/gui/trade.cpp, src/gui/char_server.cpp, src/gui/window.cpp,
+ src/gui/login.cpp, src/gui/skill.h, src/gui/gui.cpp,
+ src/gui/item_amount.h, src/gui/setup_audio.h, src/gui/newskill.cpp,
+ src/gui/register.h, src/gui/setup.cpp, src/gui/npclistdialog.h,
+ src/gui/updatewindow.cpp, src/gui/char_select.cpp, src/gui/login.h,
+ src/gui/item_amount.cpp, src/gui/setup_audio.cpp,
+ src/gui/npc_text.cpp, src/gui/chat.h, src/gui/setup_joystick.h,
+ src/gui/setup_video.cpp, src/gui/ok_dialog.cpp, src/gui/textfield.cpp,
+ src/gui/inventorywindow.h, src/gui/newskill.h, src/gui/box.h,
+ src/gui/ministatus.cpp, src/gui/buy.h, src/gui/setup.h,
+ src/gui/confirm_dialog.cpp, src/gui/debugwindow.cpp, src/gui/vbox.cpp,
+ src/gui/chat.cpp, src/gui/setup_joystick.cpp, src/gui/updatewindow.h,
+ src/gui/char_select.h, src/gui/buysell.h, src/gui/tabbedcontainer.cpp,
+ src/gui/inventorywindow.cpp, src/gui/help.cpp, src/gui/status.h,
+ src/gui/npc_text.h, src/gui/setup_video.h, src/gui/menuwindow.cpp,
+ src/gui/ok_dialog.h, src/gui/buy.cpp, src/gui/buddywindow.h,
+ src/gui/sell.h, src/gui/trade.h, src/gui/char_server.h,
+ src/gui/skill.cpp, src/gui/buysell.cpp, src/gui/confirm_dialog.h,
+ src/gui/debugwindow.h, src/gui/status.cpp, src/gui/register.cpp,
+ src/gui/scrollarea.cpp, src/gui/tabbedcontainer.h,
+ src/gui/npclistdialog.cpp, src/gui/help.h, src/net/tradehandler.cpp,
+ src/net/playerhandler.cpp, src/Makefile.am,
+ src/resources/sdlimageloader.cpp, src/resources/sdlimageloader.h,
+ src/resources/openglsdlimageloader.cpp,
+ src/resources/resourcemanager.cpp,
+ src/resources/openglsdlimageloader.h, src/resources/resourcemanager.h:
+ Updated TMW to be compatible with Guichan 0.5.0 (merged from
+ guichan-0.5.0 branch).
+ * INSTALL, docs/INSTALL/win32.txt: Updated required Guichan to version
+ 0.5.0.
+ * configure.ac: Moved some basic checks above the checks on the
+ libraries we depend on, in order to get rid of the confusing
+ rpl_realloc error.
+ * src/resources/openglsdlimageloader.cpp, src/player.cpp: Fixed
+ several compiler warnings and a linker error when compiling without
+ OpenGL support.
+
+2006-08-12 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_9-1.tmx.gz, data/maps/new_14-1.tmx.gz,
+ data/maps/new_15-1.tmx.gz, data/maps/new_16-1.tmx.gz: Fixed some
+ inaccessible areas.
+
+2006-08-07 Philipp Sehmisch <tmw@crushnet.org>
+ * data/maps/new_9-1.tmx.gz, data/maps/new_14-1.tmx.gz,
+ data/maps/new_15-1.tmx.gz, data/maps/new_16-1.tmx.gz,
+ data/graphics/images/minimap_new_9-1.png,
+ data/graphics/images/minimap_new_14-1.png,
+ data/graphics/images/minimap_new_15-1.png,
+ data/graphics/images/minimap_new_16-1.png: Added minimaps for woodland
+ maps.
+
+2006-08-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_1-1.tmx.gz, data/maps/new_14-1.tmx.gz,
+ data/maps/new_15-1.tmx.gz, data/maps/new_16-1.tmx.gz:
+ Added a new woodland map and a connection map between desert and
+ woodland.
+ * data/graphics/woodland_ground.png: Added some new rocks.
+
+2006-08-07 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/gui/chat.h, src/gui/chat.cpp, src/main.cpp: A
+ bunch of cleanups.
+
+2006-08-05 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/configuration.cpp, src/game.cpp, src/engine.cpp, src/player.cpp,
+ src/being.cpp, src/resources/mapreader.cpp,
+ src/resources/itemmanager.cpp: Some cleanups, mostly lowering
+ indentation.
+ * src/being.cpp: Small code cleanup.
+
+2006-08-04 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/animatedsprite.cpp: Fix enum being treated as string.
+ * src/animation.cpp: Small code cleanups. Removed unused headers.
+ * src/animatedsprite.cpp: Small code cleanup/lower indentation.
+
+2006-08-04 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/animatedsprite.cpp: Fixed presence of NULL actions. This is
+ doener's version of the fix, because it was more efficient in the more
+ common case.
+
+2006-08-04 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * data/graphics/tiles/desert_x3.png: Replaced the old cactus with
+ a nice new high-res one.
+
+2006-08-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/player.cpp, src/being.cpp, src/being.h: Removed three
+ setDirection(mDirection) calls by instead specifically setting the
+ current direction on the newly added animated sprite. The same might
+ be done for the action later.
+ * src/animatedsprite.h, src/animatedsprite.cpp: Since this class isn't
+ subclassed and has no virtual functions, make protected members
+ private. Also added a start of a reset function which could be a
+ solution to unsynchronized animated sprites.
+ * src/net/network.cpp: Fixed two delete/delete[] errors.
+
+2006-08-01 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/animation.h, src/animation.cpp, src/animatedsprite.h,
+ src/animatedsprite.cpp, src/being.cpp: Animations and directions
+ are now passed and stored as enums and no longer as strings.
+
+2006-07-30 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/animatedsprite.h, src/animatedsprite.cpp: Unified the play
+ methods.
+
+2006-07-30 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_5-1.tmx.gz: Fixed two minor mapping errors (no new
+ walkmap required).
+
+2006-07-29 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/animatedsprite.h, src/animatedsprite.cpp, src/animation.cpp: A
+ bunch of cleanups.
+ * src/animation.h, src/animatedsprite.cpp: Moved included from header
+ to source file.
+
+2006-07-28 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/npc.cpp, src/player.cpp, src/animatedsprite.h, src/animation.h,
+ src/being.cpp, src/main.cpp, src/monster.cpp, src/animatedsprite.cpp,
+ src/animation.cpp, src/Makefile.am, src/being.h: Moved AnimatedSprite
+ into its own files, removed useless includes.
+ * src/engine.cpp: Removed an unused var.
+
+2006-07-26 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/Makefile.am, data/graphics/tiles/Makefile.am,
+ data/maps/Makefile.am, data/maps/new_13-1.tmx.gz: Added map with
+ inside of snow village buildings and fixed makefiles.
+ * src/being.cpp, src/being.h, src/player.cpp: Fixed direction and
+ action issues when changing appeareance, frames are still out of sync.
+ * data/maps/Makefile.am, data/maps/new_14-1.tmx.gz,
+ data/maps/new_9-1.tmx.gz: Added new woodland map by Crush and fixed
+ connection with the old one.
+
+2006-07-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/maps/new_4-1.tmx.gz: Fixes to the collision layer.
+
+2006-07-26 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * data/graphics/tiles/snowset.png, data/graphics/tiles/snow_x2.png,
+ data/graphics/tiles/snow_x3.png: Moved the lamppost, the rock and the
+ bench to seperate tall tilebitmaps.
+ * data/maps/new_11-1.tmx.gz: Improved the snow village map, main
+ changes are that the player can now walk better behind houses,
+ lampposts, rocks and benches.
+ * data/graphics/sprites/item003.png, data/graphics/sprites/item003.xml:
+ Added the leather shirt
+
+2006-07-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/log.cpp, src/log.h: Added support for writing log to standard
+ output.
+ * src/gui/updatewindow.cpp: Fixed updating on Windows.
+
+2006-07-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp: Fixed the loading of updates and made skipping the
+ update process also skip the loading of updates.
+
+2006-07-24 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/localplayer.cpp, src/being.cpp: Fixed setDirection() semantics.
+ Removed a printf-leftover.
+
+2006-07-24 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * data/graphics/sprites/npcs.png: Added the organdealer to the NPCs.
+ * data/graphics/sprites/player_male_base.png,
+ data/graphics/sprites/player_female_base.png: Fixed some transparency
+ issues.
+
+2006-07-24 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/being.cpp, src/being.h, src/localplayer, The Mana World.dev,
+ tmw.cbp: Removed unused code, fixed "change direction when not
+ walking" bug, updated project files.
+ * data/graphics/sprites/monster1.xml: Slowed down scorpions.
+ * data/graphics/sprites/monster2.xml: Red scorpions have got the same
+ problem.
+ * data/graphics/sprites/player_female_base.xml: Fixed female playerset
+ animation definition.
+ * data/help/about.txt, data/help/changes.txt, data/help/commands.txt,
+ data/help/header.txt, data/help/index.txt, data/help/skills.txt,
+ data/help/support.txt, data/help/team.txt: Forced to use UNIX end of
+ line character.
+ * src/net/equipmenthandler.cpp: Equipments now use real slot
+ positions.
+
+2006-07-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/floor_item.cpp, src/animation.h, src/being.cpp, src/main.cpp,
+ src/gui/equipmentwindow.cpp, src/gui/playerbox.cpp,
+ src/gui/itemcontainer.cpp, src/engine.cpp, src/tileset.h,
+ src/animation.cpp, src/Makefile.am, src/resources/mapreader.cpp,
+ src/resources/resourcemanager.cpp, src/resources/spriteset.cpp,
+ src/resources/resourcemanager.h, src/resources/spriteset.h,
+ src/being.h, src/graphic/spriteset.cpp, src/graphic/spriteset.h,
+ data/graphics/sprites/npc.xml, data/graphics/sprites/weapons.xml:
+ Implemented caching of spritesets, including a lot of cleanups to the
+ new animation system. Action now refers to the Spriteset directly and
+ AnimatedSprite refers to the current Action directly instead of using
+ the std::map with a std::string constantly. Some methods and
+ parameters are marked as const. The READ_PROP macro was replaced by
+ static methods. Warnings are logged when unnamed actions are defined
+ or when actions refer to undefined imagesets. Code is more tolerant
+ towards missing actions.
+ * NEWS: Rearranged some items.
+
+2006-07-21 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/animation.cpp, src/animation.h: Removed unused code, fixed a
+ numeric conversion, used a more meaningful speed.
+
+2006-07-20 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/help/header.txt, data/help/skills.txt, docs/FAQ.txt, README:
+ Updated some docs for the 0.0.20 release.
+ * NEWS: Added new features of 0.0.20.
+ * data/items.xml: Added shorts.
+ * src/tmw.rc, The Mana World.dev, tmw.cbp: Added a resource script to
+ let both Dev-Cpp and Code::Blocks share the same binary icon and
+ version infos.
+ * data/graphics/sprites/player_female_base.xml,
+ data/graphics/sprites/player_male_base.xml, src/animation.cpp,
+ src/animation.h, src/being.cpp: Fixed left bow attack animation,
+ made the attack animation stay in sync with attack speed.
+
+2006-07-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/minimap.cpp: Fixed dot size of local player.
+ * src/engine.cpp: Fixed color of "[TARGET]".
+ * src/resources/mapreader.cpp, src/resources/mapreader.h,
+ data/maps/new_12-1.tmx.gz, data/maps/new_3-1.tmx.gz,
+ data/maps/new_4-1.tmx.gz, data/maps/new_5-1.tmx.gz,
+ data/maps/new_6-1.tmx.gz, data/maps/new_7-1.tmx.gz,
+ data/maps/new_8-1.tmx.gz, data/maps/new_9-1.tmx.gz,
+ data/maps/new_1-1.tmx.gz, data/maps/new_10-1.tmx.gz,
+ data/maps/new_11-1.tmx.gz, data/maps/new_2-1.tmx.gz: Implemented
+ loading for the way Tiled saves properties since version 0.6.0 and
+ updated all current maps.
+
+2006-07-19 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/item001.png, data/graphics/sprites/item001.xml,
+ data/graphics/sprites/item002.png, data/graphics/sprites/item002.xml,
+ data/graphics/sprites/item1202.png, data/graphics/sprites/Makefile.am,
+ docs/INSTALL/win32.txt, src/animation.cpp, src/being.cpp, src/being.h,
+ src/gui/equipmentwindow.cpp, src/gui/newskill.cpp, src/main.cpp,
+ src/net/beinghandler.cpp, src/net/charserverhandler.cpp,
+ src/player.cpp, src/player.h: Merged trunk changes r2381:2397 into
+ new_animation branch.
+ * tmw.cbp: Updated Code::Blocks project file.
+ * src/gui/char_select.cpp: Fixed next/previous buttons behaviour in
+ character selection dialog.
+ * data/graphics/sprites/Makefile.am: Alphabetically correct.
+
+2006-07-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * tmw.cbp: Added Code::Blocks project file.
+
+2006-07-18 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/updatewindow.cpp, src/gui/updatewindow.h, src/main.cpp,
+ src/resources/resourcemanager.cpp, src/resources/resourcemanager.h:
+ Updated the updating system. It will now only load those updates
+ specified in the downloaded resources.txt file, and in the order
+ in which they are mentioned (the top one being the most
+ significant).
+
+2006-07-17 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * data/graphics/sprites/items.png: Added shorts' icon to items.png
+
+2006-07-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/newskill.cpp: Fixed up a string comparison that caused a
+ warning with GCC 4.2.
+
+2006-07-12 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * data/graphics/sprites/item001.png: Completed the cotton shirt
+ equipment graphic.
+
+2006-07-06 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/animation.cpp, src/animation.h, src/being.cpp, src/being.h,
+ src/monster.cpp, src/npc.cpp, src/player.cpp:
+ Fixed some minor bugs, cleaned up general code style and added more
+ comments.
+
+2006-07-05 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/monster.cpp, src/npc.cpp, src/player.cpp: Fixed broken paths.
+ * data/graphics/sprites/Makefile.am: Added new files.
+ * src/animation.cpp: Added missing return value...
+ * src/Makefile.am: Added new files.
+
+2006-07-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/sprites/monster0.xml: Fixed frame size of maggot.
+ * src/being.h: drawName should be virtual, lest we want names to be
+ drawn.
+
+2006-07-03 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/spriteset.cpp, src/spriteset.h: Spriteset::get() doesn't crash
+ anymore when requesting a sprite outside of the spriteset. (it returns
+ NULL instead and logs a warning).
+
+2006-07-03 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/being.cpp: Fixed a compiler issue reported by Pajarico.
+
+2006-07-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * tools/Reorganize.java: Added tool used for reorganizing and
+ auto-cropping the monster spritesets.
+
+2006-07-03 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/main.cpp, src/engine.cpp: Removed some no longer required old
+ style spritesets.
+ * src/being.h, src/being.cpp: Removed some no longer needed member
+ variables.
+ * src/monster.cpp: Monsters are now drawed with the new animation
+ system.
+ * src/npc.cpp, data/graphics/sprites/npcs.xml: NPCs are now drawed
+ with the new animation system.
+ * src/being.h, src/being.cpp, src/npc.cpp, src/npc.h, src/monster.cpp,
+ src/monster.h: Moved all drawing code from the Being based classes
+ into Being.
+ * data/graphics/sprites/monster*.png: Resized and reorganized the
+ monster spritesets to fit the new animation system (thanks, Bjørn).
+ * data/graphics/sprites/monster*.xml: Added animation files for all
+ monsters.
+ * src/animation.cpp: The offset values of the Frames of animated
+ sprites are now modified so every frame is drawn centered.
+ * data/graphics/sprites/hairstyle*.xml: Retuned the offsets of the
+ hair sprites.
+ * src/animation.cpp: Small stability fix.
+ * src/being.cpp, src/being.h: weapon animation now uses the new
+ animation system.
+ * data/graphics/sprites/player_male_base.xml
+ data/graphics/sprites/player_female_base.xml
+ data/graphics/sprites/hairstyle*.xml: Tuned walk speed and added bow
+ animations.
+
+2006-07-03 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/being.cpp: Removed an unnecessary parameter.
+
+2006-07-03 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/sprites/Makefile.am: Updated to new xml files.
+
+2006-07-02 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/localplayer.cpp: Fixed the "walking against walls" bug.
+ * src/animation.cpp src/animation.h: fixed the "sliding" bug and
+ removed some unused variables.
+
+2006-07-01 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/being.cpp, src/being.h, src/player.cpp, src/player.h,
+ src/localplayer.cpp: Sprites are now stored in a vector instead of a
+ list, so they can be replaced a lot easier; added female playerset;
+ added hairstyles and colors.
+ * src/animation.cpp, src/animation.h: added support for variations,
+ variations are animations stored in the same spriteset with the same
+ layout and sequence but starting at another index.
+ * data/graphics/sprites/player_female_base.xml: Added xml file for
+ female characters.
+ * data/graphics/sprites/hairstyle0.xml,
+ data/graphics/sprites/hairstyle1.xml,
+ data/graphics/sprites/hairstyle2.xml,
+ data/graphics/sprites/hairstyle3.xml,
+ data/graphics/sprites/hairstyle4.xml,
+ data/graphics/sprites/hairstyle5.xml,
+ data/graphics/sprites/hairstyle6.xml,
+ data/graphics/sprites/hairstyle7.xml: Added xml files for all
+ hairstyles (these xml files are using the new variation feature).
+ * src/being.cpp, src/being.h, src/localplayer.cpp, src/player.cpp: The
+ beings now haven't got one, but a list of animated sprites (named
+ mSprites). At the moment it contains the hair and the base sprite.
+ * src/animation.cpp, src/animation,h: Fixed a crash when substituting
+ an undefined direction; renamed completeDirections method to
+ substituteAction.
+ * data/graphics/sprites/hairstyle0.xml: Made a xml file for the hair
+ animation.
+
+2006-06-29 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/items.xml, src/being.cpp, src/being.h src/net/beinghandler.cpp,
+ src/player.cpp: Clients get notified of equipping visible items.
+ * src/net/beinghandler.cpp: GCC 4 fix.
+
+2006-06-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/animation.cpp, src/animation.h: Parser now works like described
+ on the wiki; the single animation phases are now stored in structures;
+ drawing call for animatiedSprites moved into the animatiedSprite
+ class.
+ * src/being.cpp, src/being.h, src/localplayer.cpp, src/player.cpp:
+ Renamed mAnimatedSprite to mBaseSprite to distinct it from hair-equip
+ and other sprites that will also be part of the class.
+ * src/player.cpp: Drawing call for animatiedSprites moved into the
+ animatiedSprite class; time now correctly passed in ms to the
+ animatedSprite class.
+ * src/graphic/spriteset.cpp, src/graphic/spriteset.h: Width and height
+ of the subimages is now saved in the spritesheet class.
+ * src/graphics.cpp: Added an additional check to avoid crashes when
+ passing a NULL pointer as image argument.
+ * data/graphics/sprites/player_male_base.xml: Animation file now has
+ the syntax described on the wiki.
+
+2006-06-27 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/player_male_base.xml, src/being.cpp,
+ src/being.h, src/engine.cpp, src/localplayer.cpp, src/main.cpp,
+ src/net/beinghandler.cpp, src/net/playerhandler.cpp,
+ src/resources/itemmanager.cpp, The Mana World.dev: Added a beginning
+ of a new animation system to slow down player walking.
+ * src/animation.cpp, src/animation.h: Forgot 2 files.
+ * src/being.cpp, src/gui/equipmentwindow.cpp, src/player.cpp:
+ Equipment window now show all the slots, and adapted visible shirts to
+ head (middle) equipments.
+
+2006-06-27 Frode Lindeijer <f.lindeijer@gmail.com>
+
+ * /tmw/trunk/data/graphics/sprites/player_male_base.png:
+ Fixed transparency issue with the north punching frames
+
+2006-06-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/net/messagein.cpp: Fixed the readString method (synchronized
+ with the server version by Guillaume Melquiond).
+
+2006-06-21 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/monster11.png,
+ data/graphics/sprites/monster17.png: Fixed attack animation of monster
+ 11 and added a new monster.
+ * data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/player_female_base.png, src/being.cpp,
+ src/being.h, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/playerbox.cpp, src/gui/playerbox.h, src/gui/register.cpp,
+ src/main.cpp, src/net/beinghandler.cpp, src/net/charserverhandler.cpp,
+ src/player.cpp: Added female players.
+
+2006-06-19 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/sprites/monster16.png: added the little pink monster
+
+2006-05-22 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/tiles/icecave.png, data/graphics/tiles/Makefile.am,
+ data/maps/Makefile.am, data/maps/new_10-1.tmx.gz,
+ data/maps/new_11-1.tmx.gz, data/maps/new_4-1.tmx.gz,
+ data/maps/new_5-1.tmx.gz, src/resources/itemmanager.cpp: A bunch of
+ updates to the world and disabled art and type xml parser checks since
+ they're not used.
+
+2006-05-21 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Updated dev-cpp project file.
+
+2006-05-17 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/npcs.png, data/graphics/tiles/Makefile.am,
+ data/graphics/snow_building.png, data/graphics/tiles/snowset.png,
+ data/maps/Makefile.am, data/maps/new_11-1.tmx.gz: New NPCs, new snow
+ tiles and village.
+
+2006-05-15 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/item_amount.cpp: Set slider range to the real values instead
+ of mapping the amount between [0,1] and [1,max] all the time.
+
+2006-05-13 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/openglgraphics.cpp: Set color back to current color instead of
+ setting it to white. Fixes white rectangles in equipment window.
+ * src/being.cpp, src/being.h, src/player.cpp: Specify the color in
+ which speech and names are supposed to be drawn. Removed unused
+ mSpeechColor member.
+
+2006-05-12 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.cpp: Fixed initialization order in Being ctor.
+
+2006-05-12 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/item1202.png,
+ data/graphics/sprites/Makefile.am, src/being.cpp, src/being.h,
+ src/localplayer.cpp, src/localplayer.h, src/main.cpp, src/player.cpp,
+ The Mana World: You can now see the shirt when equipping a top
+ equipment.
+
+2006-05-05 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/setup_video.cpp: Fixed some numeric conversions.
+
+2006-05-03 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * configure.ac, src/game.cpp, src/graphics.cpp, src/main.cpp,
+ src/openglgraphics.cpp, The Mana World: Increased fps limit
+ granularity and cleaned some code, fixed some xml library name in
+ Dev-C++ project file, switched version to 0.0.20.
+ * src/game.cpp, src/gui/setup.cpp, src/gui/setup_video.cpp,
+ src/gui/setup_video.h, src/main.cpp: FPS limit can now be set in setup
+ dialog. Default value for FPS is 50. (Code based on peoro's patch).
+
+2006-05-02 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/localplayer.cpp: Fixed the delay last move bug.
+
+2006-04-29 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/tiles/cave.png: Added tiles by yosuhara.
+
+2006-04-28 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/Woodland_ground.png: Graphical update of the
+ woodland tileset. Paths improved, and tiles that were redunant
+ replaced by new dirt tiles.
+ * data/maps/new_9.1.tmx.gz: Modified because of changes in the tileset
+ layout (no new server sided walkmap required).
+ * data/graphics/sprites/monster11.png: Improved the shading of the
+ mushroom monster.
+ * data/graphics/sprites/monster15.png: Added dropshadow to the bat
+ monster (note that the version 0.0.19 live update overrides the
+ changed file).
+
+2006-04-04 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * ChangeLog: Converted to UTF-8.
+ * NEWS: Spelling correction.
+ * docs/INSTALL/debian.txt, docs/INSTALL/win32.txt: Updated with
+ respect to the move from CVS to Subversion.
+
+2006-03-25 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/window.cpp: Added window resize patch by peoro.
+
+2006-03-21 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Updated project.
+
+2006-03-20 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp: Fixed a crash on map change.
+
+2006-03-20 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/char_select.cpp: Fixed an include.
+
+2006-03-19 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/register.h, src/gui/register.cpp: Fixed a memory leak and
+ removed some whitespace noise.
+ * src/lockedarray.h, src/game.cpp, src/gui/gui.cpp,
+ src/gui/browserbox.cpp, src/gui/register.cpp,
+ src/resources/resourcemanager.cpp: Removed some useless null pointer
+ checks.
+ * src/gui/login.cpp, src/gui/setup_audio.h, src/gui/setup.cpp,
+ src/gui/setup_audio.cpp, src/gui/setup_video.cpp,
+ src/gui/setup_video.h: Removed some duplicated initializations.
+ * src/gui/setup_audio.h, src/gui/setup.cpp, src/gui/setup_audio.cpp,
+ src/gui/setup_joystick.h, src/gui/setup_video.cpp, src/gui/setuptab.h,
+ src/gui/setup.h, src/gui/setup_joystick.cpp, src/gui/setup_video.h,
+ src/Makefile.am: Splitted setup window into manageable pieces
+ according to their tabs in the window. Fixed some memory leaks along
+ the way. Also fixed two settings not being stored on "apply".
+
+2006-03-18 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/chat.cpp, src/gui/menuwindow.cpp, src/gui/skill.cpp,
+ src/gui/status.cpp: Use the window container instead of the graphics
+ class to calculate window positions.
+ * src/utils/dtor.h: Fixed indentation.
+ * src/configuration.cpp, src/log.cpp, src/main.cpp, src/being.cpp,
+ src/monster.cpp, src/gui/equipmentwindow.cpp, src/gui/sell.cpp,
+ src/gui/trade.cpp, src/gui/char_server.cpp, src/gui/setup.cpp,
+ src/gui/updatewindow.cpp, src/gui/char_select.cpp,
+ src/gui/ministatus.cpp, src/gui/debugwindow.cpp,
+ src/gui/tabbedcontainer.cpp, src/gui/inventorywindow.cpp,
+ src/gui/buy.cpp, src/gui/itemcontainer.cpp, src/gui/inttextbox.cpp,
+ src/gui/debugwindow.h, src/gui/status.cpp, src/gui/register.cpp,
+ src/net/chathandler.cpp, src/engine.cpp, src/utils/tostring.h,
+ src/Makefile.am: Added a toString conversion function.
+
+2006-03-15 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.h, src/main.cpp, src/gui/equipmentwindow.cpp,
+ src/gui/window.cpp, src/gui/login.cpp, src/gui/listbox.h,
+ src/gui/chat.h, src/gui/ministatus.cpp, src/gui/chat.cpp,
+ src/gui/help.cpp, src/gui/itemcontainer.cpp, src/gui/listbox.cpp,
+ src/gui/checkbox.cpp, src/engine.cpp, src/resources/image.cpp: A bunch
+ of cosmetic changes.
+ * src/net/network.cpp: Fixed connection not being shut down completely
+ in case of an error.
+
+2006-03-13 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/main.cpp: Fixed skip update option.
+
+2006-03-13 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_7.1.tmx.gz: Fixed some map bugs (update of server
+ sided walkmap required!)
+
+2006-03-11 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/hairstyle1.png,
+ data/graphics/sprites/hairstyle2.png,
+ data/graphics/sprites/hairstyle3.png,
+ data/graphics/sprites/hairstyle4.png,
+ data/graphics/sprites/hairstyle6.png,
+ data/graphics/sprites/hairstyle7.png,
+ data/graphics/sprites/Makefile.am: Fixed some hair positions, added a
+ new style, updated makefile.
+
+2006-03-09 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/utils/dtor.h: Added guards.
+ * src/game.cpp, src/main.cpp, src/gui/connection.cpp,
+ src/gui/menuwindow.cpp, src/net/tradehandler.cpp,
+ src/net/playerhandler.cpp: Made all local action listeners structs and
+ moved them into anonymous namespaces.
+ * src/gui/connection.cpp, src/gui/newskill.cpp,
+ src/gui/chargedialog.cpp, src/gui/updatewindow.cpp,
+ src/gui/progressbar.h, src/gui/ministatus.cpp,
+ src/gui/progressbar.cpp, src/gui/status.cpp: Removed coordinate
+ arguments from ProgressBar ctor.
+ * src/openglgraphics.cpp, src/localplayer.cpp, src/game.cpp,
+ src/map.cpp, src/log.cpp, src/being.cpp, src/monster.cpp, src/sound.h,
+ src/graphics.cpp, src/gui/equipmentwindow.cpp, src/gui/sell.cpp,
+ src/gui/trade.cpp, src/gui/char_server.cpp, src/gui/window.cpp,
+ src/gui/login.cpp, src/gui/inttextbox.h, src/gui/chargedialog.h,
+ src/gui/focushandler.h, src/gui/skill.h, src/gui/gui.cpp,
+ src/gui/newskill.cpp, src/gui/register.h, src/gui/popupmenu.h,
+ src/gui/setup.cpp, src/gui/npclistdialog.h, src/gui/chargedialog.cpp,
+ src/gui/playerbox.h, src/gui/char_select.cpp, src/gui/login.h,
+ src/gui/focushandler.cpp, src/gui/chat.h, src/gui/inventorywindow.h,
+ src/gui/newskill.h, src/gui/ministatus.cpp, src/gui/buy.h,
+ src/gui/playerbox.cpp, src/gui/setup.h, src/gui/itemcontainer.h,
+ src/gui/debugwindow.cpp, src/gui/chat.cpp, src/gui/char_select.h,
+ src/gui/inventorywindow.cpp, src/gui/help.cpp, src/gui/status.h,
+ src/gui/buy.cpp, src/gui/itemcontainer.cpp, src/gui/equipmentwindow.h,
+ src/gui/sell.h, src/gui/trade.h, src/gui/ministatus.h,
+ src/gui/inttextbox.cpp, src/gui/char_server.h, src/gui/window.h,
+ src/gui/skill.cpp, src/gui/debugwindow.h, src/gui/status.cpp,
+ src/gui/register.cpp, src/gui/popupmenu.cpp, src/gui/minimap.cpp,
+ src/gui/npclistdialog.cpp, src/gui/help.h, src/net/buysellhandler.cpp,
+ src/net/beinghandler.cpp, src/net/charserverhandler.cpp,
+ src/net/maploginhandler.cpp, src/net/playerhandler.cpp,
+ src/engine.cpp, src/localplayer.h, src/beingmanager.cpp, src/map.h,
+ src/log.h, src/sound.cpp, src/resources/itemmanager.h,
+ src/resources/buddylist.cpp, src/resources/buddylist.h,
+ src/resources/image.cpp, src/resources/image.h,
+ src/resources/itemmanager.cpp, src/being.h, src/player.cpp: Made all
+ class members named like mClassMember.
+ * src/floor_item.cpp, src/map.cpp, src/being.cpp,
+ src/gui/equipmentwindow.cpp, src/gui/playerbox.cpp,
+ src/gui/itemcontainer.cpp, src/graphic/spriteset.cpp,
+ src/graphic/spriteset.h, src/player.cpp: Added Spriteset::get() and
+ Spriteset::size() to hide the member vector and remove the weird
+ mySpriteset->spriteset stuff.
+ * src/gui/buddywindow.cpp, src/gui/connection.cpp, src/gui/sell.cpp,
+ src/gui/trade.cpp, src/gui/char_server.cpp, src/gui/login.cpp,
+ src/gui/button.h, src/gui/newskill.cpp, src/gui/setup.cpp,
+ src/gui/updatewindow.cpp, src/gui/button.cpp, src/gui/char_select.cpp
+ ,src/gui/item_amount.cpp, src/gui/npc_text.cpp, src/gui/ok_dialog.cpp,
+ src/gui/confirm_dialog.cpp, src/gui/debugwindow.cpp,
+ src/gui/tabbedcontainer.cpp, src/gui/inventorywindow.cpp,
+ src/gui/help.cpp, src/gui/menuwindow.cpp, src/gui/buy.cpp,
+ src/gui/skill.cpp, src/gui/buysell.cpp, src/gui/status.cpp,
+ src/gui/register.cpp, src/gui/npclistdialog.cpp: Made the Button ctor
+ accept eventId and action listener.
+ * src/localplayer.cpp, src/game.cpp, src/gui/trade.cpp,
+ src/gui/inventorywindow.cpp, src/gui/trade.h, src/localplayer.h,
+ src/game.h: Use std::auto_ptr in some places.
+ * src/lockedarray.h: Use fill_n instead of for-loop.
+ * src/gui/browserbox.cpp: Make the MouseOverLink functor dynamic and
+ use a STL algorithm in one more place.
+
+2006-03-08 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/browserbox.h, src/gui/menuwindow.cpp, src/gui/buysell.cpp:
+ Some fixes for compiling with pedantic compiler settings and const
+ char* checks.
+ * data/graphics/sprites/player_male_base.png: Use two rows for each
+ direction in order to make the texture less wide so that it stays
+ within the 1024 texture limit for OpenGL mode.
+
+2006-03-08 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/map.cpp, src/main.cpp, src/gui/button.cpp,
+ src/gui/textfield.cpp, src/gui/playerbox.cpp,
+ src/gui/windowcontainer.cpp, src/gui/skill.cpp,
+ src/gui/scrollarea.cpp, src/engine.cpp, src/beingmanager.cpp,
+ src/utils, src/utils/dtor.h, src/Makefile.am,
+ src/flooritemmanager.cpp, src/graphic/spriteset.cpp: Added a 'dtor'
+ helper functor to delete objects in arrays and containers using STL
+ algorithms.
+ * src/resources/image.cpp: Removed some conditional code.
+ * src/localplayer.cpp, src/gui/gui.cpp: Reverted changes from r2225,
+ it broke walking code as I missed the differences between tile and
+ being collisions.
+ * src/gui/itemcontainer.cpp, src/inventory.cpp: Made Inventory use STL
+ algorithms and fixed getLastUsedSlot semantics.
+ * src/engine.cpp, src/engine.h: Moved a variable definition into the
+ right place and made getCurrentMap inline.
+ * src/equipment.cpp, src/equipment.h: Use STL algorithms and make
+ destructor inline.
+ * src/localplayer.cpp, src/gui/gui.cpp: Let the LocalPlayer decide
+ whether it can walk to a destination.
+
+2006-03-07 Yohann Ferreira <bertram@cegetel.net>
+
+ * debian/rules, debian/changelog, ChangeLog: Updating Debian files for
+ 0.0.19 release.
+
+2006-03-07 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/tiles/Makefile.am, data/graphics/tiles/Woodland.png:
+ Removed unused tileset.
+
+2006-03-06 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * configure.ac: Version changed to 0.0.19.
+
+2006-03-06 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_9.1.tmx.gz: Fixed some mapping bugs.
+
+2006-03-06 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * AUTHORS, NEWS, README, data/help/changes.txt, data/help/header.txt,
+ data/help/team.txt: A bunch of updates to docs, ready for 0.0.19.
+ * data/help/changes.txt, src/main.cpp: Small fixes before releasing.
+
+2006-03-05 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * data/graphics/sprites/Makefile.am: Remove trailing whitespace.
+ * src/engine.cpp: Re-add main.h header, Windows build needs it.
+
+2006-03-05 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/player_male_base.png: Added pants.
+
+2006-03-02 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/weapon1.png: Added missing frames.
+ * src/player.cpp: Fixed north shooting hair position.
+ * data/graphics/sprites/Makefile.am: Added new graphics.
+ * data/graphics/sprites/monster15.png: Added bat monster.
+
+2006-03-01 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Enabled -Wall switch.
+ * data/graphics/sprites/monster9.png: Fixed fire goblin north walking
+ animation.
+ * data/graphics/sprites/hairstyle1.png,
+ data/graphics/sprites/hairstyle2.png,
+ data/graphics/sprites/hairstyle3.png,
+ data/graphics/sprites/hairstyle4.png,
+ data/graphics/sprites/hairstyle5.png,
+ data/graphics/sprites/hairstyle6.png,
+ data/graphics/sprites/player_male_base.png,
+ data/graphics/sprites/weapon0.png,
+ data/graphics/sprites/weapon1.png: New graphics for hair styles,
+ player and weapons.
+ * src/being.cpp, src/being.h, src/engine.cpp, src/gui/playerbox.cpp,
+ src/localplayer.cpp, src/main.cpp, beinghandler.cpp, player.cpp,
+ src/resources/image.cpp: Hacked code to support the new playerset.
+
+2006-02-25 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/beingmanager.cpp, src/beingmanager.h, src/engine.cpp,
+ src/main.h, src/sound.h: Added a logic method to the being manager.
+
+2006-02-24 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.cpp, src/being.h, src/configuration.cpp,
+ src/configuration.h, src/engine.cpp, src/map.cpp, src/map.h,
+ src/properties.h, src/gui/browserbox.cpp, src/gui/browserbox.h,
+ src/gui/chat.cpp, src/gui/chat.h, src/gui/gccontainer.cpp,
+ src/gui/gccontainer.h, src/gui/minimap.cpp,
+ src/gui/tabbedcontainer.cpp, src/gui/tabbedcontainer.h,
+ src/net/network.cpp, src/net/network.h, src/resources/itemmanager.cpp,
+ src/resources/itemmanager.h: Another bunch of cosmetic cleanups, i.e.
+ mostly typedefs...
+
+2006-02-23 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.cpp, src/being.h, src/beingmanager.cpp,
+ src/beingmanager.h, src/engine.cpp, src/inventory.cpp,
+ src/inventory.h, src/logindata.h, src/main.cpp, src/main.h,
+ src/openglgraphics.cpp, src/gui/equipmentwindow.h,
+ src/gui/minimap.cpp, src/gui/minimap.h, src/gui/windowcontainer.cpp,
+ src/gui/windowcontainer.h, src/net/loginhandler.cpp: A bunch of mostly
+ cosmetic cleanups.
+
+2006-02-23 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_4.1.tmx.gz: I remapped the hermits cave. It looks much
+ more natural now. A new server sided walkmap is required.
+
+2006-02-22 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/cave.png: fixed two almost invisible pixel
+ errors
+
+2006-02-21 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/maps/new_9.1.tmx.gz: fixed another map bug.
+
+2006-02-05 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/resources/itemmanager.cpp: Added warnings when parameters are
+ missing in the items xml file.
+
+2006-02-16 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/browserbox.cpp, src/gui/browserbox.h, src/gui/gui.cpp: Use
+ Widget::mFont instead of browerFont for drawing, fixes the "gui
+ needs to be valid real early" issue.
+
+2006-02-07 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.cpp, src/being.h, src/game.cpp, src/localplayer.cpp,
+ src/localplayer.h, src/monster.cpp, src/player.cpp,
+ src/net/messagein.cpp, src/net/protocol.cpp: Made the being directions
+ being stored in a bitfield.
+
+2006-02-06 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/Woodland_ground.png,
+ data/graphics/tiles/Woodland_x2.png, data/maps/new_9.1.tmx.gz: added
+ dynamic grass that covers the lower area of sprites (doesn't work for
+ flower beds yet).
+
+2006-02-06 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/net/tradehandler.cpp: Updated Dev-Cpp project
+ file, fixed a gcc 3.4 issue.
+ * src/net/tradehandler.cpp: Undone last changes because Bertram
+ already fixed the compiler issue.
+
+2006-02-06 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/game.cpp, src/joystick.cpp, src/joystick.h,
+ src/gui/setup.cpp, src/gui/setup.h: Added a Joystick class.
+ * src/being.cpp, src/being.h, src/monster.cpp, src/npc.cpp: Unify some
+ of the drawing code for beings.
+ * src/being.cpp, src/being.h, src/localplayer.h, src/player.cpp,
+ src/player.h: Use virtual methods instead of getType() checks.
+ * data/graphics/gui/browserfont.png,
+ data/graphics/gui/fixedfont.png, data/graphics/gui/rpgfont_wider.png,
+ data/graphics/gui/sansserif8.png, src/Makefile.am, src/engine.cpp,
+ src/floor_item.cpp, src/floor_item.h, src/flooritemmanager.cpp,
+ src/flooritemmanager.h, src/game.cpp, src/gui/gui.cpp,
+ src/net/itemhandler.cpp: Introduced a FloorItemManager class.
+
+2006-02-05 Yohann Ferreira <bertram@cegetel.net>
+
+ * data/graphics/gui/rpgfont_wider.png,
+ data/graphics/gui/fixedfont.png,data/graphics/gui/browserfont.png,
+ data/graphics/gui/sansserif8.png: Adding è accents mostly to the font
+ images.
+ * src/engine.cpp, src/being.h, src/being.cpp, src/player.cpp,
+ src/gui/char_select.h, src/gui/char_select.cpp: Made the nickname and
+ emotions displayed above every layers. Made the delete and ok buttons
+ be disabled once the character is selected at login.
+ * src/net/tradehandler.cpp, src/resources/itemmanager.cpp: Fixed a gcc
+ 4.0 issue in the tradehandler. Strengthen the xml parser in the
+ itemmanager so tmw doesn't crash anymore if an item lacks some
+ parameters.
+
+2006-02-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * INSTALL: Updated dependencies in response to patch by Hanno Braun.
+
+2006-02-05 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * data/graphics/tiles/Makefile.am: Added the new tilesets.
+ * src/localplayer.cpp, src/localplayer.h, src/gui/gui.cpp: Made the
+ player walk to items prior to picking them up.
+
+2006-02-04 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/Woodland.png: new path design
+ * data/graphics/tiles/Woodland_ground.png,
+ data/graphics/tiles/Woodland_x2.png,
+ data/graphics/tiles/Woodland_x3.png: splitted the tileset into three
+ tilesets with different tile sizes
+ (i kept the original tileset for backward compatiblity)
+ * data/maps/new_9.1.tmx.gz: remapped with the oversized tile
+ technology. made the forests less regular. made the unwalkable map
+ borders more visual appealing
+
+2006-02-04 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/localplayer.h, src/logindata.h, src/main.cpp, src/main.h,
+ src/gui/char_select.cpp, src/gui/char_server.cpp,
+ src/gui/char_server.h, src/net/charserverhandler.cpp,
+ src/net/charserverhandler.h, src/net/loginhandler.cpp,
+ src/net/loginhandler.h, src/net/network.cpp, src/net/network.h: Unify
+ the gui code for the various logins to use LoginData.
+
+2006-02-03 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/logindata.h, src/main.cpp, src/gui/login.cpp, src/gui/login.h:
+ Made the login dialog work on LoginData only, without playing with the
+ config, it's not its job to do so.
+ * src/net/protocol.cpp, src/net/protocol.h: Removed some unused code.
+
+2006-02-02 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/desert1.png, data/graphics/tiles/desert2.png,
+ data/graphics/tiles/desert_x2.png, data/graphics/tiles/desert_x3.png:
+ Replaced the old sand tile with Irucards new one. Added new crates.
+ Made some minor corrections.
+
+2006-02-01 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/game.h, src/main.cpp: Created a Game class.
+ * src/gui/passwordfield.cpp: Removed duplicated code.
+ * src/Makefile.am, src/main.cpp, src/gui/error.cpp, src/gui/error.h:
+ Replaced ErrorDialog by OkDialog + listener.
+ * src/Makefile.am, src/game.cpp, src/gui/buysell.cpp,
+ src/gui/char_select.cpp, src/gui/confirm_dialog.cpp,
+ src/gui/confirm_dialog.h, src/gui/login.cpp, src/gui/login.h,
+ src/gui/menuwindow.cpp, src/gui/ok_dialog.cpp, src/gui/ok_dialog.h,
+ src/gui/register.cpp, src/gui/requesttrade.cpp,
+ src/gui/requesttrade.h, src/gui/setup.cpp, src/net/playerhandler.cpp,
+ src/net/tradehandler.cpp: Made the OkDialog and ConfirmDialog classes
+ proxies for their buttons' events. Removed the RequestTradeWindow
+ class, replaced with a plain ConfirmDialog. Fixed a memory leak along
+ the way.
+
+ * src/gui/buysell.cpp, src/gui/menuwindow.cpp: Simplified button
+ creation code.
+ * src/gui/npc_text.cpp: Fixed a bug where the game crashes if there's a
+ message dialog from a npc that no longer exists.
+ * src/properties.h: Reverted properties to private.
+
+2006-01-31 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/setup.cpp: Cleanup.
+ * src/gui/requesttrade.cpp, src/gui/requesttrade.h: Made
+ RequestTradeDialog inherit from ConfirmDialog.
+ * src/Makefile.am, src/gui/buy.cpp, src/gui/buy.h, src/gui/sell.cpp,
+ src/gui/sell.h, src/gui/shop.cpp, src/gui/shop.h: Created a ListModel
+ for ShopItems.
+ * src/floor_item.cpp, src/graphics.h, src/map.cpp, src/map.h,
+ src/properties.h, src/sprite.h, src/gui/login.cpp,
+ src/gui/scrollarea.cpp, src/gui/windowcontainer.cpp,
+ src/resources/sdlimageloader.cpp: Various small cleanups.
+ * src/resources/resource.cpp, src/resources/resourcemanager.cpp,
+ src/resources/resource.h, src/resources/resourcemanager.h: Made
+ ResourceManager a friend of Resource to avoid looping over decRef,
+ which returns void now.
+
+2006-01-30 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/char_select.cpp, src/gui/confirm_dialog.cpp,
+ src/gui/confirm_dialog.h, src/gui/error.cpp, src/gui/error.h,
+ src/gui/ministatus.cpp, src/gui/ok_dialog.cpp, src/gui/ok_dialog.h,
+ src/gui/setup.cpp, src/net/charserverhandler.cpp: A few cleanups and
+ simplifications.
+
+2006-01-26 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/game.h, src/main.cpp: Moved some setup code out of
+ the game loop into the setup functions. Setup functions are now called
+ from the outside.
+
+2006-01-22 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/main.cpp: Updated Dev-Cpp project file, fixed
+ a GDI issue.
+
+2006-01-22 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/net/network.cpp: Make dispatchMessages actually
+ handle more than one message per call.
+ * src/main.cpp: Remove obsoleted action listeners.
+ * src/main.cpp: Use generic error method for sound failure.
+ * src/main.cpp, src/net/charserverhandler.cpp,
+ src/net/loginhandler.cpp, src/net/maploginhandler.cpp,
+ src/net/network.cpp: Unify some network stuff in the main loop and fix
+ a bug in the network class that triggers when a handlers survives the
+ network object.
+
+2006-01-21 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/browserbox.cpp: Applied a patch by Ar2ro that works around
+ the problems with line wrapping in the chatbox. Note though that this
+ while code should be properly rewritten later.
+
+2006-01-20 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Updated Dev-Cpp project file.
+
+2006-01-20 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/equipment.h, src/game.cpp, src/game.h, src/main.h,
+ src/gui/buddywindow.cpp, src/gui/buddywindow.h,
+ src/gui/chargedialog.h, src/gui/connection.cpp, src/gui/connection.h,
+ src/gui/equipmentwindow.cpp, src/gui/equipmentwindow.h,
+ src/gui/linkhandler.h, src/gui/ministatus.h, src/gui/register.h,
+ src/net/protocol.h, src/resources/mapreader.h: Header, class
+ declaration and include cleanup.
+ * src/localplayer.cpp, src/localplayer.h, src/gui/requesttrade.cpp,
+ src/net/tradehandler.cpp: Made the local player object care about its
+ trading state, later this could be used for different stuff, like the
+ player setting itself to auto-decline trade offers without messing up
+ the code in the tradehandler. Removed message sending code from the
+ trade handler.
+ * src/npc.cpp, src/npc.h: Added the files for real this time.
+ * src/npc.cpp, src/npc.h, src/Makefile.am, src/being.cpp,
+ src/beingmanager.cpp, src/beingmanager.h, src/engine.cpp,
+ src/engine.h, src/game.cpp, src/game.h, src/localplayer.cpp,
+ src/localplayer.h, src/map.cpp, src/gui/buy.cpp, src/gui/buysell.cpp,
+ src/gui/buysell.h, src/gui/gui.cpp, src/gui/minimap.cpp,
+ src/gui/npc.cpp, src/gui/npc.h, src/gui/npc_text.cpp,
+ src/gui/npc_text.h, src/gui/npclistdialog.cpp,
+ src/gui/npclistdialog.h, src/gui/popupmenu.cpp,
+ src/gui/requesttrade.cpp, src/gui/requesttrade.h, src/gui/sell.cpp,
+ src/gui/setup.cpp, src/gui/skill.cpp, src/gui/skill.h,
+ src/gui/status.cpp, src/gui/status.h, src/net/buysellhandler.cpp,
+ src/net/charserverhandler.cpp, src/net/chathandler.cpp,
+ src/net/equipmenthandler.cpp, src/net/npchandler.cpp,
+ src/net/playerhandler.cpp, src/net/protocol.cpp,
+ src/net/tradehandler.cpp: Added a class for NPCs. Removed network
+ stuff from a bunch of gui dialog classes. Cleaned up some gui class
+ declarations and checked a bunch of includes for being useless.
+
+2006-01-19 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * INSTALL, README, The Mana World.dev, data/help/support.txt,
+ docs/INSTALL/debian.txt, docs/INSTALL/win32.txt, docs/progression.txt:
+ Updated infos on new irc channel.
+
+2006-01-14 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/main.cpp, src/main.h, src/gui/char_server.cpp,
+ src/gui/char_server.h: Moved network code out of the
+ ServerSelectDialog.
+ * src/gui/char_select.cpp, src/gui/char_select.h: Change setPlayerInfo
+ to updatePlayerInfo, as there's now a convenient wrapper around the
+ plain data.
+ * src/Makefile.am, src/lockedarray.cpp, src/lockedarray.h,
+ src/main.cpp, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/net/charserverhandler.cpp,
+ src/net/charserverhandler.h, src/net/network.cpp, src/net/network.h:
+ Created a single CharServerHandler. Created a LockedArray class to
+ "synchronize" access to arrays. Moved a bunch of networking out of the
+ char server related gui classes.
+ * src/Makefile.am, src/logindata.h, src/main.cpp, src/main.h,
+ src/gui/login.cpp, src/gui/login.h, src/gui/register.cpp,
+ src/gui/register.h: Removed network code from login and register
+ dialogs.
+ * src/gui/login.cpp, src/gui/login.h: Removed unused var.
+ * src/main.cpp, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/char_server.h,
+ src/gui/connection.cpp, src/gui/connection.h, src/gui/error.cpp,
+ src/gui/error.h, src/gui/login.cpp, src/gui/login.h,
+ src/gui/register.cpp, src/gui/register.h, src/gui/updatewindow.cpp,
+ src/gui/updatewindow.h: Removed the pre-game input handlers and
+ unified them in main.cpp. Some header and class cleanups.
+ * src/net/maploginhandler.cpp, src/net/maploginhandler.h,
+ src/Makefile.am, src/engine.cpp, src/engine.h, src/game.cpp,
+ src/main.cpp, src/gui/connection.cpp, src/gui/connection.h,
+ src/net/playerhandler.cpp: Made changeMap() care about sending the
+ map-loaded message. Removed network stuff from connection dialog.
+
+2006-01-13 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/gui/login.cpp, src/gui/login.h,
+ src/gui/register.cpp, src/net/loginhandler.cpp,
+ src/net/loginhandler.h: Remove duplicated code by unifying the message
+ handlers for login and register.
+ * src/gui/char_server.cpp, src/gui/char_server.h: Removed the polling
+ loop.
+ * src/gui/char_select.cpp, src/gui/char_select.h: Remove destructor
+ again, no idea why the compiler complained earlier.
+ * src/gui/char_select.cpp, src/gui/char_select.h: Created a message
+ handler for character creation and cleaned up the header file.
+ * src/gui/register.cpp, src/gui/register.h: Added a message handler
+ and removed the polling loop.
+ * src/net/network.cpp: Add recognition of disconnects.
+ * src/gui/connection.cpp, src/gui/connection.h,
+ src/net/playerhandler.cpp: Removed the polling loop and the duplicate
+ login message handler.
+ * src/gui/login.cpp, src/gui/login.h: Remove polling loop, the new
+ network code takes care of all that.
+ * src/net/network.cpp: Make sure that we don't send anything when not
+ connected.
+ * src/gui/login.cpp: Added a handler for network messages.
+ * src/game.cpp, src/net/beinghandler.cpp, src/net/beinghandler.h,
+ src/net/buysellhandler.cpp, src/net/buysellhandler.h,
+ src/net/chathandler.cpp, src/net/chathandler.h,
+ src/net/equipmenthandler.cpp, src/net/equipmenthandler.h,
+ src/net/inventoryhandler.cpp, src/net/inventoryhandler.h,
+ src/net/itemhandler.cpp, src/net/itemhandler.h,
+ src/net/messagehandler.cpp, src/net/messagehandler.h,
+ src/net/npchandler.cpp, src/net/npchandler.h,
+ src/net/playerhandler.cpp, src/net/playerhandler.h,
+ src/net/skillhandler.cpp, src/net/skillhandler.h,
+ src/net/tradehandler.cpp, src/net/tradehandler.h: Reverted the patch
+ to make the handlers register themselves, this just cannot work.
+ * src/game.cpp: Small cleanup.
+ * src/game.cpp, src/localplayer.cpp, src/localplayer.h: Made emote() a
+ method of the LocalPlayer class.
+
+2006-01-12 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/main.cpp, src/net/beinghandler.cpp,
+ src/net/beinghandler.h, src/net/buysellhandler.cpp,
+ src/net/buysellhandler.h, src/net/chathandler.cpp,
+ src/net/chathandler.h, src/net/equipmenthandler.cpp,
+ src/net/equipmenthandler.h, src/net/inventoryhandler.cpp,
+ src/net/inventoryhandler.h, src/net/itemhandler.cpp,
+ src/net/itemhandler.h, src/net/messagehandler.cpp,
+ src/net/messagehandler.h, src/net/npchandler.cpp,
+ src/net/npchandler.h, src/net/playerhandler.cpp,
+ src/net/playerhandler.h, src/net/skillhandler.cpp,
+ src/net/skillhandler.h, src/net/tradehandler.cpp,
+ src/net/tradehandler.h: Added a constructor parameter to the
+ MessageHandler class to support it self-registering to a network.
+ * src/game.cpp, src/net/beinghandler.cpp, src/net/network.cpp,
+ src/net/network.h, src/net/playerhandler.cpp: Moved the last few
+ messages out of the game loop into handlers. Added logging of
+ unhandled messages to the network class.
+ * src/Makefile.am, src/game.cpp, src/net/skillhandler.cpp,
+ src/net/skillhandler.h: Added a dedicated handler for skill messages.
+ * src/game.cpp, src/net/beinghandler.cpp: Moved some messages into the
+ being message handler.
+ * src/net/playerhandler.cpp: Fixed death listener.
+ * src/Makefile.am, src/game.cpp, src/net/playerhandler.cpp,
+ src/net/playerhandler.h: Added a dedicated handler for player
+ messages.
+ * src/game.cpp, src/net/chathandler.cpp: Moved WHO answer and some MVP
+ thing into the chat handler.
+ * src/Makefile.am, src/game.cpp, src/net/npchandler.cpp,
+ src/net/npchandler.h: Added a dedicated handler for npc messages.
+ * src/Makefile.am, src/game.cpp, src/net/itemhandler.cpp,
+ src/net/itemhandler.h: Added a dedicated handler for item messages.
+ * src/net/messagehandler.cpp, src/Makefile.am, src/game.cpp,
+ src/gui/char_select.cpp, src/gui/char_server.cpp,
+ src/gui/connection.cpp, src/net/messagehandler.h, src/net/network.cpp,
+ src/net/tradehandler.cpp, src/net/tradehandler.h: Made the
+ MessageHandler class aware of the network it is listening to and
+ unregistering itself.
+ * src/Makefile.am, src/beingmanager.cpp, src/beingmanager.h,
+ src/engine.cpp, src/game.cpp, src/net/beinghandler.cpp,
+ src/net/beinghandler.h: Added a dedicated handler for being messages.
+ Made the beingManager care about map changes.
+ * src/net/network.cpp: Removed some debug output.
+ * src/Makefile.am, src/game.cpp, src/net/inventoryhandler.cpp,
+ src/net/inventoryhandler.h: Added a dedicated handler for inventory
+ messages.
+ * src/game.cpp, src/inventory.cpp, src/inventory.h,
+ src/localplayer.cpp, src/localplayer.h, src/gui/trade.cpp,
+ src/net/buysellhandler.cpp, src/net/equipmenthandler.cpp,
+ src/net/tradehandler.cpp: Added delegation methods for inventory stuff
+ to the LocalPlayer class. Removed some unneeded includes.
+ * src/Makefile.am, src/game.cpp, src/net/equipmenthandler.cpp,
+ src/net/equipmenthandler.h: Added a dedicated handler for equipment
+ messages.
+ * src/game.cpp, src/localplayer.h: Removed unions, array are indexed
+ by the existing enums now.
+ * src/Makefile.am, src/game.cpp, src/net/buysellhandler.cpp,
+ src/net/buysellhandler.h: Added a dedicated handler for buy and sell
+ messages.
+ * src/Makefile.am, src/game.cpp, src/net/chathandler.cpp,
+ src/net/chathandler.h, src/net/tradehandler.cpp: Added a dedicated
+ handler for chat messages.
+
+2006-01-11 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/game.cpp, src/game.h, src/gui/popupmenu.cpp,
+ src/gui/requesttrade.h, src/net/messagehandler.h, src/net/network.cpp,
+ src/net/network.h, src/net/tradehandler.cpp, src/net/tradehandler.h:
+ Added a dedicated handler for trade messages.
+ * gui/char_select.cpp, gui/char_server.cpp, gui/connection.cpp,
+ net/messagehandler.h, net/network.cpp: Fixed a memory leak.
+ * src/Makefile.am, src/game.cpp, src/localplayer.cpp, src/main.cpp,
+ src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/char_server.h,
+ src/gui/connection.cpp, src/gui/connection.h, src/gui/gui.cpp,
+ src/gui/popupmenu.cpp, src/net/messagehandler.h, src/net/network.cpp,
+ src/net/network.h, src/net/protocol.cpp, src/net/protocol.h: Fixed
+ networking thread. Made skip calls queuable. Added MessageHandler base
+ class and added derived message handlers for some stuff.
+ * src/being.h, src/beingmanager.cpp, src/beingmanager.h,
+ src/game.cpp, src/game.h, src/localplayer.cpp, src/localplayer.h,
+ src/main.cpp, src/gui/buy.cpp, src/gui/buy.h, src/gui/buysell.cpp,
+ src/gui/buysell.h, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/char_server.h, src/gui/chat.cpp,
+ src/gui/chat.h, src/gui/connection.cpp, src/gui/connection.h,
+ src/gui/gui.cpp, src/gui/login.cpp, src/gui/login.h, src/gui/npc.cpp,
+ src/gui/npc.h, src/gui/npc_text.cpp, src/gui/npc_text.h,
+ src/gui/popupmenu.cpp, src/gui/register.cpp, src/gui/register.h,
+ src/gui/requesttrade.cpp, src/gui/requesttrade.h, src/gui/sell.cpp,
+ src/gui/sell.h, src/gui/skill.cpp, src/gui/skill.h,
+ src/gui/status.cpp, src/gui/status.h, src/gui/trade.cpp,
+ src/gui/trade.h, src/net/messageout.cpp, src/net/messageout.h,
+ src/net/network.cpp, src/net/network.h, src/net/protocol.cpp,
+ src/net/protocol.h: Created a network class.
+
+2006-01-10 Philipp Sehmisch <tmw@crushnet.org>
+
+ * data/graphics/tiles/Woodland.png: color modifications
+ * data/maps/new_9-1.tmx.gz: some more errors fixed
+
+2006-01-09 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp: Fixed canceled/cancelled inconsistency.
+
+2006-01-08 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/floor_item.cpp, src/floor_item.h, src/game.cpp,
+ src/localplayer.cpp, src/localplayer.h, src/gui/gui.cpp,
+ src/gui/popupmenu.cpp, src/net/protocol.cpp, src/net/protocol.h: Made
+ find_floor_item_by_cor return the item instead of its id. Made pickUp
+ a method of the LocalPlayer class.
+ * equipment.cpp, equipment.h, game.cpp, inventory.cpp, inventory.h,
+ localplayer.cpp, localplayer.h, gui/equipmentwindow.cpp,
+ gui/inventorywindow.cpp, gui/item_amount.cpp, gui/popupmenu.cpp: Made
+ inventory and equipment properties of the LocalPlayer class.
+ * src/game.cpp, src/game.h, src/gui/connection.cpp: Removed some
+ globals.
+
+2006-01-07 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/localplayer.cpp, src/localplayer.h: Created a walk
+ method for LocalPlayer.
+
+2006-01-07 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/maps/new_9-1.tmx.gz: Crush fixed the issues reported on wiki.
+ * The Mana World.dev, src/game.cpp, src/gui/setup.cpp, src/gui/setup.h,
+ src/main.cpp: Removed --skipupdate option from Dev.Cpp project file,
+ splitted the setup window into 3 tabs and added a joystick calibration
+ tool.
+
+2006-01-06 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/localplayer.cpp: Changed semantics for auto
+ target. The player now keeps attacking the select target till he
+ selects an other one, and not just by running into another one.
+ * src/being.cpp, src/beingmanager.cpp, src/beingmanager.h,
+ src/game.cpp, src/localplayer.h, src/gui/char_select.cpp,
+ src/gui/char_server.cpp: Fix local player id being wrongly assigned
+ causing various issues.
+ * src/gui/status.cpp: Fix attributes not being shown.
+ * src/Makefile.am, src/being.cpp, src/being.h, src/beingmanager.cpp,
+ src/beingmanager.h, src/engine.cpp, src/game.cpp, src/game.h,
+ src/localplayer.cpp, src/localplayer.h, src/main.cpp, src/map.cpp,
+ src/monster.cpp, src/monster.h, src/player.cpp, src/player.h,
+ src/playerinfo.h, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/chargedialog.cpp, src/gui/chat.cpp,
+ src/gui/gui.cpp, src/gui/inventorywindow.cpp, src/gui/minimap.cpp,
+ src/gui/ministatus.cpp, src/gui/popupmenu.cpp, src/gui/skill.cpp,
+ src/gui/status.cpp, src/gui/status.h, src/net/protocol.cpp,
+ src/net/protocol.h: Created subclasses of the Being class to move
+ specific code there. Added a BeingManager to remove use of globals.
+ Moved PLAYERINFO stuff into the new LocalPlayer class.
+
+2006-01-05 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * engine.cpp, engine.h, game.cpp, game.h, gui/buysell.h,
+ gui/chargedialog.h, gui/debugwindow.cpp, gui/debugwindow.h, gui/gui.h,
+ gui/ministatus.h, gui/npc_text.h, gui/sell.h, gui/setup.h: Remove some
+ useless code.
+
+2006-01-04 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/Makefile.am, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/confirm_dialog.cpp,
+ src/gui/confirm_dialog.h, src/gui/ok_dialog.cpp, src/gui/ok_dialog.h,
+ src/gui/trade.cpp, src/playerinfo.h: Reverted r0nny changes, enabled 3
+ slots to create players, smoothed player deletion.
+
+2006-01-04 Icy <icywolf@web.de>
+
+ * src/game.cpp, src/main.cpp, src/main.h: FreeBSD fixes to The Mana
+ World.
+
+2006-01-03 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp, src/gui/chat.cpp, src/gui/chat.h, src/gui/login.cpp,
+ src/gui/trade.cpp: Really disabled /commands and added proper message
+ when logging in and banned.
+ * src/game.cpp, src/gui/chat.cpp, src/gui/chat.h, src/net/protocol.h:
+ Enabled some /commands.
+ * src/main.cpp: Fixed a compile warning with GCC 4.1.
+
+2006-01-02 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/login.cpp, src/gui/register.cpp:
+ Smoothed also character creation, buttons are now disabled during
+ connection/data phase.
+
+2006-01-01 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/login.cpp, src/gui/login.h: Remove tracking of OkDialog, the
+ garbage collection stuff takes care of deletion and breaks manual
+ tracking.
+
+2006-01-01 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/main.cpp: Applied patch by pclouds that allows for a faster
+ login sequence by providing the username and password from the command
+ line, and allowing the client to choose the default server and
+ character.
+
+2005-12-30 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/chat.cpp, src/gui/chat.h: Applied patch by pclouds to have
+ the chat window temporarily become visible when chatting while it is
+ hidden.
+
+2005-12-30 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, data/graphics/sprites/items.png,
+ data/items.xml, src/Makefile.am, src/gui/char_select.cpp,
+ src/gui/char_server.cpp, src/gui/login.cpp, src/gui/login.h,
+ src/main.cpp, src/main.h, src/net/network.cpp, src/net/network.h,
+ src/gui/register.cpp, src/gui/register.h: Added a new item, improved
+ smooth login sequence, added a registration window (a lot of
+ duplicated code to be removed).
+
+2005-12-29 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, data/maps/new_10-1.tmx.gz,
+ src/gui/char_select.cpp, src/gui/char_select.h, src/gui/char_server.cpp,
+ src/gui/char_server.h, src/gui/connection.cpp, src/gui/connection.h,
+ src/gui/login.cpp, src/gui/login.h, src/net/network.h: Restored Dev-Cpp
+ default execution options, updated walkmap in snow map, smoothed login
+ sequence.
+
+2005-12-29 Jan-Fabian Humann <malastare@gmx.net>
+
+ * src/gui/gui.cpp: Added rather ugly workaround to prevent a on-start
+ crash by Doener. Fixed GCC 3.3.6 and 4.x paranthesis problem, patch
+ by r0nny. Fixed popupMenu not showing on items.
+
+2005-12-29 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/gui/popupmenu.cpp, src/net/protocol.cpp: Remove
+ duplicated code for picking up items as patched by pclouds.
+ * src/game.cpp, src/gui/gui.cpp, src/gui/gui.h,
+ src/gui/inventorywindow.cpp, src/gui/popupmenu.h: Added popup support
+ to the Gui and moved the according code there to get rid of some nasty
+ hack that made them disappear.
+ * src/game.cpp, src/gui/gui.cpp, src/gui/gui.h,
+ src/gui/inventorywindow.cpp, src/gui/popupmenu.h,
+ src/net/protocol.cpp, src/net/protocol.h: Moved all mouse input code
+ into the Gui class.
+
+2005-12-26 Duane Bailey <nayryeliab@gmail.com>
+
+ * src/main.h: Fixed define problems with The_Mana_World_private.h.
+
+2005-12-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/being.cpp: Small fix to prevent other stuff than the damage
+ numbers from fading out.
+
+2005-12-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/map.cpp: Worked around fringe layer drawing bug at the bottom.
+ * src/main.cpp: When compiling with OpenGL support, it'll default to
+ using OpenGL on only Windows and Mac. These systems are known to have
+ stable acceleration most of the time.
+ * NEWS, configure.ac, The Mana World.dev: Updated in preparation of
+ release 0.0.18.1.
+
+2005-12-20 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac: Changed version to 0.0.18.
+
+2005-12-18 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/maps/new_10-1.tmx.gz, src/main.cpp: Removed unused code and
+ added changes to snowy map by Bertram.
+
+2005-12-15 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp: Fixed setup window behaviour.
+
+2005-12-13 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/items.xml: Changed item properties according to eAthena scripting
+ capabilities.
+ * src/being.cpp: Enabled monster emotions.
+
+2005-12-12 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, data/graphics/tiles/Makefile.am, data/items.xml,
+ data/maps/Makefile.am, data/graphics/tiles/Woodland.png,
+ data/graphics/tiles/snowset.png, data/maps/new_9-1.tmx.gz,
+ data/maps/new_10-1.tmx.gz: Cleaned Dev-Cpp project file, added new
+ items definitions and new maps and tilesets.
+
+2005-12-08 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/graphics/sprites/monster11.png,
+ data/graphics/sprites/monster12.png, data/graphics/sprites/monster13.png,
+ data/graphics/sprites/monster14.png, data/graphics/sprites/Makefile.am,
+ data/graphics/sprites/items.png, data/graphics/sprites/npcs.png,: Added
+ new monsters, items and npcs.
+
+2005-12-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+ * src/gui/char_server.cpp: Avoid crashing on trying to log the name
+ of a non-existing character.
+ * src/main.h, src/main.cpp: Display TMW version on Windows too.
+
+2005-11-13 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Updated Dev-Cpp project file.
+
+2005-11-13 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/maps/new_1-1.tmx.gz, data/maps/new_3-1.tmx.gz,
+ data/maps/new_7-1.tmx.gz: Made the three desert maps use the fringe
+ layer for objects. Reveals bug with objects disappearing at the bottom
+ and still some draw order problems.
+
+2005-10-24 Ferreira Yohann <Bertram@cegetel.net>
+
+ * src/main.cpp: Add version displaying at startup.
+ * docs/INSTALL/debian.txt: Updated Debian Install Doc.
+
+2005-10-20 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/item_amount.cpp: Fix scrollbar not being updated when the
+ amount is changed using the buttons.
+ * src/gui/buddywindow.cpp, src/gui/buddywindow.h, src/gui/buy.cpp,
+ src/gui/buy.h, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/chat.cpp, src/gui/help.cpp,
+ src/gui/help.h, src/gui/inventorywindow.cpp,
+ src/gui/inventorywindow.h, src/gui/item_amount.cpp, src/gui/npc.cpp,
+ src/gui/npc.h, src/gui/npc_text.cpp, src/gui/npc_text.h,
+ src/gui/scrollarea.cpp, src/gui/scrollarea.h, src/gui/sell.cpp,
+ src/gui/sell.h, src/gui/setup.cpp ,src/gui/skill.cpp,
+ src/gui/trade.cpp, src/gui/updatewindow.cpp: Add garbage collection to
+ the ScrollArea class.
+ * src/gui/confirm_dialog.cpp, src/gui/confirm_dialog.h,
+ src/gui/connection.cpp, src/gui/connection.h, src/gui/debugwindow.cpp,
+ src/gui/debugwindow.h, src/gui/item_amount.cpp, src/gui/item_amount.h,
+ src/gui/menuwindow.cpp, src/gui/menuwindow.h, src/gui/ok_dialog.cpp,
+ src/gui/ok_dialog.h: Various cleanups and refactorisations.
+ * data/help/index.txt: Fix typo, remove spaces on empty lines.
+
+2005-10-19 Duane Bailey <nayryeliab@gmail.com>
+
+ * data/help/index.txt: Added SDL_net reference.
+
+2005-10-19 Yohann Ferreira <bertram@cegetel.net>
+
+ * debian/rules, debian/tmw.install, debian/copyright, debian/compat,
+ debian/changelog, debian/control, debian/docs, debian/tmw.menu:
+ Updated Debian files to get tmw ready for official ITP.
+
+2005-10-19 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/resources/resourcemanager.cpp: Fix empty lines not being read
+ from text files.
+ * src/gui/browserbox.cpp, src/gui/browserbox.h: Code cleanup.
+ * src/gui/gccontainer.cpp: Remove debug output.
+
+2005-10-18 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/gui/buddywindow.cpp, src/gui/buddywindow.h,
+ src/gui/buy.cpp, src/gui/buy.h, src/gui/buysell.cpp,
+ src/gui/buysell.h, src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/char_server.h,
+ src/gui/chargedialog.cpp, src/gui/chargedialog.h, src/gui/chat.cpp,
+ src/gui/confirm_dialog.cpp, src/gui/confirm_dialog.h,
+ src/gui/connection.cpp, src/gui/connection.h, src/gui/debugwindow.cpp,
+ src/gui/debugwindow.h, src/gui/error.h, src/gui/hbox.cpp,
+ src/gui/hbox.h, src/gui/help.cpp, src/gui/inttextbox.cpp,
+ src/gui/inttextbox.h, src/gui/inventorywindow.cpp,
+ src/gui/item_amount.cpp, src/gui/item_amount.h, src/gui/login.cpp,
+ src/gui/login.h, src/gui/menuwindow.cpp, src/gui/menuwindow.h,
+ src/gui/ministatus.cpp, src/gui/ministatus.h, src/gui/newskill.cpp,
+ src/gui/newskill.h, src/gui/npc.cpp, src/gui/npc_text.cpp,
+ src/gui/ok_dialog.cpp, src/gui/popupmenu.cpp, src/gui/popupmenu.h,
+ src/gui/requesttrade.cpp, src/gui/requesttrade.h, src/gui/sell.cpp,
+ src/gui/setup.cpp, src/gui/skill.cpp, src/gui/status.cpp,
+ src/gui/status.h, src/gui/tabbedcontainer.cpp, src/gui/trade.cpp,
+ src/gui/updatewindow.cpp, src/gui/vbox.cpp, src/gui/vbox.h,
+ src/gui/window.cpp, src/gui/window.h, src/gui/windowcontainer.cpp:
+ Added automatic widget cleanup to the window class.
+ * src/gui/connection.cpp, src/gui/connection.h, src/gui/error.cpp,
+ src/gui/status.cpp, src/gui/window.h: Header, whitespace and
+ indentation cleanups.
+
+2005-10-16 Duane Bailey <nayryeliab@gmail.com>
+
+ * src/main.cpp: OpenGL is now default for mac, win, and those who
+ define USE_OPENGL
+ * src/gui/setup.cpp: made it so those who use and go to fullscreen
+ requires a restart (texture/context baddies)
+
+2005-10-16 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.cpp, src/game.cpp, src/inventory.cpp, src/gui/buy.cpp,
+ src/gui/buysell.cpp, src/gui/char_select.cpp, src/gui/char_server.cpp,
+ src/gui/chat.cpp, src/gui/connection.cpp, src/gui/login.cpp,
+ src/gui/npc.cpp, src/gui/npc_text.cpp, src/gui/popupmenu.cpp,
+ src/gui/requesttrade.cpp, src/gui/sell.cpp, src/gui/skill.cpp,
+ src/gui/status.cpp, src/gui/trade.cpp, src/net/messagein.cpp,
+ src/net/messagein.h, src/net/messageout.cpp, src/net/messageout.h,
+ src/net/protocol.cpp: Rename {read,write}{Byte,Short,Long} to
+ {read,write}Int{8,16,32}.
+ * src/being.cpp, src/engine.cpp, src/engine.h, src/game.cpp,
+ src/main.cpp, src/gui/equipmentwindow.cpp, src/gui/itemcontainer.cpp,
+ src/resources/resourcemanager.cpp, src/resources/resourcemanager.h:
+ Use the ResourceManager to get spritesets.
+ * src/being.cpp: Reduce code duplication in the findNode functions and
+ use a functor to do the search.
+ * src/map.cpp: Some code improvements.
+ * src/Makefile.am: Added two missing files.
+
+2005-10-16 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/game.cpp, src/gui/char_select.cpp,
+ src/gui/char_server.cpp, src/gui/char_server.h, src/gui/connection.cpp,
+ src/gui/connection.h, src/gui/login.cpp, src/gui/login.h, src/main.cpp,
+ src/main.h, src/net/network.cpp, src/net/network.h,
+ src/net/protocol.cpp, src/net/protocol.h: The connection should be
+ non-blocking now and fixed the problem with sound not being played at
+ startup.
+
+2005-10-15 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp: Moved some variables into the conditional block
+ where they are used.
+ * src/being.cpp: A few changes that make the code look nicer.
+ * src/openglgraphics.cpp, src/resources/image.cpp,
+ src/resources/image.h: Some small cleanups.
+ * src/engine.cpp: Removed some legacy debug code.
+
+2005-10-13 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp: Prevent Alt+p/s/f from appearing in chatbox.
+ * src/Makefile.am: Some updates for added/removed headers.
+ * src/being.cpp: Changed char to signed char for GNU/Linux PPC.
+
+2005-10-13 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp, src/gui/browserbox.cpp, src/gui/gui.cpp,
+ src/gui/gui.h: Use gcn::Font instead of gcn::ImageFont where the
+ former is sufficient.
+
+2005-10-10 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/being.cpp, src/being.h, src/game.cpp: Always compile with debug
+ window and hide it on startup. Also added fading out effect on damage
+ font (only works in OpenGL).
+ * src/Makefile.am: Don't include debugwindow.h/cpp twice.
+ * data/graphics/gui/browserfont.png, data/graphics/gui/fixedfont.png,
+ data/graphics/gui/rpgfont_wider.png, src/gui/browserbox.cpp,
+ src/gui/gui.cpp: Pajarico added more international characters to the
+ fixed font and rpg font.
+ * src/game.cpp, README, data/helps/commands.txt: Introduced new window
+ shortcuts.
+ * src/gui/status.cpp: Corrected position of job XP bar.
+ * src/data/graphics/tiles/Makefile.am: Forgot to add new tilesets
+ here.
+ * src/map.cpp: Another small fix to sprite rendering.
+
+2005-10-09 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/gui/browserbox.cpp, src/gui/ministatus.cpp,
+ src/gui/debugwindow.h, src/gui/debugwindow.cpp, src/game.cpp,
+ src/engine.cpp, src/Makefile.am: Corrected the white browser font
+ bug and the black hp/mp bug which were linked. Added a debug window
+
+2005-10-09 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/being.cpp, src/being.h, src/engine.cpp, src/engine.h,
+ src/floor_item.cpp, src/floor_item.h, src/map.cpp, src/map.h,
+ src/sprite.h: Made Sprite into an interface implemented by both
+ FloorItem and Being, which hook themselves into the map on
+ construction. The improved fringe layer is working as expected now.
+ * src/equipment.cpp, src/equipment.h, src/game.cpp, src/game.h,
+ src/graphics.cpp, src/guichanfwd.h, src/inventory.h,
+ src/openglgraphics.cpp, src/sound.cpp, src/gui/chargedialog.cpp,
+ src/gui/chargedialog.h, src/gui/chat.cpp, src/gui/chat.h,
+ src/gui/equipmentwindow.cpp, src/gui/equipmentwindow.h,
+ src/gui/gui.cpp, src/gui/help.cpp, src/gui/inventorywindow.cpp,
+ src/gui/item_amount.cpp, src/gui/itemcontainer.cpp,
+ src/gui/itemcontainer.h, src/gui/linkhandler.h, src/gui/login.cpp,
+ src/gui/menuwindow.cpp, src/gui/newskill.cpp, src/gui/npc_text.cpp,
+ src/gui/popupmenu.cpp, src/gui/popupmenu.h, src/gui/progressbar.cpp,
+ src/gui/progressbar.h, src/gui/scrollarea.cpp, src/gui/scrollarea.h,
+ src/gui/skill.cpp, src/gui/status.cpp, src/gui/trade.h,
+ src/gui/window.cpp, src/gui/window.h, src/net/messagein.cpp,
+ src/net/packet.cpp, src/net/packet.h, src/resources/image.cpp,
+ src/resources/image.h, src/resources/iteminfo.cpp,
+ src/resources/iteminfo.h, src/resources/music.cpp,
+ src/resources/music.h, src/resources/soundeffect.cpp,
+ src/resources/soundeffect.h: Made sure TMW compiles without warnings
+ even when using "-Wconversion -Wshadow -Wcast-qual -Wwrite-strings
+ -ansi -pedantic", lots of cleanups.
+ * src/data/maps/new_3-1.tmx.gz, src/graphics/tiles/desert_x2.png,
+ src/graphics/tiled/desert_x3.png: Added two new small tilesets that
+ contain the desert tiles that are twice and three times the height of
+ a normal tile. One well in new_3-1 has been converted to use the new
+ double tiles for testing purposes.
+ * src/being.cpp, src/game.cpp, src/engine.cpp: Fixed map switch
+ crashing the client, display of [TARGET], Alt keys for toggling
+ windows and names to overlap other players.
+
+2005-10-06 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/being.cpp: Modified finding NPC as by timonator's suggestion in
+ order to allow NPCs to be clicked on their heads too.
+ * src/engine.cpp, src/engine.h, src/floor_item.cpp, src/floor_item.h,
+ src/game.cpp, src/map.cpp, src/sprite.h: Added a Sprite class that
+ represents something on the map. The map will make sure to draw the
+ sprites top to bottom, at the same time as the fringe layer tiles.
+ This is currently still only used by the floor items.
+ * src/item.cpp, src/item.h: Changed formatting and added
+ documentation.
+ * src/properies.h: Separated properties class from Map class, in order
+ to simplify Map class and to allow properties to be used by other
+ classes.
+
+2005-10-06 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.cpp, src/being.h, src/game.cpp: Use integer types from SDL
+ and along the way fixed some long vs. int issues.
+ * src/inventory.cpp: Return NULL when no valid item index is given to
+ getItem() to bail out early.
+
+2005-10-05 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/engine.cpp, src/main.cpp, src/gui/char_select.cpp,
+ src/gui/skill.cpp, src/net/messagein.cpp: Fixed some resource cleanup
+ and memory leaks.
+ * src/resources/resource.h, src/resources/resourcemanager.cpp:
+ Changed the way dangling references to resources are reported to be
+ more informative.
+
+2005-10-04 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/game.cpp, src/gui/menuwindow.cpp, src/gui/inventorywindow.cpp,
+ src/gui/equipmentwindow.cpp: Move to top the requested window with
+ shortcuts or with menu button, also corrected the default position
+ of equipment and inventory windows.
+ * src/gui/chat.cpp: Fixed the Chat Window scrolling bug.
+ * src/gui/status.cpp, src/gui/ministatus.cpp: Changed the font used
+ in mini-status. Dynamised previously statically placed widgets in
+ status win to avoid some label over-drawings.
+ * src/gui/setup.cpp: Enable the OpenGL Checkbox only if tmw has been
+ compiled with its support.
+
+2005-10-02 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac, src/Makefile.am: Added check for pthread library and
+ removed manual -lpthread and -lguichan linker flags.
+ * src/map.cpp: A small start on supporting other tile height than the
+ default (map) tile height.
+ * src/gui/window.cpp, src/gui/window.h, src/resources/buddylist.cpp,
+ src/resources/buddylist.h: Some cleanups (void argument list was
+ something you had to do in C times, not necessary in C++).
+
+2005-09-30 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/gui/inventorywindow.cpp, src/gui/inventorywindow.h,
+ src/gui/window.h src/gui/window.cpp src/gui/setup.cpp: Made the
+ inventory Win behave normally when resized by default size functions.
+
+2005-09-29 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/game.cpp, src/gui/window.h, src/gui/window.cpp, src/gui/setup.h,
+ src/gui/setup.cpp, src/gui/chat.cpp, src/gui/inventorywindow.h,
+ src/gui/inventorywindow.cpp, src/gui/skill.cpp,
+ src/gui/equipmentwindow.cpp, src/gui/menuwindow.cpp,
+ src/gui/ministatus.cpp, src/gui/minimap.cpp, src/gui/status.cpp:
+ Improved a lot windows reset to default size and pos. Also corrected
+ a few the default win position. And moved the setposition from game to
+ each win, to clarify the code.
+
+2005-09-29 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/map.cpp, src/map.h, src/tileset.h, src/resources/mapreader.cpp,
+ src/resources/mapreader.h: Moved tileset management into the map class
+ and made sure the tilesets are cleaned up properly on switching maps.
+
+2005-09-28 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/gui/updaterwindow.cpp: Fixed the scroll bug in the update window.
+ * src/gui/ministatus.h, src/gui/ministatus.cpp: Added HP, MP Display
+ in mini-status window.
+ * src/gui/window.h, src/gui/window.cpp, src/gui/skill.cpp,
+ src/gui/status.cpp, src/gui/equipmentwindow.cpp, src/gui/help.cpp,
+ src/gui/inventorywindow.cpp, src/gui/minimap.cpp, src/gui/chat.cpp:
+ Added window internal name to later get X, Y, height and width be
+ saved.
+ * src/gui/window.h, src/gui/window.cpp, src/game.cpp: Load and save X,
+ Y, Width and Height of windows when useful.
+ * src/gui/setup.cpp, src/gui/setup.h; src/gui/minimap.h: Added a 'Reset
+ Windows to Default' Button in the Setup Window.
+
+2005-09-28 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/browserbox.cpp: Fix deletion of the gui font because of a
+ missing check.
+ * src/Makefile.am: Added -Werror to the CXXFLAGS to catch warnings
+ easier.
+ * src/gui/error.h: Removed unnecessary ambigous inheritance.
+
+2005-09-26 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/gui/char_select.cpp, debian/control, debian/rules,
+ debian/tmw.install, debian/changelog: Updated Debian files and fixed a
+ typo let by Elven.
+
+2005-09-26 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/Makefile.am, src/game.cpp,
+ src/gui/char_select.cpp, src/gui/char_server.cpp, src/gui/error.cpp,
+ src/gui/error.h, src/gui/gui.cpp, src/gui/login.cpp,
+ src/gui/updatewindow.cpp, src/main.cpp, src/main.h,
+ src/net/network.cpp: Added a nicer handling of when you get
+ disconnected from the server.
+ * src/gui/char_select.cpp, src/gui/skill.cpp, src/main.cpp, src/main.h,
+ src/net/network.cpp: Now error message is displayed properly when the
+ map server is offline.
+
+2005-09-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/openglgraphics.cpp: Fixed taking OpenGL screenshots and in
+ addition made it flip the image using just a line buffer instead of a
+ buffer for the complete image. Still needs testing on MacOS X.
+
+2005-09-24 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/being.cpp, src/engine.cpp, src/game.cpp, src/main.cpp,
+ src/map.cpp, src/sound.cpp, src/gui/char_select.cpp,
+ src/gui/char_select.h, src/gui/char_server.cpp, src/gui/char_server.h,
+ src/gui/chargedialog.cpp, src/gui/chargedialog.h, src/gui/chat.cpp,
+ src/gui/equipmentwindow.cpp, src/gui/login.h, src/gui/setup.cpp,
+ src/gui/setup.h, src/gui/status.cpp, src/gui/updatewindow.cpp,
+ src/gui/updatewindow.h, src/resources/iteminfo.cpp,
+ src/resources/iteminfo.h, src/resources/itemmanager.cpp,
+ src/resources/itemmanager.h: Merged most of the changes in
+ biggeruniverse's second memory cleanup patch.
+
+2005-09-23 Duane Bailey <nayryeliab@gmail.com>
+
+ * src/openglgraphics.cpp: Totally redid the OpenGL screenshot method.
+ Needs to be tested on lil endian systems. Also made it smoother on
+ OpenGL MacOSX.
+
+2005-09-23 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/resources/imagewriter.cpp: Reverted the last change that broke
+ the screenshots facility.
+
+2005-19-22 Duane Bailey <nayryeliab@gmail.com>
+
+ * src/net/win2mac.h, src/net/win2mac.cpp: Removed
+ * src/net/network.h, src/net/messagein.h, src/net/messageout.h:
+ Removed references to win2mac.h
+ * src/net/messagein.cpp, src/net/messageout.cpp, src/net/network.cpp:
+ Changed byte swapping support to SDL_endian
+
+2005-09-21 Andrej Sinicyn <andrej4000@gmail.com>
+
+ * src/gui/chat.cpp: Show time of the messages in the chat window.
+ * The Mana World.dev: Removed reference to src/gui/stats.* since they
+ are in the attic now.
+
+2005-09-20 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/game.cpp, src/gui/ok_dialog.cpp, src/gui/ok_dialog.h,
+ src/gui/window.cpp: Enter is used to dismiss dialogs currently,
+ removed the hacks for use in combination with non-modal dialogs that
+ made the game crash.
+ * src/openglgraphics.cpp: Changed glColor4f to glColor4ub.
+
+2005-09-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * configure.ac: Replaced custom function FIND_PATH with AC_PATH_PROG,
+ used for finding sdl-config.
+ * src/Makefile.am: Removed -lphysfs which should be added
+ automatically already.
+ * src/engine.cpp, src/game.h, src/game.cpp, src/openglgraphics.h,
+ src/gui/popupmenu.cpp, src/net/messagein.cpp, src/net/messageout.cpp,
+ src/net/win2mac.h, src/net/win2mac.cpp: Some cleanups.
+ * src/game.cpp: Actually show the overweight message, and only show it
+ once for each time weight goes above half the max weight (apparently
+ this code wasn't even tested once).
+ * src/graphics.cpp: Surfaces passed to SDL_BlitSurface shouldn't be
+ locked according to the manual.
+ * src/main.cpp: Minimal fps limit is now 10 fps.
+ * src/gui/updatewindow.cpp: Reverted change by Bertram that hardcoded
+ the updatehost value.
+
+2005-09-19 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp, src/gui/trade.cpp, src/gui/updatewindow.cpp,
+ src/inventory.cpp: Removed useless flush() calls.
+ * src/being.cpp, src/game.cpp, src/gui/buy.cpp, src/gui/buysell.cpp,
+ src/gui/char_select.cpp, src/gui/char_server.cpp, src/gui/chat.cpp,
+ src/gui/login.cpp, src/gui/npc.cpp, src/gui, npc_text.cpp,
+ src/gui/popipmenu.cpp, src/gui/requesttrade.cpp, src/gui/sell.cpp,
+ src/gui/skill.cpp, src/gui/status.cpp, src/gui/trade.cpp,
+ src/inventory.cpp, src/net/messageout.cpp, src/net/network.cpp,
+ src/net/network.h, src/net/protocol.cpp: Got rid of writeSet() calls.
+ * data/graphics/sprites/monster2.png: Fixed some non very bright pixels.
+
+2005-09-18 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/gui/npc.cpp: Updated dev-cpp project file to
+ last changes, and fixed the bug with npc lists I introduced earlier.
+ * data/items.xml: Updated the defense value of fancy hat as pointed out
+ by xand.
+ * src/game.cpp, src/gui/gui.cpp, src/gui/updatewindow.cpp,
+ src/main.cpp, src/resources/mapreader.cpp: Applied biggeruniverse's
+ patch to fix memory leaks.
+ * src/game.cpp, src/main.cpp: Increased joypad tolerance which is safer
+ and simplifyed joypad state reset code.
+
+2005-09-18 Duane Bailey <nayryeliab@gmail.com>
+
+ * game.cpp: Added weight notice; now notifies person when they
+ are carrying more then half their weight
+
+2005-09-18 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/game.cpp, src/graphics.cpp, src/graphics.h,
+ src/resources/imagewriter.cpp, src/resources/imagewriter.h:
+ Made the saveScreenShot makes its screenshots under user home dir in
+ *nices, made it more C++ way to avoid a leak, and made it check
+ for existence of a file with same name before writing; In that
+ case the screenshot's number is incremented until it finds
+ an adequate name.
+ * src/gui/updatewindow.cpp: Corrected a bug in the determination
+ of the update host I had.
+ * src/gui/updatewindow.cpp, src/playerinfo.h, debian/control,
+ debian/changelog: Corrected a range value bug for derived stats.
+ Fixed the percentage of the update win, updated debian information.
+ * src/gui/status.cpp: As m[a]tt noticed, made the status win a
+ little more wide, and resizable.
+
+2005-09-18 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp, src/graphics.cpp, src/graphics.h: Move the writing
+ logic out of the Graphics class once again... Some cleanups in the
+ screenshot filename selection code.
+ * src/resources/imagewriter.cpp: Small cleanups.
+ * src/Makefile.am, src/game.cpp, src/graphics.cpp, src/graphics.h,
+ src/openglgraphics.cpp, src/openglgraphics.h: Changed saveScreenshot
+ function in Graphics to getScreenshot. We now use the ImageWriter to
+ save that screenshot.
+ * src/resources/imagewriter.cpp, src/resources/imagewriter.h: Added
+ ImageWriter class that provides a function to save a SDL surface as
+ png.
+
+2005-09-17 Duane Bailey <nayryeliab@gmail.com>
+
+ * src/net/messagin.cpp, src/net/messageout.cpp, src/net/network.cpp:
+ removed replaced MACOSX defines with big endian defines
+ * src/graphics.cpp, src/graphics.h: added screenshot method
+ * src/game.cpp: added code, so that when one presses 'alt-p' (for
+ picture), it takes a screenshot and saves it to a png
+ * src/Makefile.am, config.ac: added png library stuff
+
+2005-09-17 Matthias Hartmann <hartmann.matthias@gmail.com>
+
+ * src/engine.cpp: [TARGET] text over player
+ * src/game.cpp, src/game.h: PVP
+ * src/gui/popupmenu.cpp: Added "attack" option to the popupmenu
+ * src/net/protocol.cpp: findPlayer
+
+2005-09-17 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/engine.cpp, src/game.cpp: Indent properly.
+
+2005-09-17 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * configure.ac: Fix typo.
+ * src/Makefile.am: Remove useless (duplicate) -lpng.
+ * src/graphics.cpp: Add missing cstdarg header.
+ * src/net/messagein.cpp: Fix some funny looking preprocessor
+ statement.
+ * src/net/messageout.cpp: Readd SDLnet header, for changed
+ preprocessor stuff.
+ * src/game.h: Remove inclusion of being.h, there was a forward
+ declaration of class Being anyways...
+ * src/openglgraphics.cpp: Use gl{Push,Pop}Matrix instead of
+ calculating offsets, cause the values are stored as float and aren't
+ accurate enough.
+
+2005-09-17 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/gui/skill.cpp: Updated to last changes, and
+ wrong names fixes.
+ * src/being.cpp, src/game.cpp, src/gui/buy.cpp, src/gui/buysell.cpp,
+ src/gui/char_select.cpp, src/gui/char_server, src/gui/chat.cpp,
+ src/gui/npc.cpp, src/gui/npc_text.cpp, src/gui/popupmenu.cpp,
+ src/gui/requesttrade.cpp, src/gui/sell.cpp, src/gui/skill.cpp,
+ src/gui/status.cpp, src/gui/trade.cpp, src/inventory.cpp,
+ src/net/messageout.cpp, src/net/network.cpp, src/net/network.h,
+ src/net/protocol.cpp, src/net/protocol.h: Completed transition to use
+ MessageOut.
+
+2005-09-17 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/game.cpp, src/gui/ministatus.cpp, src/gui/ministatus.h,
+ src/gui/menuwindow.h, src/gui/menuwindow.cpp, src/gui/status.cpp,
+ src/gui/status.h: Improving General Layout.
+ * src/games.cpp, src/playerinfo.h, src/gui/char_server.cpp,
+ src/gui/char_select.cpp, src/gui/ministatus.cpp, src/gui/skill.cpp,
+ src/gui/status.cpp, src/gui/status.h: Now the derived stats values
+ are got from the server, and then, are correct ones.
+ * src/gui/minimap.cpp: Only shows the Minimap Window if there's
+ actually a minimap to the current map.
+ * src/gui/status.cpp, src/game.cpp: The derived stats are now updated
+ correctly upon equipping/unequipping.
+
+2005-09-16 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/resources/image.cpp: Report which error occured when loading of
+ an image fails.
+
+2005-09-14 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp: Fix missing parentheses in a negated check.
+ * src/engine.cpp, src/engine.h, src/game.cpp: Moved Map management
+ code completely into engine.cpp.
+ * src/net/messagein.cpp, src/net/messagein.h, src/net/messageout.cpp,
+ src/net/messageout.h: Added stream operators for char, short and long
+ reading and writing.
+ * src/game.cpp, src/log.cpp, src/main.cpp, src/gui/char_select.cpp,
+ src/gui/char_server.cpp, src/gui/login.cpp, src/net/messageout.cpp,
+ src/net/messageout.h, src/net/network.cpp, src/net/network.h,
+ src/net/packet.cpp, src/net/protocol.cpp: Header cleanups.
+ * src/gui/popupmenu.cpp, src/gui/sell.cpp: Use cassert instead of
+ assert.h.
+ * src/net/network.cpp: Add missing cassert header, remove some unused
+ headers.
+ * src/net/messagein.cpp: Add missing cassert header.
+ * src/being.cpp, src/being.h, src/game.cpp: Made Being::setDamage
+ accept a short instead of a string.
+ * src/game.cpp, src/game.h, src/gui/char_select.cpp: Converted
+ map_path from char array to std::string.
+
+2005-09-13 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Updated to last changes.
+ * The Mana World.dev: Added latest changes to the proper branch.
+ * src/gui/login.cpp, src/net/messageout.cpp, src/net/messageout.h,
+ src/net/network.cpp, src/net/network.h: Started to use MessageOut to
+ send login data.
+
+2005-09-13 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * ChangeLog, The Mana World.dev, configure.ac, src/Makefile.am,
+ src/being.cpp, src/being.h, src/engine.cpp, src/floor_item.cpp,
+ src/floor_item.h, src/game.cpp, src/game.h, src/inventory.cpp,
+ src/log.h, src/main.cpp, src/playerinfo.h, src/serverinfo.h,
+ src/gui/buy.cpp, src/gui/buysell.cpp, src/gui/char_select.cpp,
+ src/gui/char_server.cpp, src/gui/chargedialog.cpp, src/gui/chat.cpp,
+ src/gui/inventorywindow.cpp, src/gui/login.cpp, src/gui/npc.cpp,
+ src/gui/npc.h, src/gui/npc_text.cpp, src/gui/npc_text.h,
+ src/gui/popupmenu.cpp, src/gui/requesttrade.cpp,
+ src/gui/requesttrade.h, src/gui/sell.cpp, src/gui/skill.cpp,
+ src/gui/stats.cpp, src/gui/status.cpp, src/gui/status.h,
+ src/gui/trade.cpp, src/net/messagein.cpp, src/net/messagein.h,
+ src/net/messageout.cpp, src/net/messageout.h, src/net/network.cpp,
+ src/net/network.h, src/net/packet.cpp, src/net/packet.h,
+ src/net/protocol.cpp, src/net/protocol.h, src/net/win2linux.h,
+ src/net/win2mac.cpp, src/net/win2mac.h: Merged with SDL_NET_TEST
+ branch.
+ * src/being.cpp, src/being.h, src/game.cpp: Simplify remove_node.
+ * src/being.cpp, src/being.h, src/game.cpp: Merged createBeing and
+ add_node into createBeing.
+ * src/main.cpp, src/main.h, src/gui/char_select.cpp,
+ src/gui/login.cpp: Removed some globals.
+ * src/main.cpp, src/main.h, src/gui/char_select.cpp,
+ src/gui/char_select.h, src/gui/char_server.cpp, src/gui/char_server.h,
+ src/gui/login.cpp, src/gui/login.h, src/gui/updatewindow.cpp,
+ src/gui/updatewindow.h: Unified the loops for the various dialogs that
+ are shown before the actual game starts.
+ * src/gui/login.cpp: Removed a close_session call i missed.
+ * src/gui/login.cpp: Close the session only when it was opened.
+
+2005-09-13 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/floor_item.cpp, src/floor_item.h, src/engine.cpp,
+ popupmenu.cpp: Made members private and provided more convenient
+ constructor.
+ * src/net/messageout.cpp: Fixed bug in destructor.
+ * src/net/network.cpp: Initialize buffers and enforce only a single
+ session at a time.
+ * src/game.cpp, src/net/protocol.h: Converted all incoming messages
+ handled in game.cpp to use the MessageIn class. This is a huge change
+ so please test if everything is still working correctly.
+ * src/gui/npc.cpp, src/gui/npc.h, src/gui/npc_text.cpp,
+ src/gui/npc_text.h: Changed argument from char* to std::string for
+ convenience.
+ * src/gui/setup.cpp, src/gui/setup.h: Enabled OpenGL checkbox and
+ added messagebox informing the user that apply this change requires
+ restarting the client.
+ * src/gui/updatewindow.cpp: Start displaying file progress at 0% and
+ some small fixes.
+
+2005-09-12 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/gui/browserbox.cpp, src/gui/gui.cpp,
+ src/resources/resourcemanager.cpp, src/resources/resourcemanager.h,
+ src/resources/sdlimageloader.cpp, src/resources/sdlimageloader.h:
+ Added SDLImageLoader to make guichan support physfs. Removed
+ ResourceManager::getRealPath() because it's no longer needed.
+
+2005-09-12 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * data/graphics/gui/hits_blue.png, data/graphics/gui/hits_red.png,
+ data/graphics/gui/hits_yellow.png: Made shadow translucent.
+ * data/graphics/images/minimap_new_7-1.png: Added this minimap.
+ * data/help/changes.txt, data/help/commands.txt: Added 0.0.16 changes.
+ * data/maps/new_7-1.tmx.gz: Fixed well being in the wrong layer.
+
+2005-09-11 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/net/network.cpp: Improved error reporting a bit and got rid of
+ loop for sending data, which shouldn't be necessary according to
+ SDL_net documentation.
+ * src/Makefile.am, src/being.cpp, src/being.h, src/engine.cpp,
+ src/game.cpp, src/main.cpp, src/playerinfo.h, src/gui/char_server.cpp,
+ src/gui/chargedialog.cpp, src/gui/chat.cpp,
+ src/gui/inventorywindow.cpp, src/gui/popupmenu.cpp, src/gui/skill.cpp,
+ src/gui/stats.cpp, src/gui/status.cpp, src/gui/status.h,
+ src/net/protocol.cpp: Changed char_info into the array it's used as
+ for character selection and introduced player_info as the pointer to
+ the player information. Should help towards support for multiple
+ characters on the same account. Also changed PLAYER_INFO name field to
+ a std::string.
+ * src/net/win2mac.cpp, src/net/win2mac.h: A bit of clean up.
+ * src/net/packet.h, src/net/packet.cpp, src/net/messagein.h,
+ src/net/messagein.cpp, src/net/messageout.h, src/net/messageout.cpp:
+ Added these packet reading/writing helpers, taken from the new server
+ in development.
+ * src/gui/char_select.cpp: Made new character message be parsed
+ using MessageIn. Many other incoming messages should be ready to be
+ ported similarly, simplifying the parsing of packets because of
+ automatic incrementation of the read position.
+ * src/game.cpp, src/game.h, src/gui/popupmenu.cpp,
+ src/gui/requesttrade.cpp, src/gui/requesttrade.h: Changed
+ tradePartnerName to std::string.
+ * src/net/win2linux.h: Removed because it became redundant with
+ the use of SDL_net.
+ * src/game.cpp, src/game.h, src/gui/char_select.cpp,
+ src/net/messagein.cpp, src/net/messagein.h, src/net/network.cpp,
+ src/net/network.h: Got rid of usage of Packet by MessageIn,
+ simplifying both its usage and implementation. Now also handling
+ response to character selection through MessageIn.
+ * src/main.cpp, src/serverinfo.h, src/gui/char_select.cpp,
+ src/gui/char_server.cpp, src/gui/login.cpp, src/net/network.cpp,
+ src/net/network.h, src/net/protocol.cpp, src/net/protocol.h:
+ Introduced get_next_message function to reduce duplication of that
+ process. Also now MessageIn is used for all incoming messages handled
+ during the login sequence.
+ * src/being.cpp, src/being.h, src/game.cpp, src/game.h,
+ src/inventory.cpp, src/serverinfo.h, src/gui/login.cpp,
+ src/gui/trade.cpp, src/net/messagein.cpp, src/net/messagein.h,
+ src/net/network.cpp, src/net/protocol.cpp, src/net/protocol.h: Added
+ readCoordinates and readCoordinatePair to MessageIn for reading the
+ specific ways eAthena sends sends those, and converted part of
+ game.cpp to use the MessageIn class. Also simplified cases where
+ flush() was still called in a loop for sending and added asserts to
+ MessageIn methods.
+
+2005-09-10 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/log.cpp: Committed patch by Nayr for displaying a messagebox
+ when an error occurs on MacOS.
+
+2005-09-10 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * configure.ac: Add check for SDL_net.
+
+2005-09-09 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/game.cpp: Fixes to dropped items network code
+
+2005-09-09 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/net/win2linux.h: Removed inclusion of malloc.h header as it
+ doens't seem necessary and was problematic on FreeBSD.
+
+2005-09-08 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp: Clean the floor items when the map changes.
+
+2005-08-30 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * README, The Mana World.dev, data/graphics/sprites/items.png,
+ data/graphics/sprites/npcs.png, data/help/header.txt,
+ data/help/skills.txt, data/items.xml, data/maps/new_8-1.tmx.gz:
+ Updated docs for release, fixed Dev-Cpp project file, added more items
+ and npcs, fixed the new map and added it to the makefile.
+
+2005-08-31 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/openglgraphics.cpp: Fix push/pop of clip area, we need to
+ translate using the x/y offset, not the x/y coordinates of the clip
+ area. This fixes the broken scrollareas.
+
+2005-08-30 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Updated project file.
+ * data/graphics/sprites/npcs.png, src/gui/sell.cpp: Added empty sprite
+ and reorganized spriteset, fixed a typo.
+
+2005-08-29 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/configlistener.cpp, src/configlistener.h: Made
+ the destructor inline, as it is an interface, we don't need a .cpp
+ file, thus it was removed.
+ * src/resources/image.cpp, src/resources/image.h,
+ src/resources/music.cpp, src/resources/music.h,
+ src/resources/resource.cpp, src/resources/resource.h,
+ src/resources/resourcemanager.cpp, src/resources/soundeffect.cpp,
+ src/resources/soundeffect.h: Removed the setIdPath() method from the
+ Resource class and added the idPath as a Constructor parameter, as
+ that value is not meant to be changed.
+
+2005-08-29 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * data/maps/new_8-1.tmx.gz: Some layer and walkability fixes.
+
+2005-08-28 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/openglgraphics.cpp, src/gui/browserbox.cpp,
+ src/gui/buddywindow.cpp, src/gui/buddywindow.h, src/gui/buysell.h,
+ src/gui/char_server.h, src/gui/chargedialog.h, src/gui/chat.cpp,
+ src/gui/chat.h, src/gui/confirm_dialog.h, src/gui/equipmentwindow.h,
+ src/gui/focushandler.h, src/gui/gui.cpp, src/gui/gui.h,
+ src/gui/help.h, src/gui/inttextbox.cpp, src/gui/inventorywindow.cpp,
+ src/gui/inventorywindow.h, src/gui/item_amount.h,
+ src/gui/itemcontainer.cpp, src/gui/listbox.cpp, src/gui/newskill.h,
+ src/gui/npc_text.h, src/gui/ok_dialog.h, src/gui/passwordfield.cpp,
+ src/gui/requesttrade.h, src/gui/setup.h, src/gui/stats.h,
+ src/gui/status.h, src/gui/textbox.cpp, src/gui/textfield.cpp,
+ src/gui/trade.h, src/gui/updatewindow.h: Add #include's that just
+ weren't necessary because the guichan folks don't provide clean
+ headers. This is preparatory for the case that they ever do. ;)
+ * src/gui/gui.cpp, src/gui/gui.h: Create a GuiConfigListener class.
+ * src/gui/window.h: Small cleanup.
+ * src/gui/window.cpp, src/gui/window.h: Create a static ConfigListener
+ for the Window class. (Fixes each Window listening to config changes,
+ although they only affect a static class member.)
+
+2005-08-27 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/npc.cpp: Fix a memory leak.
+ * src/game.cpp, src/gui/npc.cpp, src/gui/npc.h: Fix the bug when
+ sometimes the last entry in npc list windows is missing. The network
+ buffer isn't reset to all zeros, thus we can't rely on the received
+ string to be nul-terminated, instead we have to use the length
+ parameter we receive from eAthena (and this way we're also safe
+ against buffer overflows, because we can use strncpy()).
+ * src/gui/window.cpp: Bail out early if there's no window container.
+ * src/engine.cpp, src/game.cpp, src/gui/stats.cpp, src/gui/stats.h,
+ src/gui/status.cpp, src/gui/status.h: Update the stats and status
+ window contents only at a single location and let them do it
+ automagically.
+ * src/gui/updatewindow.cpp, src/gui/updatewindow.h: Small cleanups.
+
+2005-08-25 Ferreira Yohann <bertram@cegetel.net>
+
+ * src/gui/buy.h, src/gui/buy.cpp, src/gui/sell.h, src/gui/sell.cpp,
+ src/gui/inventorywindow.h, src/gui/inventorywindow.cpp: Added effect
+ description to those each windows, and also made some improvements and
+ bugfixes as I was on it.
+ * data/maps/new_7-1.tmx.gz: Added eyecandy to the map 7-1.
+
+2005-08-26 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * ChangeLog: Fix indentation and line length.
+ * docs/HACKING.txt: Fix the example (OOPS!).
+ * src/configuration.cpp: Remove dependency on math.h.
+ * src/openglgraphics.cpp: Remove useless code.
+ * src/openglgraphics.cpp: Use glTranslatef instead of glTranslated.
+ Remove some useless code.
+
+2005-08-25 Ferreira Yohann <bertram@cegetel.net>
+
+ * src/main.h, src/main.cpp, src/gui/login.cpp,
+ src/resources/buddylist.cpp, gui/char_select.cpp: Adding min and max
+ length check for password, more code cleanups in login and removing
+ possible buffer overflows by replacing some global char[] by
+ std::strings.
+ * src/items.h, src/items.cpp, src/resources/itemmanager.h,
+ src/resources/itemmanager.cpp, src/resources/iteminfo.h,
+ src/resources/iteminfo.cpp, data/items.xml, data/items.xsd: Added
+ Effects description to items.
+
+2005-08-25 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * ChangeLog: Fixed line length using tab size of 8.
+ * src/configuration.h, src/configuration.cpp: Removed some debug code
+ and updated documentation a bit.
+ * src/resources/resourcemanager.cpp: Removed unused (I think) headers
+ for Windows.
+
+2005-08-25 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/openglgraphics.cpp: Use the translation capabilities of OpenGL
+ instead of doing it ourselves all the time.
+ * src/graphics.cpp: Simplify the image rect drawing code a bit and
+ remove an obsolete included header.
+ * src/openglgraphics.cpp, src/openglgraphics.h: Reduce the code
+ duplication even further.
+ * src/engine.cpp, src/floor_item.cpp, src/floor_item.h: Move the
+ extern declaration for the floor item list into engine.cpp as it's
+ only used there.
+ * src/log.cpp: Lower indentation level.
+ * src/openglgraphics.cpp, src/openglgraphics.h: Reduce code
+ duplication.
+ * src/configuration.cpp: Fix compilation errors.
+ * src/graphics.cpp, src/openglgraphics.cpp, src/gui/button.cpp,
+ src/gui/checkbox.cpp, src/gui/equipmentwindow.cpp,
+ src/gui/itemcontainer.cpp, src/gui/minimap.cpp,
+ src/gui/passwordfield.cpp, src/gui/playerbox.cpp,
+ stc/gui/progressbar.cpp, src/gui/radiobutton.cpp,
+ src/gui/scrollarea.cpp, src/gui/slider.cpp, src/gui/textfield.cpp,
+ src/gui/window.cpp: Made our Graphics::drawImage() method respect the
+ clip area from the guichan part. Removed some obsolete code.
+ * src/gui/tabbedcontainer.h: Fix include path for guichanfwd.h.
+ * src/gui/tabbedcontainer.cpp, src/gui/tabbedcontainer.h: Added a new
+ container type, that allows switching between the contents through a
+ tab bar at the top of the container.
+ * ChangeLog: Fixed intendation and line length.
+ * docs/HACKING.txt: Added a notice about line length in ChangeLog and
+ an example for the ChangeLog format.
+
+2005-08-24 Ferreira Yohann <bertram@cegetel.net>
+
+ * src/game.cpp: Simply don't show equipped items in sell dialog as it's
+ annoying.
+ * src/gui/login.h, src/gui/login.cpp: Code cleanups and improvements
+ to the login sequence.
+
+2005-08-23 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/shop.h: Fixed using a forward declaration for std::string,
+ where it was a class member.
+ * src/game.cpp, src/gui/sell.cpp, src/gui/sell.h: Made the sell dialog
+ accepts Items instead of looking them up in the inventory.
+ * src/gui/sell.cpp: Some code cleanups, simplifications and removal of
+ duplicate code.
+ * src/gui/buy.cpp, src/gui/sell.cpp, src/gui/shop.h: Avoid possible
+ buffer overflows by using a std::string instead of char[30].
+ * src/gui/buy.cpp: Some code cleanups, simplifications and removal of
+ duplicate code.
+
+2005-08-22 Ferreira Yohann <bertram@cegetel.net>
+
+ * src/gui/buy.cpp, src/gui/sell.cpp, src/game.cpp: Removed asserts as
+ they were not suitable for a stable implementation of buy/sell dialogs
+ and made some improvements on them. Still has to clean up code.
+ * src/gui/login.h, src/login.cpp: Code cleanups, little improvements of
+ the login function.
+
+2005-08-22 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/skill.cpp: Disabled use button in skill dialog since is still
+ not being used.
+
+2005-08-20 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/openglgraphics.cpp: Added some missing state changes and checks.
+ * src/gui/inventorywindow.cpp, src/gui/item_amount.cpp,
+ src/gui/item_amount.h, src/gui/popupmenu.cpp, src/gui/trade.cpp: Made
+ the item amount dialog work on a provided item, instead of having it
+ ask the inventory window itself.
+
+2005-08-19 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp, src/game.cpp: The engine isn't connected to all the
+ gui windows, so move creation from its constructor into the game.cpp
+ where most of them are actually used.
+ * src/log.cpp, src/log.h, src/main.cpp: Added support for parsing
+ command line options. Added option to skip the update process. Made
+ logger being created immediately after startup, because some
+ destructors use it.
+
+2005-08-18 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/game.cpp, src/gui/skill.h, src/gui/skill.cpp:
+ Updated reference to latest libxml, fixed a bug in updating skills,
+ updated skill names database.
+
+2005-08-18 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/graphics.cpp, src/graphics.h, src/main.cpp,
+ src/openglgraphics.cpp src/openglgraphics.h, src/gui/gui.cpp,
+ src/resources/image.h: Semi-separated OpenGL and SDL graphics classes,
+ improves OpenGL performance quite a bit, while rewriting a good bunch
+ of code provided by guichan (but maybe we'll diverge so much that we'd
+ need that anyways...)
+
+2005-08-17 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/configuration.cpp, src/resources/itemmanager.cpp,
+ src/resources/mapreader.cpp: Removed special #ifdefs for libxml2
+ linking issues in Win32.
+
+2005-08-16 Ferreira Yohann <bertram@cegetel.net>
+
+ * src/gui/window.h, src/gui/window.cpp: Bugfixing and simplifying
+ resize code.
+ * debian/*: Updates to the debian packaging files. (The actual update
+ was from a few days ago.) Now we have the tmw, tmw-data and tmw-music
+ packages.
+ * src/gui/setup.h, src/gui/setup.cpp: Now the setup (Config) windows
+ works as it should be. (The actual update was from a few days ago.)
+
+2005-08-16 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev, src/gui/status.cpp, src/gui/window.cpp,
+ src/gui/window.h, src/gui/windowcontainer.h,
+ data/graphics/gui/resize.png: Added a resize grip to resizable window,
+ fixed some compiling errors.
+
+2005-08-15 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp, src/gui/gui.cpp, src/gui/gui.h: Removed guiTop global
+ variable.
+ * src/graphics.cpp, src/graphics.h, src/main.cpp: Made the OpenGL
+ related code fully #ifdef'ed.
+ * src/main.cpp, src/gui/browserbox.cpp, src/gui/gui.cpp,
+ src/resources/image.cpp, src/resources/image.h: Fully faded out the
+ useOpenGL global. Image and Graphics keep track of the mode on their
+ own now (the latter will go away once we have separate classes...)
+ * src/graphics.cpp, src/graphics.h, src/main.cpp, src/main.h,
+ src/gui/browserbox.cpp, src/gui/gui.cpp, src/resources/image.cpp:
+ Started to fade out the useOpenGL global variable.
+ * src/engine.cpp, src/gui/char_select.cpp, src/gui/char_server.cpp,
+ src/gui/chat.cpp, src/gui/gui.cpp, src/gui/gui.h, src/gui/login.cpp,
+ src/gui/popupmenu.cpp, src/gui/setup.cpp, src/gui/updatewindow.cpp,
+ src/gui/window.cpp: Removed guiGraphics global pointer and removed
+ dependencies on gui.h in some places.
+
+
+2005-08-14 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/graphics.cpp, src/graphics.h, src/resources/image.cpp,
+ src/resources/image.h: Moved the image drawing code into the graphics
+ class.
+ * src/being.cpp, src/engine.cpp, src/graphics.cpp, src/graphics.h: Made
+ the wrapper functions in the Graphics class conditional on whether we
+ compile with OpenGL support.
+
+2005-08-13 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/being.cpp, src/being.h, src/configlistener.cpp,
+ src/configlistener.h, src/configuration.cpp, src/configuration.h,
+ src/engine.cpp, src/engine.h, src/equipment.cpp, src/equipment.h,
+ src/game.cpp, src/game.h, src/graphics.cpp, src/graphics.h,
+ src/guichanfwd.h, src/inventory.cpp, src/inventory.h, src/item.h,
+ src/log.cpp, src/log.h, src/main.cpp, src/main.h, src/map.cpp,
+ src/map.h, src/playerinfo.h, src/sound.cpp, src/sound.h,
+ src/graphic/imagerect.h, src/graphic/spriteset.cpp,
+ src/graphic/spriteset.h, src/gui/box.h, src/gui/browserbox.cpp,
+ src/gui/browserbox.h, src/gui/buddywindow.h, src/gui/button.cpp,
+ src/gui/button.h, src/gui/buy.cpp, src/gui/buy.h, src/gui/buysell.h,
+ src/gui/char_select.cpp, src/gui/char_select.h,
+ src/gui/char_server.cpp, src/gui/char_server.h,
+ src/gui/chargedialog.cpp, src/gui/chargedialog.h, src/gui/chat.cpp,
+ src/gui/chat.h, src/gui/chatinput.cpp, src/gui/checkbox.cpp,
+ src/gui/checkbox.h, src/gui/confirm_dialog.cpp,
+ src/gui/confirm_dialog.h, src/gui/equipmentwindow.cpp,
+ src/gui/equipmentwindow.h, src/gui/focushandler.h, src/gui/gui.cpp,
+ src/gui/gui.h, src/gui/help.cpp, src/gui/help.h,
+ src/gui/inttextbox.cpp, src/gui/inttextbox.h,
+ src/gui/inventorywindow.cpp, src/gui/inventorywindow.h,
+ src/gui/item_amount.cpp, src/gui/item_amount.h,
+ src/gui/itemcontainer.cpp, src/gui/itemcontainer.h,
+ src/gui/listbox.cpp, src/gui/listbox.h, src/gui/login.cpp,
+ src/gui/login.h, src/gui/minimap.cpp, src/gui/minimap.h,
+ src/gui/newskill.cpp, src/gui/newskill.h, src/gui/npc.h,
+ src/gui/npc_text.h, src/gui/ok_dialog.cpp, src/gui/ok_dialog.h,
+ src/gui/passwordfield.h, src/gui/playerbox.cpp, src/gui/playerbox.h,
+ src/gui/popupmenu.cpp, src/gui/popupmenu.h, src/gui/progressbar.cpp,
+ src/gui/progressbar.h, src/gui/radiobutton.cpp, src/gui/radiobutton.h,
+ src/gui/requesttrade.cpp, src/gui/requesttrade.h,
+ src/gui/scrollarea.cpp, src/gui/scrollarea.h, src/gui/sell.cpp,
+ src/gui/sell.h, src/gui/setup.cpp, src/gui/setup.h, src/gui/skill.h,
+ src/gui/slider.cpp, src/gui/slider.h, src/gui/stats.cpp,
+ src/gui/stats.h, src/gui/status.cpp, src/gui/status.h,
+ src/gui/textbox.cpp, src/gui/textbox.h, src/gui/textfield.cpp,
+ src/gui/textfield.h, src/gui/trade.cpp, src/gui/trade.h,
+ src/gui/updatewindow.cpp, src/gui/updatewindow.h, src/gui/window.cpp,
+ src/gui/window.h, src/gui/windowcontainer.h, src/net/protocol.cpp,
+ src/net/protocol.h, src/resources/buddylist.hm
+ src/resources/image.cpp, src/resources/image.h,
+ src/resources/itemmanager.cpp, src/resources/itemmanager.h,
+ src/resources/mapreader.cpp, src/resources/mapreader.h,
+ src/resources/music.h, src/resources/resource.cpp,
+ src/resources/resourcemanager.cpp, src/resources/resourcemanager.h,
+ src/resources/soundeffect.h: Huge header cleanup, removing nearly all
+ #include's from headers to reduce dependencies and compile time.
+ * src/engine.cpp, src/gui/char_select.cpp, src/gui/inventorywindow.cpp,
+ src/gui/skill.cpp, src/gui/skill.h, src/gui/stats.cpp,
+ src/gui/status.cpp: Another small header cleanup, should also solve
+ compilation problems on windows.
+ * src/gui/sell.cpp: Reset selection in the sell dialog if all items at
+ the selected slot are sold.
+
+2005-08-13 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/gui/status.h, src/gui/status.cpp: Reformatted status window
+ layout to avoid overlapping and lowered saturation of bars' colors.
+ * src/gui/status.cpp: Removed smooth color changing from xp bar which
+ was causing problems and doesn't act as the job xp bar.
+ * The Mana World.dev, src/game.cpp, src/playerinfo.h,
+ src/net/protocol.cpp, src/resources/itemmanager.cpp,
+ src/gui/inventorywindow.cpp: Updated dev-cpp project file, removed
+ unnecessary header, fixed some include paths.
+
+2005-08-12 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * src/buy.cpp, src/sell.cpp: Resetting quantity to 0 after selecting
+ other items in buy/sell dialogs.
+
+2005-08-11 Andrej Sinicyn <andrej4000@gmail.com>
+
+ * src/resources/image.cpp: Little cleanup and simplification.
+
+2005-08-10 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp, src/graphics.cpp, src/graphics.h,
+ src/gui/browserbox.cpp, src/gui/gui.cpp, src/gui/listbox.cpp,
+ src/gui/minimap.cpp, src/gui/progressbar.cpp, src/gui/scrollarea.cpp:
+ Moved knowledge about whether we use OpenGL into the Graphics class (as
+ much as possible)
+ * src/game.cpp: Added helper function for being creation to reduce code
+ duplication. Some code simplifications.
+
+2005-08-09 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp: Adjust drawing offset to have the player centered in
+ higher resolutions as well.
+
+2005-08-04 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/main.cpp: Use "true" instead of "1" as bool argument.
+ * src/resources/resourcemanager.cpp, src/resources/resourcemanager.h:
+ Added a method to determine the real path of a file in the PhysFS
+ search path.
+ * src/gui/browserbox.cpp: Make use of then new resource manager method
+ to determine the real path of a file.
+ * src/gui/gui.cpp: Dynamically determine the path to graphic files
+ instead of using the try-catch fallback method.
+
+2005-08-03 Andrej Sinicyn <andrej4000@gmail.com>
+
+ * src/game.cpp, src/game.h, src/gui/requesttrade.cpp,
+ src/gui/requesttrade.h: Moved my invented variable, since it makes more
+ sense.
+ * src/game.cpp, src/game.h, src/gui/requesttrade.cpp: Fix my previous
+ fix because it broke my own code.
+
+2005-08-03 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/main.cpp: Use PhysFS to determine user's home directory on unix
+ system. Removed an now unused header.
+ * src/game.cpp: Commented a switch case label that was left uncommented
+ though the rest was commented.
+ * src/resources/buddylist.cpp, src/main.h: Removed unneeded header from
+ main.h, added it to buddylist.cpp.
+ * src/engine.cpp: Converted two global variables to function-local
+ ones.
+
+2005-08-02 Andrej Sinicyn <andrej4000@gmail.com>
+
+ * src/game.cpp: Fixed "Trade canceled" happening often.
+
+2005-08-02 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/engine.cpp: Cleanups in the drawing code.
+ * src/engine.cpp, src/game.cpp: Made autoTarget checks being handled at
+ a single location.
+ * src/being.cpp, src/being.h, src/engine.h: Small header cleanups.
+ * src/graphics.cpp, src/graphics.h, src/main.cpp, src/main.h,
+ src/gui/setup.cpp: Moved graphics setup code into the graphics class.
+
+2005-08-02 Marcel W. Wysocki <maci@satgnu.org>
+
+ * tmw/src/gui/status.cpp: making setup dialog quitting when clicking
+ on setup button while dialog is opened
+
+2005-08-01 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/inventory.cpp, src/inventory.h, src/gui/itemcontainer.cpp,
+ src/gui/itemcontainer.h: Added a logic function to dynamically adjust
+ the size of the itemcontainer.
+ * src/game.cpp: Fixed autoTarget not being set to NULL on map change.
+
+2005-07-31 Andrej Sinicyn <andrej4000@gmail.com>
+
+ * src/game.cpp, src/game.h, src/gui/popupmenu.cpp: Show the name of the
+ trade partner in the trade dialog.
+
+2005-07-31 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/listbox.cpp: Small cleanup of the drawing code.
+ * src/engine.cpp: Added a check to stop scrolling when we hit the map
+ border.
+
+2005-07-31 Andrej Sinicyn <andrej4000@gmail.com>
+
+ * src/game.cpp: Don't allow more than one trade dialog or requesting it
+ at once; if a trade is canceled on the other side, close the trade
+ window.
+
+2005-07-30 Andrej Sinicyn <andrej4000@gmail.com>
+
+ * src/main.cpp: Removed unnecessary value assignment to a variable.
+
+2005-07-30 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/main.cpp, src/resources/resourcemanager.h,
+ src/resources/resourcemanager.cpp: Fixed buggy check for the existence
+ of the updates directory. Extended the resource manager with some
+ physfs functions and moved the actual setup process from the resource
+ manager constructor into the main initialization.
+
+2005-07-29 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp: Fixed popup window not always being correctly hidden
+ when the player clicks somewhere else.
+
+2005-07-28 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/main.cpp, src/gui/update.cpp, src/resources/resourcemanager.cpp,
+ src/resources/resourcemanager.h: Added support for files downloaded
+ through the update manager to the resource manager. Changed directory
+ name for updates from "data" to "updates".
+ * src/game.cpp, src/gui/inventorywindow.cpp, src/gui/popupmenu.cpp,
+ src/gui/popupmenu.h: Cleaned up the showPopup() code, moved
+ "map"-related code into game.cpp, made the popup show up at mouse
+ coordinates instead of being aligned to tiles.
+ * src/being.cpp, src/being.h, src/engine.cpp, src/game.cpp, src/game.h,
+ src/gui/gui.cpp, src/net/protocol.cpp: Added an action enumeration to
+ the Being class and removed the old #define's.
+ * src/resources/resourcemanager.cpp: Fixed a location where a wrong
+ dir-separator was used.
+ * src/main.cpp: Fixed updates directory not being created on non-unix
+ systems. Started using PhysFS write support.
+
+2005-07-27 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/engine.cpp, src/game.cpp, src/graphics.cpp, src/graphics.h,
+ src/main.cpp, src/gui/browserbox.cpp, src/gui/button.cpp,
+ src/gui/gui.cpp, src/gui/listbox.cpp, src/gui/minimap.cpp,
+ src/gui/playerbox.cpp, src/gui/progressbar.cpp,
+ src/gui/scrollarea.cpp, src/gui/textfield.cpp, src/gui/window.cpp,
+ src/resources/image.cpp, src/resources/image.h,
+ src/resources/mapreader.h: Merged OpenGL/SDL merge patch by Andrej
+ Sinicyn, and his followup patch for fixing SDL-only build.
+
+2005-07-27 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/gui/gui.cpp, src/gui/gui.h: Removed continous mouse movement,
+ that implementation wasn't suitable for a release.
+
+2005-07-26 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.cpp, src/being.h, src/engine.cpp, src/game.cpp,
+ src/gui/minimap.cpp, src/gui/popupmenu.cpp, src/net/protocol.cpp:
+ Introduced a Being::Type enumeration. Added type-aware findNode()
+ function.
+ * src/being.cpp: Set font back to gui font after drawing speech.
+ Draw auto-target marker in engine instead of being.
+ * src/gui/popupmenu.cpp: Fixed empty popup window being shown when user
+ right clicks on an empty tile while the popup is visible.
+
+2005-07-26 Eugenio Favalli <elvenprogrammer@gmail.com>
+
+ * The Mana World.dev: Updated release infos.
+ * data/graphics/sprites/emotions.png: Added Modanung's smilies.
+ * src/being.cpp, src/engine.cpp: Fixed text and smilies position.
+ * src/game.cpp: Cleanups.
+ * src/gui/skill.cpp: Added new skill names.
+ * src/main.cpp: Moved sound playback to update screen and changed song.
+
+2005-07-24 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/game.cpp: Made the key-event handler use switches instead of
+ if-else.
+ * src/gui/gui.cpp, src/gui/gui.h: Allow continous movement when holding
+ down the left mouse button.
+
+2005-07-23 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/being.h, src/being.cpp: Added a member to keep the current map,
+ restored setDestination.
+ * src/game.cpp, src/gui/gui.cpp: Change calls to Being::setPath() to
+ Being::setDestination().
+ * src/map.h: Add a forward declaration for struct PATH_NODE.
+
+2005-07-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * NEWS: Moved project news here.
+ * ChangeLog: Started standard ChangeLog file here.
+ * docs/HACKING.txt: Added info about member naming and ChangeLog
+ format.
+ * src/gui/updatewindow.h, src/gui/updatewindow.cpp: Changed member
+ names, set a 15 second timeout for connecting to update server and
+ restore some doxygen comments, improved size adaption and made the
+ window a shorter.
+ * data/graphics/images/login_wallpaper.png: New login wallpaper by
+ Momotaro.
diff --git a/English.lproj/InfoPlist.strings b/English.lproj/InfoPlist.strings
new file mode 100644
index 000000000..7080cf949
--- /dev/null
+++ b/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/English.lproj/SDLMain.nib/classes.nib b/English.lproj/SDLMain.nib/classes.nib
new file mode 100644
index 000000000..c4b887e72
--- /dev/null
+++ b/English.lproj/SDLMain.nib/classes.nib
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/English.lproj/SDLMain.nib/info.nib b/English.lproj/SDLMain.nib/info.nib
new file mode 100644
index 000000000..0411a4a54
--- /dev/null
+++ b/English.lproj/SDLMain.nib/info.nib
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBFramework Version</key>
+ <string>670</string>
+ <key>IBLastKnownRelativeProjectPath</key>
+ <string>../themanaworld.xcodeproj</string>
+ <key>IBOldestOS</key>
+ <integer>5</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>29</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>9F33</string>
+ <key>targetFramework</key>
+ <string>IBCarbonFramework</string>
+</dict>
+</plist>
diff --git a/English.lproj/SDLMain.nib/objects.xib b/English.lproj/SDLMain.nib/objects.xib
new file mode 100644
index 000000000..6d0c83dbc
--- /dev/null
+++ b/English.lproj/SDLMain.nib/objects.xib
@@ -0,0 +1,77 @@
+<?xml version="1.0" standalone="yes"?>
+<object class="NSIBObjectData">
+ <object name="rootObject" class="NSCustomObject" id="1">
+ </object>
+ <array count="8" name="allObjects">
+ <object class="IBCarbonMenuItem" id="229">
+ <string name="title">Quit</string>
+ <string name="keyEquivalent">q</string>
+ <boolean name="notPreviousAlternate">TRUE</boolean>
+ <ostype name="command">quit</ostype>
+ </object>
+ <object class="IBCarbonWindow" id="166">
+ <boolean name="receiveUpdates">FALSE</boolean>
+ <boolean name="liveResize">TRUE</boolean>
+ <boolean name="compositing">TRUE</boolean>
+ <boolean name="isConstrained">FALSE</boolean>
+ <string name="title">Window</string>
+ <object name="rootControl" class="IBCarbonRootControl" id="167">
+ <string name="viewFrame">0 0 480 360 </string>
+ <string name="bounds">0 0 360 480 </string>
+ </object>
+ <string name="windowRect">204 300 564 780 </string>
+ <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string>
+ </object>
+ <object class="IBCarbonMenu" id="184">
+ <string name="title">themanaworld</string>
+ <string name="name">_NSAppleMenu</string>
+ <array count="3" name="items">
+ <object class="IBCarbonMenuItem" id="187">
+ <string name="title">About themanaworld</string>
+ <int name="keyEquivalentModifier">0</int>
+ <ostype name="command">abou</ostype>
+ </object>
+ <object class="IBCarbonMenuItem" id="230">
+ <boolean name="separator">TRUE</boolean>
+ <boolean name="disabled">TRUE</boolean>
+ <boolean name="notPreviousAlternate">TRUE</boolean>
+ </object>
+ <reference idRef="229"/>
+ </array>
+ </object>
+ <reference idRef="230"/>
+ <object class="IBCarbonMenu" id="29">
+ <string name="title">main</string>
+ <string name="name">_NSMainMenu</string>
+ <array count="1" name="items">
+ <object class="IBCarbonMenuItem" id="185">
+ <string name="title">themanaworld</string>
+ <reference name="submenu" idRef="184"/>
+ </object>
+ </array>
+ </object>
+ <reference idRef="167"/>
+ <reference idRef="187"/>
+ <reference idRef="185"/>
+ </array>
+ <array count="8" name="allParents">
+ <reference idRef="184"/>
+ <reference idRef="1"/>
+ <reference idRef="185"/>
+ <reference idRef="184"/>
+ <reference idRef="1"/>
+ <reference idRef="166"/>
+ <reference idRef="184"/>
+ <reference idRef="29"/>
+ </array>
+ <dictionary count="3" name="nameTable">
+ <string>File&apos;s Owner</string>
+ <reference idRef="1"/>
+ <string>MainWindow</string>
+ <reference idRef="166"/>
+ <string>MenuBar</string>
+ <reference idRef="29"/>
+ </dictionary>
+ <string name="targetFramework">IBCarbonFramework</string>
+ <unsigned_int name="nextObjectID">231</unsigned_int>
+</object>
diff --git a/English.lproj/main.nib/classes.nib b/English.lproj/main.nib/classes.nib
new file mode 100644
index 000000000..c4b887e72
--- /dev/null
+++ b/English.lproj/main.nib/classes.nib
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/English.lproj/main.nib/info.nib b/English.lproj/main.nib/info.nib
new file mode 100644
index 000000000..0411a4a54
--- /dev/null
+++ b/English.lproj/main.nib/info.nib
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBFramework Version</key>
+ <string>670</string>
+ <key>IBLastKnownRelativeProjectPath</key>
+ <string>../themanaworld.xcodeproj</string>
+ <key>IBOldestOS</key>
+ <integer>5</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>29</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>9F33</string>
+ <key>targetFramework</key>
+ <string>IBCarbonFramework</string>
+</dict>
+</plist>
diff --git a/English.lproj/main.nib/objects.xib b/English.lproj/main.nib/objects.xib
new file mode 100644
index 000000000..6d0c83dbc
--- /dev/null
+++ b/English.lproj/main.nib/objects.xib
@@ -0,0 +1,77 @@
+<?xml version="1.0" standalone="yes"?>
+<object class="NSIBObjectData">
+ <object name="rootObject" class="NSCustomObject" id="1">
+ </object>
+ <array count="8" name="allObjects">
+ <object class="IBCarbonMenuItem" id="229">
+ <string name="title">Quit</string>
+ <string name="keyEquivalent">q</string>
+ <boolean name="notPreviousAlternate">TRUE</boolean>
+ <ostype name="command">quit</ostype>
+ </object>
+ <object class="IBCarbonWindow" id="166">
+ <boolean name="receiveUpdates">FALSE</boolean>
+ <boolean name="liveResize">TRUE</boolean>
+ <boolean name="compositing">TRUE</boolean>
+ <boolean name="isConstrained">FALSE</boolean>
+ <string name="title">Window</string>
+ <object name="rootControl" class="IBCarbonRootControl" id="167">
+ <string name="viewFrame">0 0 480 360 </string>
+ <string name="bounds">0 0 360 480 </string>
+ </object>
+ <string name="windowRect">204 300 564 780 </string>
+ <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string>
+ </object>
+ <object class="IBCarbonMenu" id="184">
+ <string name="title">themanaworld</string>
+ <string name="name">_NSAppleMenu</string>
+ <array count="3" name="items">
+ <object class="IBCarbonMenuItem" id="187">
+ <string name="title">About themanaworld</string>
+ <int name="keyEquivalentModifier">0</int>
+ <ostype name="command">abou</ostype>
+ </object>
+ <object class="IBCarbonMenuItem" id="230">
+ <boolean name="separator">TRUE</boolean>
+ <boolean name="disabled">TRUE</boolean>
+ <boolean name="notPreviousAlternate">TRUE</boolean>
+ </object>
+ <reference idRef="229"/>
+ </array>
+ </object>
+ <reference idRef="230"/>
+ <object class="IBCarbonMenu" id="29">
+ <string name="title">main</string>
+ <string name="name">_NSMainMenu</string>
+ <array count="1" name="items">
+ <object class="IBCarbonMenuItem" id="185">
+ <string name="title">themanaworld</string>
+ <reference name="submenu" idRef="184"/>
+ </object>
+ </array>
+ </object>
+ <reference idRef="167"/>
+ <reference idRef="187"/>
+ <reference idRef="185"/>
+ </array>
+ <array count="8" name="allParents">
+ <reference idRef="184"/>
+ <reference idRef="1"/>
+ <reference idRef="185"/>
+ <reference idRef="184"/>
+ <reference idRef="1"/>
+ <reference idRef="166"/>
+ <reference idRef="184"/>
+ <reference idRef="29"/>
+ </array>
+ <dictionary count="3" name="nameTable">
+ <string>File&apos;s Owner</string>
+ <reference idRef="1"/>
+ <string>MainWindow</string>
+ <reference idRef="166"/>
+ <string>MenuBar</string>
+ <reference idRef="29"/>
+ </dictionary>
+ <string name="targetFramework">IBCarbonFramework</string>
+ <unsigned_int name="nextObjectID">231</unsigned_int>
+</object>
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 000000000..46836c212
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,77 @@
+How to compile and run Mana on your GNU/Linux Box
+=================================================
+
+Homepage: http://manasource.org/
+IRC: irc.freenode.net / #manasource
+
+1) Requirements
+2) Compiling And Installing Mana
+3) Notes
+
+
+1. Requirements
+===============
+
+You are expected to have either checked out Mana from Git or you have downloaded
+a source release. To get Mana to compile, you need a compiler (GCC)
+and some libraries. The required libraries are:
+
+* SDL http://www.libsdl.org/
+* SDL_mixer http://www.libsdl.org/projects/SDL_mixer/
+* SDL_image http://www.libsdl.org/projects/SDL_image/
+* SDL_net http://www.libsdl.org/projects/SDL_net/
+* SDL_ttf http://www.libsdl.org/projects/SDL_ttf/
+* SDL_gfx http://www.ferzkopp.net/joomla/software-mainmenu-14/4-ferzkopps-linux-software/19-sdlgfx
+* ENet 1.2 http://enet.bespin.org/
+* Guichan 0.8.x http://guichan.sourceforge.net/
+* libxml2 http://www.xmlsoft.org/
+* physfs 1.x http://icculus.org/physfs/
+* zlib 1.2.x http://www.gzip.org/zlib/
+* libcurl http://curl.haxx.se/libcurl/
+
+If you've cloned the Git repository, you will also need these tools to compile:
+
+* GNU automake 1.9 http://www.gnu.org/software/automake/
+* GNU autoconf http://www.gnu.org/software/autoconf/
+* GNU gettext http://www.gnu.org/software/gettext/
+* CVS http://www.nongnu.org/cvs/ (needed to run autopoint)
+
+On some machines, it's been reported that this package is also needed. However,
+you might not need it:
+
+* GNU libtool http://www.gnu.org/software/libtool/
+
+Installing these dependencies is distributions-specific, and we'll leave it to
+you to figure this out.
+
+
+2. Compiling And Installing Mana
+================================
+
+1) Go to the directory you have extracted the source to.
+2) If you've cloned the Git repository, run "autoreconf -i" to generate
+ configure and install any missing auxiliary files.
+3) Run "./configure"
+4) Run "make"
+5) Run "make install" as root
+
+It should have installed Mana on your system now, and you can run it
+with "mana". By default all files are installed to /usr/local, you can pass a
+different prefix to configure as usual.
+
+
+ NOTE: It is possible to compile Mana without support for OpenGL rendering.
+ To do this perform step 3 as follows:
+
+ ./configure --without-opengl
+
+ Rebuild the executable from scratch using "make clean" and then "make".
+
+
+3. Notes
+========
+
+If you have any problems, you are welcome to post your questions on our forums,
+or talk about them in our IRC channel.
+
+- Mana Dev Team
diff --git a/Info.plist b/Info.plist
new file mode 100644
index 000000000..b5fecbee7
--- /dev/null
+++ b/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>mana.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>Mana</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>Mana</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright 2009 Mana Development Team</string>
+ <key>NSMainNibFile</key>
+ <string>SDLMain</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ <key>NSPrincipleClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 000000000..808de717d
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,20 @@
+# Subdirectories to build
+SUBDIRS = data docs po src
+
+desktopdir = $(datarootdir)/applications
+
+desktop_DATA = manaplus.desktop
+
+# Extra files to include
+EXTRA_DIST = $(desktop_DATA) \
+ CMakeLists.txt \
+ po/CMakeLists.txt \
+ CMake/Modules/FindENet.cmake \
+ CMake/Modules/FindGuichan.cmake \
+ CMake/Modules/FindLibIntl.cmake \
+ CMake/Modules/FindSDL_gfx.cmake \
+ mana.cbp \
+ manaplus.menu
+
+# Autopoint m4 stuff
+ACLOCAL_AMFLAGS = -I m4
diff --git a/Mana.icns b/Mana.icns
new file mode 100644
index 000000000..7230a0994
--- /dev/null
+++ b/Mana.icns
Binary files differ
diff --git a/NEWS b/NEWS
new file mode 100644
index 000000000..d9e096568
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,552 @@
+1.0.0 (...)
+- The Mana World client is now called the Mana client
+- Added support for branding the client differently via command line parameter
+- Added support for ManaServ and eAthena (TMW version) from the same binary
+- Added support for switching character or server without restart
+- Added downloading of server list
+- Added the ability to define multiple outfits to quickly switch between
+- Added /ignore, /unignore and /createparty commands
+- Added support for showing particle effects when monsters attack
+- Added highlights on hovering over buttons, tabs, sliders and scrollbars
+- Added --screenshot-dir command line parameter to set the screenshot directory
+- Added handling of player revival after dying
+- Added handling of damage dealt using skills
+- Added support for showing map background images
+- Added nick autocompletion in chat when pressing Tab
+- Added ability to only change player direction by holding "emote" key
+- Added option to show the amount of damage dealt to target monster
+- Added automatic loading of minimap based on file name
+- Added support for pasting text from the clipboard in text fields
+- Added rudimentary support for GUI themes
+- Added additional mouse cursors to indicate attack and talk actions
+- Added option to show gender next to player names
+- Added ability to unassign keyboard shortcuts
+- Combined Party and Guild (ManaServ) support in one Social window
+- Display the first key binding conflict in keyboard setup
+- The login wallpaper is now scaled when it doesn't exactly fit the screen
+- Ambient image layers can now be scaled to fit the screen
+- Automatically show inventory window when starting a trade
+- Display the party name of other players on mouseover
+- The party tab will now only show when you're in a party
+- Allow displaying warp portals using particle effects
+- Hide color codes from speech text
+- Improved keyboard control of the quit dialog
+- Quickly move items into your store by "emote"-clicking them
+- Allow redirects when downloading updates
+- Fixed windows to stay on screen when resolution is lowered
+- Fixed some slowness due to chat window
+- Changed the default locations for configuration, updates and screenshots
+- Many additional fixes and cleanups
+
+0.0.29.1 (9 June 2009)
+- Added the ability to change your password after logging in
+- The leader of a party is now displayed in bold
+- Status window was reorganized to allow larger numbers to be displayed
+- The client no longer quits when it can't find the current map
+- Fixed position of floating text for damage, pickup and experience
+- Fixed a possible crash on logging in to the map server
+- Fixed the crash when shift-clicking an item in the inventory
+- Fixed a crash related to item links in the chat window
+- Fixed a crash on whispering somebody again after closing their tab
+- Fixed lightspeed bug when stopping to attack
+- Fixed the -S/--home-dir command line option
+- Fixed Reset Windows to also reset the party window
+- Fixed problems with the context menu in the Brazilian translation
+- Fixed resetting the height of the chat on /clear
+- Fixed playing of login song and the music after login
+- Fixed a problem with the player skipping corners, desyncing from the server
+- Small optimizations to OpenGL mode when drawing certain GUI widgets
+- Updated Spanish, Polish, Portugese, Swedish, French and German translations
+
+0.0.29 (13 May 2009)
+- Added support for dynamic emotes and a new way to select them
+- Added speech balloons that wrap the text
+- Added item popup for showing detailed information
+- Added ability to refer to items in chat
+- Added the ability to see your own name in game
+- Added the option to hide player names
+- Added support for dynamically defined weight unit and currency
+- Added support for NPC item storage
+- Added compile-time support for tmwserv, as an alternative to eAthena
+- Added support for entering the port of the login server
+- Added support for creating parties and inviting other players to them
+- Added tabs to the chat window for party and private chats
+- Added ability to set initial player attributes when creating a new character
+- Added command line option to temporarily disable OpenGL (--no-opengl)
+- Added support for showing arrows flying through the air
+- Added option to show pickup as text particle instead of in the chat
+- Added ability to change the font size
+- Added support for the /me command to do actions
+- Added a /present command to show players present in the area
+- Added ability to record the chatlog to a file
+- Made emote shortcuts customizable in more detail
+- Made it possible to change resolution
+- Made many colors used by the game configurable
+- Made setup window available during login
+- Dynamically generate the item effects description
+- Minimap can now be told to stay on the screen
+- Minimap now adapts to the scale and size of the minimap image
+- Non-stackable items can now be sold more easily
+- Login dialog now remembers the list of recently used servers
+- Completely rewritten NPC interaction
+- GUI opacity now effects the whole user interface
+- Redesigned the trade window
+- Redesigned equipment window and allow unequip from there
+- Next level percentage is now displayed in hundredths
+- The player will no longer walk away when clicking the map while sitting
+- Keep the login screen from taking 100% CPU
+- No longer prompt for character server when there is only one
+- Fixed compilation with GCC 4.4
+- Fixed scroll wheel handling and dragging glitches in lists
+- Many more bug fixes, small improvements and code cleanups
+- Updated German, Finnish, Croatian, French, Spanish, Swedish and Polish
+ translations
+
+0.0.28.1 (12 February 2009)
+- Enabled translations on Windows
+- Added command line option to set home directory path
+- Tweaked green chat color to be a bit more readable
+- Made font size configurable in the config file
+- Fixed restoring of punching animation after weapon removal
+- Fixed inability to chat while talking to NPCs
+- Updated German, Spanish, Finnish, Swedish and Polish translations
+
+0.0.28 (25 January 2009)
+- Added support for animated map tiles
+- Added support for internationalization, plus many translations
+- Added support for TrueType fonts
+- Trade window is now resizable
+- Obscure precise home directory name when making screenshots
+- Fixed follow-parent of nested and being-following particle emitters
+
+0.0.27 (9 December 2008)
+- Added support for showing map name above minimap
+- Added showing how long the ban is when banned
+- Added --data parameter for developers
+- Added particle effect for critical hits
+- Added support for dynamic skill names and hair colors
+- Added support for status effects
+- Added ability to add equipment to the shortcut bar
+- Added ability to change configuration during login phase (from Aethyra)
+- Mouse cursor will now hide when not used for some time
+- Inventory window now displays amount of slots used
+- Center minimap on player when it is larger than the minimap window
+- Extended particle emitters with properties that can change over time
+- Extended the GUI font to support more characters
+- Only require a restart to switch to full screen with OpenGL on Windows
+- Make sure news and update file list aren't cached (from Aethyra)
+- Made NPC dialogs resizable (from Aethyra)
+- Made window shortcuts configurable
+- Fixed visibility of trade window on startup
+- Fixed a client input freeze when closing NPC script from server
+- Fixed dead players to lie on the ground instead of standing around
+- Fixed shortcuts being activated when trade window was visible
+- Fixed a crash when equipment window is open
+- Fixed money value on failing to buy (from Aethyra)
+- Fixed crash in right-click menu when used after a being disappeared
+
+0.0.26 (29 August 2008)
+- Added support for a newer version of eAthena server
+- Added support for showing custom being effects
+- Added new features to the particle engine
+- Position names and chat such that there is no overlap, when possible
+- Fixed a crash when loading a corrupt map that has too much layer data
+
+0.0.25 (27 July 2008)
+- Added support for whispering to other players
+- Added ability to ignore other players
+- Added command line argument for specifying the update host (-H)
+- Added support for receiving the update host from the server
+- Added support for displaying a shield sprite
+- Added shortcut window, allowing you to quickly access inventory items
+- Added message when gaining money from trade or quest
+- Added support for an arbitrary number of map layers
+- Added support for basing one sprite definition on another
+- Added the possibility to assign particle effects to NPCs
+- Added remembering whether windows are visible or not
+- Updated to work with Guichan 0.8.x
+- Improved accuracy of monster targeting with the mouse
+- Page up and page down will now scroll the chat window
+- Item icons are now loaded on demand and unloaded when no longer used
+- Fixed display of critical hits
+- Fixed multi-channel image dyeing
+- Fixed updating of money display after buying
+
+0.0.24.1 (7 April 2008)
+- Added /clear command to clear chat window
+- Added ability to close quit dialog by pressing ESC
+- Added key for targetting nearest player
+- Added the possibility to assign particle effects to monsters
+- Added possibility to pass through players with key controls
+- Fixed crash on exit after connection to server was lost
+- Fixed initialization of some variables
+- Fixed an error with chat messages without a sender that include a colon
+- Fixed minimap to not keep reappearing when hidden
+- Fixed a GCC 4.3 compile error
+- Fixed music loading from non-default location
+- Fixed crash on trying to show out of range emoticon
+- Updated Dev-C++ and Code::Blocks project files
+
+0.0.24 (24 December 2007)
+- Added female specific hair styles
+- Added user-definable key settings
+- Added XP gaining notification
+- Added close button to most windows
+- Added support for dynamic sprite recoloring
+- Added notification when the connection to the server is lost
+- Updated to work with Guichan 0.7.x
+- Mouse cursor now indicates when resize is possible
+- Changed amount slider in buy and sell dialogs to start at 1
+- Made weapon sprites and sounds customizable
+- Made buy and sell dialogs resizable
+- Merged equipment database with items database
+- Chat window log no longer goes back forever
+- Chat messages are trimmed (spaces are removed on both sides)
+- Fixed segmentation fault with some OpenGL drivers
+- Fixed updating of defense when increasing vitality
+- Fixed a bug that prevented being-controlled particles from being deleted
+- Fixed a crash in the particle engine related to child emitters
+- Fixed encoding issues with user home directory
+- Fixed a crash in equipment window on failure to load an item icon
+- Fixed a crash on filling up your inventory
+- Fixed item list in shops not to scroll back when selling
+
+0.0.23 (3 June 2007)
+- Added a particle engine along with some particle effects
+- Added a cursor to indicate targeted enemy
+- Added new program icon
+- Added a man page for UNIX like systems
+- Added the --version command line parameter
+- Improved MacOS X release
+- Screenshots are now saved in the .tmw directory on UNIX like systems
+- Magic pink is no longer used for transparency (fixes issues with that on Mac)
+- Fixed difficulties with resizing windows
+- Fixed misleading error message when connecting fails
+- Fixed wrong error message when account name already exists
+- Fixed crash when deleting a character
+- Fixed error message when creating a new character fails
+- Fixed updating problem when using scrollwheel to change shop selection
+
+0.0.22.2 (17 February 2007)
+- Updated to work with Guichan 0.6.1
+- Changed to new default server (server.themanaworld.org)
+- Changed custom mouse cursor
+- Fixed the issue where _M or _F is appended to the username
+- Fixed problem with Cancel button in update dialog
+
+0.0.22.1 (15 January 2007)
+- Updated to work with Guichan 0.6.0 (older versions no longer supported)
+- Fixed mouse coordinates in debug window
+- Fixed clicking on GUI to cause the player to start walking sometimes
+
+0.0.22 (24 December 2006)
+- Added support for female-specific equipment graphics
+- Added support for monster sounds
+- Added item icons to buy/sell dialogs
+- Enhanced character select dialog to show equipment
+- Changed to new update host (http://updates.themanaworld.org)
+- Worked around a Guichan exception thrown for mice with many buttons
+- Changed mouse walk to keep following mouse while button is held down
+- Extended font support for å and Å
+- Disabled RLE compression on all surfaces in software mode
+- Fixed joystick setting not to show disabled when it's actually enabled
+- Fixed money field to no longer hide below the bottom of the window
+- Fixed pathfinding to allow walking through beings when they block your path
+- Fixed an issue with NPC dialogs staying open after player respawn
+
+0.0.21.1 (30 October 2006)
+- Reload wallpaper after loading updates
+- Added support for gzip compressed map layer data
+- Added support for building with CMake
+- Added slider to setup dialog for configuring overlay effect
+- Fixed excessive unnecessary reloading of sprites
+- Fixed problem with OpenGL related redefinition
+- Fixed problems with hiding windows using h
+- Fixed trade window positioning
+
+0.0.21 (17 September 2006)
+- Added item pickup messages to the chat dialog
+- Added XP bar to ministatus in the top left
+- Added configurable smooth and lazy scrolling
+- Added option to turn off the joystick
+- Added --playername option for automatic character picking
+- Added --configfile option for specifying which configuration file to use
+- Added shortcut and middle mouse button for targetting nearest monster
+- Added support for map effect overlays
+- Fixed FPS limiter
+- Fixed updating system on Windows
+- Fixed player animations going out of sync on changing equipment or hairstyle
+- Fixed SDL_image configure check on some systems by first checking for libpng
+- Fixed big memory leak when using OpenGL
+- Updated to work with Guichan 0.5.0 (older versions no longer supported)
+
+0.0.20 (24 July 2006)
+- Added new hairstyle, and some fixes to the old ones
+- Added slider to set FPS limit
+- Added visible equipments
+- Added new maps and monsters
+- Added female characters
+- Implemented a new animation system
+- Updated the updating system
+- Reduced size of textures to stay within the limits of some OpenGL drivers
+- Fixed connection not being shut down completely in case of an error
+- Fixed min size of a window when resizing
+- Fixed some maps issues
+- Some fixes to monsters and player graphics
+- Minor bug fixes and lots of code cleanups
+
+0.0.19 (6 March 2006)
+- Added new playerset
+- Added --username, --password and --defaults command line options
+- Made the player walk to items prior to picking them up
+- Improved login sequence
+- Improved setup window and added a joystick calibration tool
+- Enabled 3 slots to create players
+- Reorganized and improved network code
+- Some maps fixes
+- Fixed some bugs
+- Lots of cleanups and code re-organization
+
+0.0.18.1 (30 December 2005)
+- Fixed a drawing glitch with high tiles at the bottom of the screen
+- Fixed glitches caused by fading out the damage display
+
+0.0.18 (20 December 2005)
+- Added new items, npcs, tilesets, maps and monsters
+- Non blocking connection at startup
+- Enabled monster emotions
+- Client version is now displayed during login
+- Fixed setup window behaviour
+- Fixed a Windows crash issue
+- Fixed ScrollArea and BrowserBox behaviour
+- Code cleanups
+
+0.0.17 (10 October 2005)
+- Added remembering of window position and sizes
+- Added taking screenshot with Alt+P
+- Added notice about the player being overweight
+- Added time to chat messages
+- Added messagebox on error for MacOS X
+- Added new network layer based on SDL_net
+- Added proper error message for when the map server goes offline
+- Added more international characters to fixed and rpg fonts
+- Improved damage text font, shadow is now translucent
+- Improved GUI layout, new profile window
+- Improved support for building on FreeBSD and MacOS X
+- Improved tile engine to fix graphics glitches and make mapping easier
+- Rearanged keyboard shortcuts
+- Fixed items on map to be removed on map switch
+- Fixed OpenGL checkbox in the setup window to be usable
+- Cleaned up a lot of code
+
+0.0.16 (04 September 2005)
+- Added inn and casino
+- Improved status window
+- Improved OpenGL support
+- Removed lot of bugs
+- Code cleanups
+
+0.0.15 (31 July 2005)
+- Added dynamic updating of client data
+- Added much better font for chat and names
+- Added option not to use the custom mouse cursor
+- Added joystick support
+- Improved mouse attack by not walking while pressing shift
+- Now one executable that has both SDL and OpenGL support
+- Fixed items being shown as equipped in inventory although they are not
+- Fixed position of right click menu
+- Fixed empty right click menu appearing sometimes
+
+0.0.14.1 (7 July 2005)
+- Fixed two map files not included in the source release
+
+0.0.14 (3 July 2005)
+- Added action menu (moved trading to action menu)
+- Added support for map properties
+- Added background image to minimap
+- Added background music to maps
+- Attempt to improve mouse control by left click auto-targetting
+- Fixed window resizing and also made chat window resizable
+- Fixed inventory item display not to be cut off
+- Fixed ghosts bug
+- Fixed fullscreen switch bug (OpenGL, win32)
+- Fixed unequip of weapon
+- Fixed equipping of picked up items
+- Fixed players to be able to see eachother attacking
+- Fixed maps to be loaded through resource manager
+
+0.0.13 (5 June 2005)
+- Added ability to trade items and money
+- Added server field to login dialog
+- Added item descriptions to inventory and buy/sell dialogs
+- Added confirmation dialog before quitting
+- Added button to show/hide equipment window
+- Added framerate limiter to config options
+- Added ability to auto attack
+- Added in-game help window
+- Added new hair style (mohawk)
+- Upgraded to Guichan 0.4.0
+- Dialogs are now modal when appropriate
+- Maximum item icon size changed to 32x32
+- Fixed a crash in OpenGL mode
+- Fixed rendering of minimap, progress bars and player sprite in OpenGL mode
+- Fixed 100% CPU usage when minimized
+- Fixed players not always appearing to sit when they are in fact sitting
+
+0.0.12 (1 May 2005)
+- Added new map (a cave), tiles, monsters and items
+- Added volume sliders in setup window
+- Added attack and level up samples
+- Added icon to application window
+- Added player names below players
+- Added register button in login screen
+- Added warning message to use at least 4 characters as user name
+- Added scrollbar and command history to chat window
+- Added proper support for installation of the game on *nix systems
+- Improved skin on scrollbars, arrows and slider
+- Improved sound engine and added fade in and out option for music
+- Now you can use right mouse button to attack (enables also ranged attacks)
+- Sound samples are now loaded through resource manager
+- Item information is now stored in an XML file
+- Monstersets are now loaded dynamically
+- Fixed crash when map server is down
+- Fixed NPC lists not to show garbage
+- Fixed attack animation to be synced with attack speed
+- Fixed speech and emoticons position
+- Fixed speech, damage and emoticon display to be framerate independent
+- Fixed rendering of certain monsters, items and NPCs in OpenGL mode
+- Fixed skipping with mouse walk and made interruptable with keyboard
+- Fixed mouse walk when dead or talking with NPC
+- Fixed log files to be created in ~/.tmw on Linux systems
+
+0.0.11.2 (8 April 2005)
+- Damage text now floats upwards
+- Mouse walk now only works with left mouse button
+- Fixed frequent crash on startup and exit that crept into 0.0.11.1
+
+0.0.11.1 (7 April 2005)
+- Buttons are now disabled when appropriate
+- Fixed players standing on top of NPCs
+- Fixed getting stuck when trying to sell with nothing to sell
+- Fixed setup dialog windowed/fullscreen switching behaviour
+- Fixed gui opacity slider (win32)
+- Fixed building up false inventory when warping
+- Fixed crash on startup with sound enabled (win32)
+
+0.0.11 (3 April 2005)
+- Added new maps, tiles and monsters
+- Added walking with mouse by clicking where you want to go
+- Added diagonal walking with keyboard
+- Added a choice dialog of how many items to drop
+- Added handling of window close button
+- Added config option for GUI opacity (guialpha)
+- Added warp between two maps
+- Changed chat entry behaviour to focus on enter and defocus on send message
+- Upgraded to Guichan 0.3.0
+- Chat now appears in a window
+- Beings now walk a lot smoother
+- Completed support for new map format (collision, compression)
+- Fixed problem where players would often turn up with black hair
+- Fixed not showing other players dead when they die
+- Fixed multiple crashes in being path handling
+- Fixed initial starting position for new player characters
+
+0.0.10 (5 March 2005)
+- Added using and dropping of items
+- Added experimental support for OpenGL rendering
+- Added support for new map format in client
+- Added ability to load resources from zip files
+- Added start of a minimap
+- Added new GUI skin, wallpaper and mouse cursor
+- Fixed and reintroduced cancel button for NPC choice dialog
+- Fixed character creation and deletion error handling
+- Fixed crash in fullscreen with hardware acceleration enabled (win32)
+- Fixed talking to NPCs and walking while NPC window is still open
+- Reimplemented A* pathfinding, more flexible and stable now
+- Removed background music that wasn't ours
+
+0.0.9 (30 Jan 2005)
+- Replaced Allegro library with SDL, SDL_image and SDL_mixer
+- A huge amount of small GUI improvements
+- Lots of internal changes including a resource manager
+
+0.0.8a (27 Dec 2004)
+- Added controlling player with arrow keys
+- Rewrote gui with Guichan
+- Added scripts for easy autotools
+
+0.0.8 (30 Oct 2004)
+- Added sound support for macosx
+- Added primitive inventory
+- Added action failed messages for all skills and known reasons (R 0x0110)
+- Added sit capability with the right level
+- Added "dead" message and restart packet
+- Added skill dialog
+- Added skill update (R 0x0141)
+- Added colored text for damage
+- Added monster death animation
+- Added icon to win32 executable
+- Added 'enter' key support in login screen
+- Added RLE sprites for tiles
+- Added collision detection with beings
+- Fix for mapserver segfault-bug in chatsystem (broken pipe for all users on
+ screen)
+- Partially added TMW GUI to inventory
+- Added soundpool that can preload, play and remove items to/from ram
+- Added tmw_bar_proc
+- Added tmw_plus_proc && possibility to increase stats point, at each new level
+- Added increase skill level dialog
+- Added 2xSaI engine
+- Added patch client v0.1 to Win32 version
+
+0.0.7e (31 Aug 2004)
+- Tons of bugfixes & improvements (again)
+- MacOS X support
+- Confirmed support for GNU/Linux on ppc
+- Added soundsystem (plays a MOD as BGM)
+- Added a 2nd Map
+- Added NPCs with simple dialogs
+- Added warps
+- Changed makefile for GCC to optimize more
+
+0.0.7d (18 Aug 2004)
+- Tons of bugfixes
+- Added a bit of prediction to player walking
+- Added Ultramichy's server to client
+- Added a walking monster
+- Added a* system (still not applied to player, but only to monster walking)
+- Started rewriting of chat system
+
+0.0.7c (22 Jul 2004)
+- Started rewriting of graphic engine
+- Fixed walking problems
+- Server: features a custom map
+
+0.0.7b (10 Jul 2004)
+- Completely rewrited network functions
+ - Removed listening thread
+ - Replaced blocking calls to socket
+ - Removed #pragma pack directives
+- Replaced MASkinG with own made GUI system
+- Finite state machine dialog system
+- Greatly reduced memory usage
+- Added a lot of comments to the code
+- Decreased the number of files in source code
+- The code is now a little more organized and easy to understand
+
+0.0.7a (30 Jun 2004)
+- Win32 binaries come with an installer
+- Renew login GUI:
+ - Change from dialogs to windows
+ - Add option to remember last login infos
+ - Add player creation dialog
+- Add NPC GUI
+
+0.0.7 (26 Jun 2004)
+- Some kind of multiplayer
+- Cross-compiler source code
+- Added setup utility
+- Minor changes
+- Bugfixes
+
+0.0.6a (13 Jun 2004)
diff --git a/README b/README
new file mode 100644
index 000000000..c1c8111ac
--- /dev/null
+++ b/README
@@ -0,0 +1,110 @@
+THE MANA CLIENT
+===============
+
+ Version: 1.0.0 Date: 2010-03-31
+
+ Development team:
+ - See AUTHORS file for a list
+
+ Powered by:
+
+ - SDL, SDL_image, SDL_mixer, SDL_ttf, SDL_net (Media framework)
+ - Guichan (GUI framework)
+ - libxml2 (XML parsing and writing)
+ - PhysFS (Data files)
+ - ENet (UDP networking library)
+ - libcurl (HTTP downloads)
+ - zlib (Archives)
+
+
+0. Index
+--------
+
+1. Account
+2. Commands
+3. Skills
+4. Support
+
+1. Account
+----------
+
+To create an account you can usually press the "Register" button after
+choosing your server. When this doesn't work, visit the website of the server
+you'd like to register on, since they may be using an online registration
+form instead.
+
+2. Commands
+-----------
+
+KEYBOARD:
+
+Use arrow keys to move around. Other keys:
+
+- Ctrl attack
+- F1 toggle the online help
+- F2 toggle profile window
+- F3 toggle inventory window
+- F4 toggle equipment window
+- F5 toggle skills window
+- F6 toggle minimap
+- F7 toggle chat window
+- F8 toggle shortcut window
+- F9 show setup window
+- F10 toggle debug window
+- Alt + 0-9 show emotions / usuable at skill level 2.
+- Alt + S sit down / stand up / usuable at skill level 3.
+- Alt + F toggle debug pathfinding feature
+- Alt + P take screenshot
+- Alt + T turns on anti-trade function / usuable at skill level 1.
+- A target nearest monster
+- H hide all non-sticky windows
+- G or Z pick up item
+- Enter focus chat window / send message
+
+MOUSE:
+
+Left click to execute default action: walk, pick up an item, attack a monster
+and talk to NPCs (be sure to click on their feet). Right click to show up a
+context menu. Holding [Left Shift] prevents from walking when attacking.
+
+/Commands:
+
+- /help Displays the list of commands
+- /announce broadcasts a global msg(Gm Cammand only)
+- /clear clears the chat window
+- /who shows how many players are online
+- /where displays the map name your currently on
+- /whisper send a private msg to another player
+ (format: /whisper <charname> <message>)
+ If the <nick> has spaces in it, enclose it in double
+ quotes e.g. /whisper "char name" <message>
+- /record Records the Chat output
+ (format: /record <filename to write to> starts the record
+ session /record again
+ stops the session)
+- /party <command> <params>: Party commands
+ - /party new creates a new party /party new <party name>
+ - /party create creates a new party /party create <party name>
+ - /party prefix This commands sets the party prefix character
+ /party prefix <prefix-char>
+ "/party prefix" reports the current party prefix
+ character
+ - /party leave This command causes the player to leave the party.
+Type /help party <option> for further help.
+- /present This command gets a list of players within hearing
+- /toggle make the chatlog lose focus on a blank line or after
+ message. (format: /toggle <option>, where option can be
+ '1', 'y' or 't' to make the chatlog lose focus on a
+ blank line, and '0', 'n' or 'f' to make the chatlog lose
+ focus after every message. /toggle displays the status)
+For more information, type /help <command>
+
+4. Support
+----------
+
+If you're having issues with this client, feel free to report them to us.
+There is a bug tracker at http://bugs.manasource.org/ and you can find us on
+IRC on irc.freenode.net in the #mana channel.
+
+If you have feedback about a specific game that uses the Mana client, be sure
+to contact the developers of the game instead.
diff --git a/README.cmake b/README.cmake
new file mode 100644
index 000000000..8471473f8
--- /dev/null
+++ b/README.cmake
@@ -0,0 +1,136 @@
+0. Contents
+------------
+ 1. Basic syntax
+ 2. How do I...
+ 3. Crosscompiling using CMake
+ 4. Creating an installer binary for Windows
+
+This readme explains the most common parameters to CMake needed for
+building mana, as well as setting up a cross build environement to
+create Windows builds.
+
+
+1. Basic syntax
+---------------
+
+cmake [options] <source directory>
+
+If you don't need any special options just change to the directory where
+you extracted the sources and do `cmake . && make'
+
+The syntax for setting variables to control CMakes behaviour is
+-D <variable>=<value>
+
+
+2. How do I...
+--------------
+
+- Use a custom install prefix (like --prefix on autoconf)?
+ CMAKE_INSTALL_PREFIX=/path/to/prefix
+- Create a debug build?
+ CMAKE_BUILD_TYPE=Debug .
+- Add additional package search directories?
+ CMAKE_PREFIX_PATH=/prefix/path
+- Add additional include search directories?
+ CMAKE_INCLUDE_PATH=/include/path
+
+For example, to build mana to install in /opt/mana, with libraries in
+/build/mana/lib, and SDL-headers in /build/mana/include/SDL you'd use
+the following command:
+
+cmake -D CMAKE_PREFIX_PATH=/build/mana \
+ -D CMAKE_INCLUDE_PATH=/build/mana/include/SDL \
+ -D CMAKE_INSTALL_PREFIX=/opt/mana .
+
+
+3. Crosscompiling using CMake
+-----------------------------
+
+The following example assumes you're doing a Windows-build from within a
+UNIX environement, using mingw32 installed in /build/mingw32.
+
+- create a toolchain-file describing your environement:
+$ cat /build/toolchain.cmake
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Windows)
+
+# toolchain prefix, can be overridden by -DTOOLCHAIN=...
+IF (NOT TOOLCHAIN)
+ SET(TOOLCHAIN "i386-mingw32-")
+ENDIF()
+
+# which compilers to use for C and C++
+SET(CMAKE_C_COMPILER ${TOOLCHAIN}gcc)
+SET(CMAKE_CXX_COMPILER ${TOOLCHAIN}g++)
+
+# here is the target environment located
+SET(CMAKE_FIND_ROOT_PATH /build/mingw32 /build/mana-libs )
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+
+- set your PATH to include the bin-directory of your mingw32-installation:
+$ export PATH=/build/mingw32/bin:$PATH
+
+- configure the source tree for the build, using the toolchain file:
+$ cmake -DCMAKE_TOOLCHAIN_FILE=/build/toolchain.cmake .
+
+- use make for building the application
+
+
+4. Creating an installer binary for Windows
+-------------------------------------------
+
+Call cmake with the following flags:
+
+ - CMAKE_TOOLCHAIN_FILE=/build/toolchain.cmake
+ The path to your toolchain file from chapter 3
+ - VERSION=$VERSION
+ The version number for the build, used to set client identification and
+ EXE meta information. Needs to be in the form Major.Minor.Release.Build
+ - CMAKE_BUILD_TYPE=RelWithDebInfo|Release
+ RelWithDebInfo is the prefered build type, as it provides some backtrace
+ information without blowing the binary up too much. Don't use Debug.
+
+Install nsis (on Debian, apt-get install nsis), and get the UnTGZ plugin:
+ http://nsis.sourceforge.net/UnTGZ_plug-in
+Place untgz.dll in nsis plugins directory (on Debian, /usr/share/nsis/Plugins/)
+
+Now chdir to packaging/windows. Make sure you have the msgfmt program (from
+gettext), and execute make-translations.sh to generate translations from the
+po-files in ../../translations/
+
+Check that you've got the translations, and call `makensis setup.nsi' with the
+following parameters:
+
+ -DDLLDIR=/build/mana-libs/lib/
+ The directory you've put the libraries. It's the one from the toolchain file
+ with /lib/ added at the end. If you'd like to include the Dr. MingW crash
+ handler place exchndl.dll in this directory.
+ -DPRODUCT_VERSION=$VERSION
+ Same as above
+ -DUPX=true
+ Set to upx if you'd like to compress the binaries using upx (and install upx,
+ of course). Will remove debug symbols.
+ -DEXESUFFIX=/src
+ Suffix to the source directory, pointing to the directory where the binaries
+ are. For cmake-builds that's /src.
+
+To build the installer for the 0.1.0.0 release you'd do the following:
+$ cmake -DVERSION=0.1.0.0 -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DCMAKE_TOOLCHAIN_FILE=/build/toolchain.cmake .
+[...]
+$ make
+[...]
+$ cd packaging/windows
+$ ./make-translations.sh
+[...]
+$ makensis -DDLLDIR=/build/mana-libs/lib/ -DPRODUCT_VERSION=0.1.0.0 \
+ -DUPX=true -DEXESUFFIX=/src setup.nsi
+
+and end up with the installer in mana-0.1.0.0-win32.exe
diff --git a/README.txt b/README.txt
new file mode 100644
index 000000000..b1cac9503
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,110 @@
+THE MANA CLIENT
+===============
+
+ Version: 1.0.0 Date: 2010-03-31
+
+ Development team:
+ - See AUTHORS file for a list
+
+ Powered by:
+
+ - SDL, SDL_image, SDL_mixer, SDL_ttf, SDL_net (Media framework)
+ - Guichan (GUI framework)
+ - libxml2 (XML parsing and writing)
+ - PhysFS (Data files)
+ - ENet (UDP networking library)
+ - libcurl (HTTP downloads)
+ - zlib (Archives)
+
+
+0. Index
+--------
+
+1. Account
+2. Commands
+3. Skills
+4. Support
+
+1. Account
+----------
+
+To create an account you can usually press the "Register" button after
+choosing your server. When this doesn't work, visit the website of the server
+you'd like to register on, since they may be using an online registration
+form instead.
+
+2. Commands
+-----------
+
+KEYBOARD:
+
+Use arrow keys to move around. Other keys:
+
+- Ctrl attack
+- F1 toggle the online help
+- F2 toggle profile window
+- F3 toggle inventory window
+- F4 toggle equipment window
+- F5 toggle skills window
+- F6 toggle minimap
+- F7 toggle chat window
+- F8 toggle shortcut window
+- F9 show setup window
+- F10 toggle debug window
+- Alt + 0-9 show emotions / usuable at skill level 2.
+- Alt + S sit down / stand up / usuable at skill level 3.
+- Alt + F toggle debug pathfinding feature
+- Alt + P take screenshot
+- Alt + T turns on anti-trade function / usuable at skill level 1.
+- A target nearest monster
+- H hide all non-sticky windows
+- G or Z pick up item
+- Enter focus chat window / send message
+
+MOUSE:
+
+Left click to execute default action: walk, pick up an item, attack a monster
+and talk to NPCs (be sure to click on their feet). Right click to show up a
+context menu. Holding [Left Shift] prevents from walking when attacking.
+
+/Commands:
+
+- /help Displays the list of commands
+- /announce broadcasts a global msg(Gm Cammand only)
+- /clear clears the chat window
+- /who shows how many players are online
+- /where displays the map name your currently on
+- /whisper send a private msg to another player
+ (format: /whisper <charname> <message>)
+ If the <nick> has spaces in it, enclose it in double
+ quotes e.g. /whisper "char name" <message>
+- /record Records the Chat output
+ (format: /record <filename to write to> starts the record
+ session /record again
+ stops the session)
+- /party <command> <params>: Party commands
+ - /party new creates a new party /party new <party name>
+ - /party create creates a new party /party create <party name>
+ - /party prefix This commands sets the party prefix character
+ /party prefix <prefix-char>
+ "/party prefix" reports the current party prefix
+ character
+ - /party leave This command causes the player to leave the party.
+Type /help party <option> for further help.
+- /present This command gets a list of players within hearing
+- /toggle make the chatlog lose focus on a blank line or after
+ message. (format: /toggle <option>, where option can be
+ '1', 'y' or 't' to make the chatlog lose focus on a
+ blank line, and '0', 'n' or 'f' to make the chatlog lose
+ focus after every message. /toggle displays the status)
+For more information, type /help <command>
+
+4. Support
+----------
+
+If you're having issues with this client, feel free to report them to us.
+There is a bug tracker at http://bugs.manasource.org/ and you can find us on
+IRC on irc.freenode.net in the #mana channel.
+
+If you have feedback about a specific game that uses the Mana client, be sure
+to contact the developers of the game instead.
diff --git a/SDLMain.nib/classes.nib b/SDLMain.nib/classes.nib
new file mode 100644
index 000000000..c4b887e72
--- /dev/null
+++ b/SDLMain.nib/classes.nib
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/SDLMain.nib/info.nib b/SDLMain.nib/info.nib
new file mode 100644
index 000000000..a753dd520
--- /dev/null
+++ b/SDLMain.nib/info.nib
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBFramework Version</key>
+ <string>670</string>
+ <key>IBLastKnownRelativeProjectPath</key>
+ <string>themanaworld.xcodeproj</string>
+ <key>IBOldestOS</key>
+ <integer>5</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>29</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>9F33</string>
+ <key>targetFramework</key>
+ <string>IBCarbonFramework</string>
+</dict>
+</plist>
diff --git a/SDLMain.nib/objects.xib b/SDLMain.nib/objects.xib
new file mode 100644
index 000000000..f4adb409e
--- /dev/null
+++ b/SDLMain.nib/objects.xib
@@ -0,0 +1,80 @@
+<?xml version="1.0" standalone="yes"?>
+<object class="NSIBObjectData">
+ <object name="rootObject" class="NSCustomObject" id="1">
+ </object>
+ <array count="8" name="allObjects">
+ <object class="IBCarbonMenu" id="184">
+ <string name="title">themanaworld</string>
+ <string name="name">_NSAppleMenu</string>
+ <array count="3" name="items">
+ <object class="IBCarbonMenuItem" id="187">
+ <string name="title">About themanaworld</string>
+ <int name="keyEquivalentModifier">0</int>
+ <ostype name="command">abou</ostype>
+ </object>
+ <object class="IBCarbonMenuItem" id="230">
+ <boolean name="separator">TRUE</boolean>
+ <boolean name="disabled">TRUE</boolean>
+ <boolean name="notPreviousAlternate">TRUE</boolean>
+ </object>
+ <object class="IBCarbonMenuItem" id="229">
+ <string name="title">Quit</string>
+ <string name="keyEquivalent">q</string>
+ <boolean name="notPreviousAlternate">TRUE</boolean>
+ <ostype name="command">quit</ostype>
+ </object>
+ </array>
+ </object>
+ <object class="IBCarbonWindow" id="166">
+ <boolean name="receiveUpdates">FALSE</boolean>
+ <boolean name="hasCloseBox">FALSE</boolean>
+ <boolean name="hasHorizontalZoom">FALSE</boolean>
+ <boolean name="isResizable">FALSE</boolean>
+ <boolean name="hasVerticalZoom">FALSE</boolean>
+ <boolean name="compositing">TRUE</boolean>
+ <boolean name="isConstrained">FALSE</boolean>
+ <string name="title">Window</string>
+ <object name="rootControl" class="IBCarbonRootControl" id="167">
+ <string name="viewFrame">0 0 800 600 </string>
+ <string name="bounds">0 0 600 800 </string>
+ </object>
+ <string name="windowRect">154 408 754 1208 </string>
+ <string name="ScreenRectAtEncodeTime">64 0 1028 1680 </string>
+ </object>
+ <object class="IBCarbonMenuItem" id="185">
+ <string name="title">The Mana World</string>
+ <reference name="submenu" idRef="184"/>
+ </object>
+ <reference idRef="167"/>
+ <reference idRef="187"/>
+ <object class="IBCarbonMenu" id="29">
+ <string name="title">main</string>
+ <string name="name">_NSMainMenu</string>
+ <array count="1" name="items">
+ <reference idRef="185"/>
+ </array>
+ </object>
+ <reference idRef="229"/>
+ <reference idRef="230"/>
+ </array>
+ <array count="8" name="allParents">
+ <reference idRef="185"/>
+ <reference idRef="1"/>
+ <reference idRef="29"/>
+ <reference idRef="166"/>
+ <reference idRef="184"/>
+ <reference idRef="1"/>
+ <reference idRef="184"/>
+ <reference idRef="184"/>
+ </array>
+ <dictionary count="3" name="nameTable">
+ <string>File&apos;s Owner</string>
+ <reference idRef="1"/>
+ <string>MainWindow</string>
+ <reference idRef="166"/>
+ <string>MenuBar</string>
+ <reference idRef="29"/>
+ </dictionary>
+ <string name="targetFramework">IBCarbonFramework</string>
+ <unsigned_int name="nextObjectID">231</unsigned_int>
+</object>
diff --git a/bcmake b/bcmake
new file mode 100755
index 000000000..64dab2116
--- /dev/null
+++ b/bcmake
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+export PATH=/usr/i586-mingw32msvc/bin:$PATH
+CXXFLAGS="-Wall -g0 -O2" cmake -DCMAKE_TOOLCHAIN_FILE=./toolchain.cmake .
+
+make -j5 2>make.log
+
diff --git a/bdeb.sh b/bdeb.sh
new file mode 100755
index 000000000..a09a29f0c
--- /dev/null
+++ b/bdeb.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+dpkg-buildpackage -rfakeroot -uc -b
diff --git a/bmake b/bmake
new file mode 100755
index 000000000..d62f4a23c
--- /dev/null
+++ b/bmake
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+#may be
+#-Wshadow -Waggregate-return -Winline
+
+#for feature
+#-Wstrict-overflow=4 -Wfloat-equal
+#-Wunsafe-loop-optimizations
+#-Wnon-virtual-dtor
+#-Woverloaded-virtual
+#-Wformat=2
+#-Wswitch-enum
+
+#for better code
+# -Weffc++
+
+#need fix: -Wold-style-cast -Wconversion
+#prof -pg
+
+dir=`pwd`
+
+export CC=gcc-4.5
+export CXX=g++-4.5
+
+export LANG=C
+export CXXFLAGS="-Wunreachable-code -Wmissing-field-initializers \
+-Wabi -Wdisabled-optimization -Wuninitialized \
+-Wvolatile-register-var -Winvalid-pch -Wredundant-decls \
+-Wnormalized=nfkc -Wmissing-format-attribute -Wmissing-noreturn \
+-Wswitch-default -Wsign-promo -Waddress -Wmissing-declarations \
+-Wctor-dtor-privacy -Wstrict-null-sentinel \
+-Wunused-parameter -Wlogical-op \
+-Wempty-body -Wsign-compare -Wclobbered -Wcast-align -Wcast-qual \
+-Wtype-limits -Wpointer-arith -Wundef -Wmissing-include-dirs \
+-Wignored-qualifiers -Winit-self -pedantic -Wall -ggdb3 -O2 -pipe"
+
+autoreconf -i
+./configure --prefix=$dir/run \
+ --datadir=$dir/run/share/games \
+ --bindir=$dir/run/bin \
+ --mandir=$dir/run/share/man
+
+cd po
+#make -j5 update-po 2>../make1.log
+make -j5 update-gmo 2>../make1.log
+cd ..
+make -j5 2>make2.log
+
diff --git a/configure.ac b/configure.ac
new file mode 100755
index 000000000..bb1085f77
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,166 @@
+AC_PREREQ(2.59)
+AC_INIT([ManaPlus], [1.0.0-beta2], [dev@manasource.org], [manaplus])
+AM_INIT_AUTOMAKE([1.9])
+AC_CONFIG_HEADERS([config.h:config.h.in])
+AC_LANG_CPLUSPLUS
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_INSTALL
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_TIME
+
+# Checks for library functions.
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_MALLOC
+AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([atexit floor getcwd gethostbyname memset mkdir select socket])
+
+# Checks for internationalization support
+AM_GNU_GETTEXT([external])
+AM_GNU_GETTEXT_VERSION([0.16.1])
+
+# Search for *-config
+AC_PATH_PROG(SDL_CONFIG, sdl-config)
+AC_PATH_PROG(PKG_CONFIG, pkg-config)
+AC_PATH_PROG(CURL_CONFIG, curl-config)
+
+# Checks for libraries
+AC_CHECK_LIB([pthread], [pthread_create], ,
+AC_MSG_ERROR([ *** Unable to find pthread library]))
+
+AC_CHECK_LIB([guichan], [gcnGuichanVersion], ,
+AC_MSG_ERROR([ *** Unable to find Guichan library (http://guichan.sf.net/)]))
+AC_CHECK_HEADERS([guichan.hpp], ,
+AC_MSG_ERROR([ *** Guichan library found but cannot find headers (http://guichan.sf.net/)]))
+
+AC_CHECK_HEADERS([guichan/widgetlistener.hpp], ,
+AC_MSG_ERROR([ *** Guichan library version is found but version is < 0.8.0 (http://guichan.sf.net/)]))
+
+if test -n "$SDL_CONFIG"; then
+ LIBS="$LIBS `$SDL_CONFIG --libs`"
+ CPPFLAGS="$CPPFLAGS `$SDL_CONFIG --cflags`"
+fi
+AC_CHECK_LIB([SDL], [SDL_Init], ,
+AC_MSG_ERROR([ *** Unable to find SDL library (http://www.libsdl.org/)]))
+AC_CHECK_HEADERS([SDL.h], ,
+AC_MSG_ERROR([ *** SDL library found but cannot find headers (http://www.libsdl.org/)]))
+
+AC_CHECK_LIB([z], [inflate], ,
+AC_MSG_ERROR([ *** Unable to find zlib (http://www.gzip.org/zlib/)]))
+
+AC_CHECK_LIB([physfs], [PHYSFS_init], ,
+AC_MSG_ERROR([ *** Unable to find PhysFS library (http://icculus.org/physfs/)]))
+AC_CHECK_HEADERS([physfs.h], ,
+AC_MSG_ERROR([ *** PhysFS library found but cannot find headers (http://icculus.org/physfs/)]))
+
+if test -n "$CURL_CONFIG"; then
+ LIBS="$LIBS `$CURL_CONFIG --libs`"
+ CPPFLAGS="$CPPFLAGS `$CURL_CONFIG --cflags`"
+fi
+AC_CHECK_LIB([curl], [curl_global_init], ,
+AC_MSG_ERROR([ *** Unable to find CURL library (http://curl.haxx.se/)]))
+AC_CHECK_HEADERS([curl/curl.h], ,
+AC_MSG_ERROR([ *** CURL library found but cannot find headers (http://curl.haxx.se/)]))
+
+if test -n "$PKG_CONFIG"; then
+ LIBS="$LIBS `$PKG_CONFIG --libs libxml-2.0`"
+ CPPFLAGS="$CPPFLAGS `$PKG_CONFIG --cflags libxml-2.0`"
+fi
+AC_CHECK_LIB([xml2], [xmlInitParser], ,
+AC_MSG_ERROR([ *** Unable to find libxml2 library (http://xmlsoft.org/)]))
+AC_CHECK_HEADERS([libxml/xmlreader.h], ,
+AC_MSG_ERROR([ *** libxml2 library found but cannot find headers (http://xmlsoft.org/)]))
+
+AC_CHECK_LIB(png, png_write_info, ,
+AC_MSG_ERROR([ *** Unable to find png library]))
+
+AC_CHECK_LIB(SDL_image, IMG_LoadPNG_RW, ,
+AC_MSG_ERROR([ *** Unable to find SDL_image library with PNG support
+(http://www.libsdl.org/projects/SDL_image/)]))
+
+AC_CHECK_LIB(SDL_ttf, TTF_Quit, ,
+AC_MSG_ERROR([ *** Unable to find SDL_ttf library (http://www.libsdl.org/projects/SDL_ttf/)]))
+
+AC_CHECK_LIB([SDL_mixer], [Mix_OpenAudio], ,
+AC_MSG_ERROR([ *** Unable to find SDL_mixer library (http://www.libsdl.org/projects/SDL_mixer/)]))
+
+AC_CHECK_LIB([guichan_sdl], [gcnSDL], ,
+AC_MSG_ERROR([ *** Unable to find Guichan SDL library (http://guichan.sf.net/)]))
+
+AC_CHECK_LIB(SDL_gfx, rotozoomSurfaceXY, ,
+AC_MSG_ERROR([ *** Unable to find SDL_gfx library (http://www.ferzkopp.net/joomla/software-mainmenu-14/4-ferzkopps-linux-software/19-sdlgfx)]))
+AC_CHECK_HEADERS(SDL_rotozoom.h, ,)
+
+# === Check for X11 (check borrowed from Wormux) ========================
+# Deactivated on purpose under OSX (in case X11 SDK is installed)
+if test "x$OSX" != "xyes" ; then
+ AC_CHECK_HEADER(X11/Xlib.h, check_x11="yes",check_x11="no")
+ if test x${check_x11} = xno ; then
+ AC_CHECK_HEADER(X11R6/Xlib.h,
+ [ check_x11="yes"
+ LDFLAGS="-L/usr/X11R6/include $CFLAGS"],
+ check_x11="no")
+ fi
+ if test x${check_x11} = xyes ; then
+ AC_CHECK_LIB(X11, XOpenDisplay,
+ [ LIBS="$LIBS -lX11"
+ AC_DEFINE(USE_X11, 1, [Define to use X11 copy'n'paste]) ],
+ [])
+ fi
+fi
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
+
+# Option to enable OpenGL
+AC_ARG_WITH(opengl,[ --without-opengl don't use OpenGL ] )
+if test "x$with_opengl" == "xno"; then
+ with_opengl=no
+else
+ with_opengl=yes
+ AC_CHECK_LIB([GL], [glBegin], ,
+ AC_MSG_ERROR([ *** Unable to find OpenGL library]))
+ AC_DEFINE(USE_OPENGL, 1, [Defines if Mana should have OpenGL support])
+fi
+
+AC_CHECK_LIB(SDL_net, SDLNet_Init, ,
+AC_MSG_ERROR([ *** Unable to find SDL_net library]))
+
+AC_CHECK_LIB(rt, shm_open, ,
+AC_MSG_ERROR([ *** Unable to find librt library]))
+
+AC_CONFIG_FILES([
+Makefile
+src/Makefile
+data/Makefile
+data/fonts/Makefile
+data/graphics/Makefile
+data/graphics/gui/Makefile
+data/graphics/images/Makefile
+data/graphics/sprites/Makefile
+data/sfx/Makefile
+data/sfx/system/Makefile
+data/themes/Makefile
+data/themes/blackwood/Makefile
+data/themes/classic/Makefile
+data/themes/enchilado/Makefile
+data/themes/redandblack/Makefile
+data/themes/wood/Makefile
+data/help/Makefile
+data/icons/Makefile
+docs/Makefile
+po/Makefile.in
+])
+
+AC_OUTPUT
+
+echo
+echo "Build with OpenGL: $with_opengl"
+echo
+echo "configure complete, now type \"make\""
+echo
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
new file mode 100644
index 000000000..968d926b3
--- /dev/null
+++ b/data/CMakeLists.txt
@@ -0,0 +1,9 @@
+SET(DATA_DIR ${PKG_DATADIR}/data)
+
+ADD_SUBDIRECTORY(fonts)
+ADD_SUBDIRECTORY(graphics)
+ADD_SUBDIRECTORY(help)
+ADD_SUBDIRECTORY(icons)
+ADD_SUBDIRECTORY(sfx)
+ADD_SUBDIRECTORY(themes)
+
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 000000000..82f0c768a
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,6 @@
+
+SUBDIRS = fonts graphics help icons sfx themes
+
+EXTRA_DIST = CMakeLists.txt
+
+manadatadir = $(pkgdatadir)/data
diff --git a/data/fonts/CMakeLists.txt b/data/fonts/CMakeLists.txt
new file mode 100644
index 000000000..636d474e8
--- /dev/null
+++ b/data/fonts/CMakeLists.txt
@@ -0,0 +1,12 @@
+SET (FILES
+ dejavusans.ttf
+ dejavusans-bold.ttf
+ dejavusansmono.ttf
+ dejavusansmono-bold.ttf
+ liberationsans.ttf
+ liberationsans-bold.ttf
+ liberationsansmono.ttf
+ liberationsansmono-bold.ttf
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/fonts)
diff --git a/data/fonts/Makefile.am b/data/fonts/Makefile.am
new file mode 100644
index 000000000..b28a11011
--- /dev/null
+++ b/data/fonts/Makefile.am
@@ -0,0 +1,15 @@
+fontsdir = $(pkgdatadir)/data/fonts
+
+fonts_DATA = \
+ dejavusans.ttf \
+ dejavusans-bold.ttf \
+ dejavusansmono.ttf \
+ dejavusansmono-bold.ttf \
+ liberationsans.ttf \
+ liberationsans-bold.ttf \
+ liberationsansmono.ttf \
+ liberationsansmono-bold.ttf
+
+EXTRA_DIST = \
+ $(fonts_DATA) \
+ CMakeLists.txt
diff --git a/data/fonts/dejavusans-bold.ttf b/data/fonts/dejavusans-bold.ttf
new file mode 100644
index 000000000..05673ed08
--- /dev/null
+++ b/data/fonts/dejavusans-bold.ttf
Binary files differ
diff --git a/data/fonts/dejavusans.ttf b/data/fonts/dejavusans.ttf
new file mode 100644
index 000000000..ff25017eb
--- /dev/null
+++ b/data/fonts/dejavusans.ttf
Binary files differ
diff --git a/data/fonts/dejavusansmono-bold.ttf b/data/fonts/dejavusansmono-bold.ttf
new file mode 100644
index 000000000..8d8e47bb9
--- /dev/null
+++ b/data/fonts/dejavusansmono-bold.ttf
Binary files differ
diff --git a/data/fonts/dejavusansmono.ttf b/data/fonts/dejavusansmono.ttf
new file mode 100644
index 000000000..899c7c1b4
--- /dev/null
+++ b/data/fonts/dejavusansmono.ttf
Binary files differ
diff --git a/data/fonts/liberationsans-bold.ttf b/data/fonts/liberationsans-bold.ttf
new file mode 100644
index 000000000..3ae183c9b
--- /dev/null
+++ b/data/fonts/liberationsans-bold.ttf
Binary files differ
diff --git a/data/fonts/liberationsans.ttf b/data/fonts/liberationsans.ttf
new file mode 100644
index 000000000..9dfc1e93a
--- /dev/null
+++ b/data/fonts/liberationsans.ttf
Binary files differ
diff --git a/data/fonts/liberationsansmono-bold.ttf b/data/fonts/liberationsansmono-bold.ttf
new file mode 100644
index 000000000..5178df87a
--- /dev/null
+++ b/data/fonts/liberationsansmono-bold.ttf
Binary files differ
diff --git a/data/fonts/liberationsansmono.ttf b/data/fonts/liberationsansmono.ttf
new file mode 100644
index 000000000..1cff69582
--- /dev/null
+++ b/data/fonts/liberationsansmono.ttf
Binary files differ
diff --git a/data/graphics/CMakeLists.txt b/data/graphics/CMakeLists.txt
new file mode 100644
index 000000000..a46ccfd0e
--- /dev/null
+++ b/data/graphics/CMakeLists.txt
@@ -0,0 +1,12 @@
+ADD_SUBDIRECTORY(gui)
+ADD_SUBDIRECTORY(images)
+ADD_SUBDIRECTORY(sprites)
+
+SET (FILES
+ target-cursor-in-range-l.png
+ target-cursor-in-range-m.png
+ target-cursor-in-range-s.png
+ target-cursor-normal-l.png
+ target-cursor-normal-m.png
+ target-cursor-normal-s.png
+ )
diff --git a/data/graphics/Makefile.am b/data/graphics/Makefile.am
new file mode 100644
index 000000000..d2f93f584
--- /dev/null
+++ b/data/graphics/Makefile.am
@@ -0,0 +1,16 @@
+
+graphicsdir = $(pkgdatadir)/data/graphics
+
+graphics_DATA = \
+ target-cursor-in-range-l.png \
+ target-cursor-in-range-m.png \
+ target-cursor-in-range-s.png \
+ target-cursor-normal-l.png \
+ target-cursor-normal-m.png \
+ target-cursor-normal-s.png
+
+EXTRA_DIST = \
+ $(graphics_DATA) \
+ CMakeLists.txt
+
+SUBDIRS = gui images sprites
diff --git a/data/graphics/gui/CMakeLists.txt b/data/graphics/gui/CMakeLists.txt
new file mode 100644
index 000000000..92a1e3efa
--- /dev/null
+++ b/data/graphics/gui/CMakeLists.txt
@@ -0,0 +1,48 @@
+SET (FILES
+ bubble.png
+ button.png
+ button_disabled.png
+ buttonhi.png
+ buttonpress.png
+ checkbox.png
+ circle-gray.png
+ circle-green.png
+ close_button.png
+ colors.xml
+ deepbox.png
+ hscroll_left_default.png
+ hscroll_left_highlight.png
+ hscroll_left_pressed.png
+ hscroll_right_default.png
+ hscroll_right_highlight.png
+ hscroll_right_pressed.png
+ item_shortcut_bgr.png
+ mouse.png
+ progress-indicator.png
+ radioin.png
+ radioin_highlight.png
+ radioout.png
+ radioout_highlight.png
+ resize.png
+ selection.png
+ slider.png
+ slider_hilight.png
+ speechbubble.xml
+ sticky_button.png
+ tab.png
+ tab_hilight.png
+ tabselected.png
+ unknown-item.png
+ vscroll_down_default.png
+ vscroll_down_highlight.png
+ vscroll_down_pressed.png
+ vscroll_grey.png
+ vscroll_highlight.png
+ vscroll_up_default.png
+ vscroll_up_highlight.png
+ vscroll_up_pressed.png
+ window.png
+ window.xml
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/graphics/gui)
diff --git a/data/graphics/gui/Makefile.am b/data/graphics/gui/Makefile.am
new file mode 100644
index 000000000..04f957b7f
--- /dev/null
+++ b/data/graphics/gui/Makefile.am
@@ -0,0 +1,52 @@
+
+guidir = $(pkgdatadir)/data/graphics/gui
+
+gui_DATA = \
+ bubble.png \
+ button.png \
+ button_disabled.png \
+ buttonhi.png \
+ buttonpress.png \
+ checkbox.png \
+ circle-gray.png \
+ circle-green.png \
+ close_button.png \
+ colors.xml \
+ deepbox.png \
+ hscroll_left_default.png \
+ hscroll_left_highlight.png \
+ hscroll_left_pressed.png \
+ hscroll_right_default.png \
+ hscroll_right_highlight.png \
+ hscroll_right_pressed.png \
+ item_shortcut_bgr.png \
+ mouse.png \
+ progress-indicator.png \
+ radioin.png \
+ radioin_highlight.png \
+ radioout.png \
+ radioout_highlight.png \
+ resize.png \
+ selection.png \
+ slider.png \
+ slider_hilight.png \
+ speechbubble.xml \
+ sticky_button.png \
+ tab.png \
+ tab_hilight.png \
+ tabselected.png \
+ unknown-item.png \
+ vscroll_down_default.png \
+ vscroll_down_highlight.png \
+ vscroll_down_pressed.png \
+ vscroll_grey.png \
+ vscroll_highlight.png \
+ vscroll_up_default.png \
+ vscroll_up_highlight.png \
+ vscroll_up_pressed.png \
+ window.png \
+ window.xml
+
+EXTRA_DIST = \
+ $(gui_DATA) \
+ CMakeLists.txt
diff --git a/data/graphics/gui/bubble.png b/data/graphics/gui/bubble.png
new file mode 100644
index 000000000..45322eb2e
--- /dev/null
+++ b/data/graphics/gui/bubble.png
Binary files differ
diff --git a/data/graphics/gui/button.png b/data/graphics/gui/button.png
new file mode 100644
index 000000000..9ebbea639
--- /dev/null
+++ b/data/graphics/gui/button.png
Binary files differ
diff --git a/data/graphics/gui/button_disabled.png b/data/graphics/gui/button_disabled.png
new file mode 100644
index 000000000..0ce3aa6ff
--- /dev/null
+++ b/data/graphics/gui/button_disabled.png
Binary files differ
diff --git a/data/graphics/gui/buttonhi.png b/data/graphics/gui/buttonhi.png
new file mode 100644
index 000000000..c47726346
--- /dev/null
+++ b/data/graphics/gui/buttonhi.png
Binary files differ
diff --git a/data/graphics/gui/buttonpress.png b/data/graphics/gui/buttonpress.png
new file mode 100644
index 000000000..e9cd17653
--- /dev/null
+++ b/data/graphics/gui/buttonpress.png
Binary files differ
diff --git a/data/graphics/gui/checkbox.png b/data/graphics/gui/checkbox.png
new file mode 100644
index 000000000..29b64100a
--- /dev/null
+++ b/data/graphics/gui/checkbox.png
Binary files differ
diff --git a/data/graphics/gui/circle-gray.png b/data/graphics/gui/circle-gray.png
new file mode 100644
index 000000000..3e884f405
--- /dev/null
+++ b/data/graphics/gui/circle-gray.png
Binary files differ
diff --git a/data/graphics/gui/circle-green.png b/data/graphics/gui/circle-green.png
new file mode 100644
index 000000000..2c98e9ef1
--- /dev/null
+++ b/data/graphics/gui/circle-green.png
Binary files differ
diff --git a/data/graphics/gui/close_button.png b/data/graphics/gui/close_button.png
new file mode 100644
index 000000000..f87cc2a91
--- /dev/null
+++ b/data/graphics/gui/close_button.png
Binary files differ
diff --git a/data/graphics/gui/colors.xml b/data/graphics/gui/colors.xml
new file mode 100644
index 000000000..b8bcdda8e
--- /dev/null
+++ b/data/graphics/gui/colors.xml
@@ -0,0 +1,53 @@
+<colors>
+ <color id="TEXT" color="#000000" />
+ <color id="SHADOW" color="#000000" />
+ <color id="OUTLINE" color="#000000" />
+ <color id="PROGRESS_BAR" color="#ffffff" />
+ <color id="BUTTON" color="#000000" />
+ <color id="BUTTON_DISABLED" color="#333333" />
+ <color id="TAB" color="#000000" />
+ <color id="PARTY_CHAT_TAB" color="#f48055" />
+ <color id="PARTY_SOCIAL_TAB" color="#ff00d8" />
+ <color id="GUILD_CHAT_TAB" color="#ff00d8" />
+ <color id="GUILD_SOCIAL_TAB" color="#ff00d8" />
+ <color id="BACKGROUND" color="#ffffff" />
+ <color id="HIGHLIGHT" color="#c0c0c0" />
+ <color id="TAB_FLASH" color="#ff0000" effect="pulse" />
+ <color id="TAB_PLAYER_FLASH" color="#00ff00" effect="pulse" />
+ <color id="SHOP_WARNING" color="#910000" />
+ <color id="ITEM_EQUIPPED" color="#000091" />
+ <color id="CHAT" color="#000000" />
+ <color id="GM" color="#ff0000" />
+ <color id="PLAYER" color="#1fa052" />
+ <color id="WHISPER" color="#0000ff" />
+ <color id="WHISPER_OFFLINE" color="#000050" />
+ <color id="IS" color="#a08527" />
+ <color id="SERVER" color="#8415e2" />
+ <color id="LOGGER" color="#919191" />
+ <color id="HYPERLINK" color="#e50d0d" />
+ <color id="UNKNOWN_ITEM" color="#000000" />
+ <color id="GENERIC" color="#21a5b1" />
+ <color id="HEAD" color="#527fa4" />
+ <color id="USABLE" color="#268d24" />
+ <color id="TORSO" color="#d12aa4" />
+ <color id="ONEHAND" color="#f42a2a" />
+ <color id="LEGS" color="#699900" />
+ <color id="FEET" color="#aa1d48" />
+ <color id="TWOHAND" color="#f46d0e" />
+ <color id="SHIELD" color="#9c2424" />
+ <color id="RING" color="#0000ff" />
+ <color id="NECKLACE" color="#ff00ff" />
+ <color id="ARMS" color="#9c24e8" />
+ <color id="AMMO" color="#8b6311" />
+ <color id="SERVER_VERSION_NOT_SUPPORTED" color="#DC0000" />
+ <color id="WARNING" color="#FF0000" />
+
+ <progressbar id="DEFAULT" color="#969696" />
+ <progressbar id="HP" color="#ff0000,e28000,c38948,0f6a20" />
+ <progressbar id="MP" color="#1a66e6" />
+ <progressbar id="NO_MP" color="#646464" />
+ <progressbar id="EXP" color="#8fc0d3" />
+ <progressbar id="INVY_SLOTS" color="#e1c819" />
+ <progressbar id="WEIGHT" color="#0000ff,ffff00,ff0000" />
+ <progressbar id="JOB" color="#e187cb" />
+</colors>
diff --git a/data/graphics/gui/deepbox.png b/data/graphics/gui/deepbox.png
new file mode 100644
index 000000000..084b5f618
--- /dev/null
+++ b/data/graphics/gui/deepbox.png
Binary files differ
diff --git a/data/graphics/gui/hscroll_left_default.png b/data/graphics/gui/hscroll_left_default.png
new file mode 100644
index 000000000..2f763d302
--- /dev/null
+++ b/data/graphics/gui/hscroll_left_default.png
Binary files differ
diff --git a/data/graphics/gui/hscroll_left_highlight.png b/data/graphics/gui/hscroll_left_highlight.png
new file mode 100644
index 000000000..6be5ae259
--- /dev/null
+++ b/data/graphics/gui/hscroll_left_highlight.png
Binary files differ
diff --git a/data/graphics/gui/hscroll_left_pressed.png b/data/graphics/gui/hscroll_left_pressed.png
new file mode 100644
index 000000000..b8ebcb463
--- /dev/null
+++ b/data/graphics/gui/hscroll_left_pressed.png
Binary files differ
diff --git a/data/graphics/gui/hscroll_right_default.png b/data/graphics/gui/hscroll_right_default.png
new file mode 100644
index 000000000..33fdddd0a
--- /dev/null
+++ b/data/graphics/gui/hscroll_right_default.png
Binary files differ
diff --git a/data/graphics/gui/hscroll_right_highlight.png b/data/graphics/gui/hscroll_right_highlight.png
new file mode 100644
index 000000000..e9e633eac
--- /dev/null
+++ b/data/graphics/gui/hscroll_right_highlight.png
Binary files differ
diff --git a/data/graphics/gui/hscroll_right_pressed.png b/data/graphics/gui/hscroll_right_pressed.png
new file mode 100644
index 000000000..53972f2bb
--- /dev/null
+++ b/data/graphics/gui/hscroll_right_pressed.png
Binary files differ
diff --git a/data/graphics/gui/item_shortcut_bgr.png b/data/graphics/gui/item_shortcut_bgr.png
new file mode 100644
index 000000000..0543e38ac
--- /dev/null
+++ b/data/graphics/gui/item_shortcut_bgr.png
Binary files differ
diff --git a/data/graphics/gui/mouse.png b/data/graphics/gui/mouse.png
new file mode 100644
index 000000000..df460e49c
--- /dev/null
+++ b/data/graphics/gui/mouse.png
Binary files differ
diff --git a/data/graphics/gui/progress-indicator.png b/data/graphics/gui/progress-indicator.png
new file mode 100644
index 000000000..907f334eb
--- /dev/null
+++ b/data/graphics/gui/progress-indicator.png
Binary files differ
diff --git a/data/graphics/gui/radioin.png b/data/graphics/gui/radioin.png
new file mode 100644
index 000000000..12e027fec
--- /dev/null
+++ b/data/graphics/gui/radioin.png
Binary files differ
diff --git a/data/graphics/gui/radioin_highlight.png b/data/graphics/gui/radioin_highlight.png
new file mode 100644
index 000000000..b193d3e30
--- /dev/null
+++ b/data/graphics/gui/radioin_highlight.png
Binary files differ
diff --git a/data/graphics/gui/radioout.png b/data/graphics/gui/radioout.png
new file mode 100644
index 000000000..5eb67bd85
--- /dev/null
+++ b/data/graphics/gui/radioout.png
Binary files differ
diff --git a/data/graphics/gui/radioout_highlight.png b/data/graphics/gui/radioout_highlight.png
new file mode 100644
index 000000000..dd31e6e30
--- /dev/null
+++ b/data/graphics/gui/radioout_highlight.png
Binary files differ
diff --git a/data/graphics/gui/resize.png b/data/graphics/gui/resize.png
new file mode 100644
index 000000000..6b31ac64b
--- /dev/null
+++ b/data/graphics/gui/resize.png
Binary files differ
diff --git a/data/graphics/gui/selection.png b/data/graphics/gui/selection.png
new file mode 100644
index 000000000..78827dafa
--- /dev/null
+++ b/data/graphics/gui/selection.png
Binary files differ
diff --git a/data/graphics/gui/slider.png b/data/graphics/gui/slider.png
new file mode 100644
index 000000000..465ad0e88
--- /dev/null
+++ b/data/graphics/gui/slider.png
Binary files differ
diff --git a/data/graphics/gui/slider_hilight.png b/data/graphics/gui/slider_hilight.png
new file mode 100644
index 000000000..37c780cd1
--- /dev/null
+++ b/data/graphics/gui/slider_hilight.png
Binary files differ
diff --git a/data/graphics/gui/speechbubble.xml b/data/graphics/gui/speechbubble.xml
new file mode 100644
index 000000000..84b6557b3
--- /dev/null
+++ b/data/graphics/gui/speechbubble.xml
@@ -0,0 +1,18 @@
+<skinset name="SpeechBubble" image="bubble.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="5" height="5" />
+ <part type="top-edge" xpos="5" ypos="0" width="5" height="5" />
+ <part type="top-right-corner" xpos="10" ypos="0" width="5" height="5" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="5" width="5" height="5" />
+ <part type="bg-quad" xpos="5" ypos="5" width="5" height="5" />
+ <part type="right-edge" xpos="10" ypos="5" width="5" height="5" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="10" width="5" height="5" />
+ <part type="bottom-edge" xpos="5" ypos="10" width="5" height="5" />
+ <part type="bottom-right-corner" xpos="10" ypos="10" width="5" height="5" />
+ </widget>
+</skinset>
diff --git a/data/graphics/gui/sticky_button.png b/data/graphics/gui/sticky_button.png
new file mode 100644
index 000000000..8c5705736
--- /dev/null
+++ b/data/graphics/gui/sticky_button.png
Binary files differ
diff --git a/data/graphics/gui/tab.png b/data/graphics/gui/tab.png
new file mode 100644
index 000000000..91eadf08f
--- /dev/null
+++ b/data/graphics/gui/tab.png
Binary files differ
diff --git a/data/graphics/gui/tab_hilight.png b/data/graphics/gui/tab_hilight.png
new file mode 100644
index 000000000..f6b39942d
--- /dev/null
+++ b/data/graphics/gui/tab_hilight.png
Binary files differ
diff --git a/data/graphics/gui/tabselected.png b/data/graphics/gui/tabselected.png
new file mode 100644
index 000000000..e2983060c
--- /dev/null
+++ b/data/graphics/gui/tabselected.png
Binary files differ
diff --git a/data/graphics/gui/unknown-item.png b/data/graphics/gui/unknown-item.png
new file mode 100644
index 000000000..9201d688e
--- /dev/null
+++ b/data/graphics/gui/unknown-item.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_down_default.png b/data/graphics/gui/vscroll_down_default.png
new file mode 100644
index 000000000..c4292489e
--- /dev/null
+++ b/data/graphics/gui/vscroll_down_default.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_down_highlight.png b/data/graphics/gui/vscroll_down_highlight.png
new file mode 100644
index 000000000..ac88f7c73
--- /dev/null
+++ b/data/graphics/gui/vscroll_down_highlight.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_down_pressed.png b/data/graphics/gui/vscroll_down_pressed.png
new file mode 100644
index 000000000..9dcc89f6f
--- /dev/null
+++ b/data/graphics/gui/vscroll_down_pressed.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_grey.png b/data/graphics/gui/vscroll_grey.png
new file mode 100644
index 000000000..f99da4676
--- /dev/null
+++ b/data/graphics/gui/vscroll_grey.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_highlight.png b/data/graphics/gui/vscroll_highlight.png
new file mode 100644
index 000000000..2e0fcbfc1
--- /dev/null
+++ b/data/graphics/gui/vscroll_highlight.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_up_default.png b/data/graphics/gui/vscroll_up_default.png
new file mode 100644
index 000000000..1cecc3512
--- /dev/null
+++ b/data/graphics/gui/vscroll_up_default.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_up_highlight.png b/data/graphics/gui/vscroll_up_highlight.png
new file mode 100644
index 000000000..7b5009f39
--- /dev/null
+++ b/data/graphics/gui/vscroll_up_highlight.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_up_pressed.png b/data/graphics/gui/vscroll_up_pressed.png
new file mode 100644
index 000000000..2320ec42f
--- /dev/null
+++ b/data/graphics/gui/vscroll_up_pressed.png
Binary files differ
diff --git a/data/graphics/gui/window.png b/data/graphics/gui/window.png
new file mode 100644
index 000000000..f0ef1af4b
--- /dev/null
+++ b/data/graphics/gui/window.png
Binary files differ
diff --git a/data/graphics/gui/window.xml b/data/graphics/gui/window.xml
new file mode 100644
index 000000000..f27dbc7f3
--- /dev/null
+++ b/data/graphics/gui/window.xml
@@ -0,0 +1,18 @@
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="4" height="4" />
+ <part type="top-edge" xpos="4" ypos="0" width="32" height="4" />
+ <part type="top-right-corner" xpos="36" ypos="0" width="4" height="4" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="4" width="4" height="216" />
+ <part type="bg-quad" xpos="4" ypos="4" width="32" height="216" />
+ <part type="right-edge" xpos="36" ypos="4" width="4" height="216" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="220" width="4" height="4" />
+ <part type="bottom-edge" xpos="4" ypos="220" width="32" height="4" />
+ <part type="bottom-right-corner" xpos="36" ypos="220" width="4" height="4" />
+ </widget>
+</skinset>
diff --git a/data/graphics/images/CMakeLists.txt b/data/graphics/images/CMakeLists.txt
new file mode 100644
index 000000000..5181b4e11
--- /dev/null
+++ b/data/graphics/images/CMakeLists.txt
@@ -0,0 +1,6 @@
+SET(FILES
+ error.png
+ login_wallpaper.png
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/graphics/images)
diff --git a/data/graphics/images/Makefile.am b/data/graphics/images/Makefile.am
new file mode 100644
index 000000000..09e7c3171
--- /dev/null
+++ b/data/graphics/images/Makefile.am
@@ -0,0 +1,9 @@
+imagesdir = $(pkgdatadir)/data/graphics/images
+
+images_DATA = \
+ error.png \
+ login_wallpaper.png
+
+EXTRA_DIST = \
+ $(images_DATA) \
+ CMakeLists.txt
diff --git a/data/graphics/images/error.png b/data/graphics/images/error.png
new file mode 100644
index 000000000..6fd7c1a8d
--- /dev/null
+++ b/data/graphics/images/error.png
Binary files differ
diff --git a/data/graphics/images/login_wallpaper.png b/data/graphics/images/login_wallpaper.png
new file mode 100644
index 000000000..109acccd5
--- /dev/null
+++ b/data/graphics/images/login_wallpaper.png
Binary files differ
diff --git a/data/graphics/sprites/CMakeLists.txt b/data/graphics/sprites/CMakeLists.txt
new file mode 100644
index 000000000..eb3802d13
--- /dev/null
+++ b/data/graphics/sprites/CMakeLists.txt
@@ -0,0 +1,13 @@
+SET(FILES
+ arrow_up.gif
+ arrow_down.gif
+ arrow_left.gif
+ arrow_right.gif
+ error.png
+ error.xml
+ manaplus_emotions.png
+ manaplus_emote.xml
+ manaplus_emotes.xml
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/graphics/sprites)
diff --git a/data/graphics/sprites/Makefile.am b/data/graphics/sprites/Makefile.am
new file mode 100644
index 000000000..8cf8cfb49
--- /dev/null
+++ b/data/graphics/sprites/Makefile.am
@@ -0,0 +1,16 @@
+spritesdir = $(pkgdatadir)/data/graphics/sprites
+
+sprites_DATA = \
+ arrow_down.gif \
+ arrow_left.gif \
+ arrow_right.gif \
+ arrow_up.gif \
+ error.png \
+ error.xml \
+ manaplus_emotions.png\
+ manaplus_emote.xml \
+ manaplus_emotes.xml
+
+EXTRA_DIST = \
+ $(sprites_DATA) \
+ CMakeLists.txt
diff --git a/data/graphics/sprites/arrow_down.gif b/data/graphics/sprites/arrow_down.gif
new file mode 100644
index 000000000..e371b0892
--- /dev/null
+++ b/data/graphics/sprites/arrow_down.gif
Binary files differ
diff --git a/data/graphics/sprites/arrow_left.gif b/data/graphics/sprites/arrow_left.gif
new file mode 100644
index 000000000..29ea8bcd9
--- /dev/null
+++ b/data/graphics/sprites/arrow_left.gif
Binary files differ
diff --git a/data/graphics/sprites/arrow_right.gif b/data/graphics/sprites/arrow_right.gif
new file mode 100644
index 000000000..e5c7d3038
--- /dev/null
+++ b/data/graphics/sprites/arrow_right.gif
Binary files differ
diff --git a/data/graphics/sprites/arrow_up.gif b/data/graphics/sprites/arrow_up.gif
new file mode 100644
index 000000000..655e5bf40
--- /dev/null
+++ b/data/graphics/sprites/arrow_up.gif
Binary files differ
diff --git a/data/graphics/sprites/error.png b/data/graphics/sprites/error.png
new file mode 100644
index 000000000..6fd7c1a8d
--- /dev/null
+++ b/data/graphics/sprites/error.png
Binary files differ
diff --git a/data/graphics/sprites/error.xml b/data/graphics/sprites/error.xml
new file mode 100644
index 000000000..3504bd016
--- /dev/null
+++ b/data/graphics/sprites/error.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<sprite>
+ <imageset name="base" src="graphics/sprites/error.png" width="29" height="9" />
+
+ <action name="default" imageset="base">
+ <animation direction="default">
+ <frame index="0" />
+ </animation>
+ </action>
+</sprite> \ No newline at end of file
diff --git a/data/graphics/sprites/manaplus_emote.xml b/data/graphics/sprites/manaplus_emote.xml
new file mode 100644
index 000000000..6fa884e40
--- /dev/null
+++ b/data/graphics/sprites/manaplus_emote.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<sprite variants="20" variant_offset="1">
+ <imageset name="base" src="graphics/sprites/manaplus_emotions.png" width="30" height="32" />
+
+ <action name="stand" imageset="base">
+ <animation direction="default">
+ <frame index="0" />
+ </animation>
+ </action>
+</sprite>
diff --git a/data/graphics/sprites/manaplus_emotes.xml b/data/graphics/sprites/manaplus_emotes.xml
new file mode 100644
index 000000000..eca7bf722
--- /dev/null
+++ b/data/graphics/sprites/manaplus_emotes.xml
@@ -0,0 +1,22 @@
+<emotes>
+ <emote id="100"><sprite name="Kitty" variant="0">manaplus_emote.xml</sprite></emote>
+ <emote id="101"><sprite name="xD" variant="1">manaplus_emote.xml</sprite></emote>
+ <emote id="102"><sprite name="^.^" variant="2">manaplus_emote.xml</sprite></emote>
+ <emote id="103"><sprite name="Heart eye" variant="3">manaplus_emote.xml</sprite></emote>
+ <emote id="104"><sprite name="Gold eye" variant="4">manaplus_emote.xml</sprite></emote>
+ <emote id="105"><sprite name="Sleepy" variant="5">manaplus_emote.xml</sprite></emote>
+ <emote id="106"><sprite name="u.u" variant="6">manaplus_emote.xml</sprite></emote>
+ <emote id="107"><sprite name="-.-'" variant="7">manaplus_emote.xml</sprite></emote>
+ <emote id="108"><sprite name="Suprised" variant="8">manaplus_emote.xml</sprite></emote>
+ <emote id="109"><sprite name="Dead" variant="9">manaplus_emote.xml</sprite></emote>
+ <emote id="110"><sprite name="Look away" variant="10">manaplus_emote.xml</sprite></emote>
+ <emote id="111"><sprite name="Sad" variant="11">manaplus_emote.xml</sprite></emote>
+ <emote id="112"><sprite name="Palmhead" variant="12">manaplus_emote.xml</sprite></emote>
+ <emote id="113"><sprite name="Evil" variant="13">manaplus_emote.xml</sprite></emote>
+ <emote id="114"><sprite name="Angry" variant="14">manaplus_emote.xml</sprite></emote>
+ <emote id="115"><sprite name="Purple Sad" variant="15">manaplus_emote.xml</sprite></emote>
+ <emote id="116"><sprite name="Insult Buble" variant="16">manaplus_emote.xml</sprite></emote>
+ <emote id="117"><sprite name="Heart" variant="17">manaplus_emote.xml</sprite></emote>
+ <emote id="118"><sprite name="Emote" variant="18">manaplus_emote.xml</sprite></emote>
+ <emote id="119"><sprite name="Pumpkin" variant="19">manaplus_emote.xml</sprite></emote>
+</emotes>
diff --git a/data/graphics/sprites/manaplus_emotions.png b/data/graphics/sprites/manaplus_emotions.png
new file mode 100644
index 000000000..ce6e2cdfc
--- /dev/null
+++ b/data/graphics/sprites/manaplus_emotions.png
Binary files differ
diff --git a/data/graphics/target-cursor-in-range-l.png b/data/graphics/target-cursor-in-range-l.png
new file mode 100644
index 000000000..77cdf4b6d
--- /dev/null
+++ b/data/graphics/target-cursor-in-range-l.png
Binary files differ
diff --git a/data/graphics/target-cursor-in-range-m.png b/data/graphics/target-cursor-in-range-m.png
new file mode 100644
index 000000000..c0107357a
--- /dev/null
+++ b/data/graphics/target-cursor-in-range-m.png
Binary files differ
diff --git a/data/graphics/target-cursor-in-range-s.png b/data/graphics/target-cursor-in-range-s.png
new file mode 100644
index 000000000..3e81c75de
--- /dev/null
+++ b/data/graphics/target-cursor-in-range-s.png
Binary files differ
diff --git a/data/graphics/target-cursor-normal-l.png b/data/graphics/target-cursor-normal-l.png
new file mode 100644
index 000000000..76d2101b1
--- /dev/null
+++ b/data/graphics/target-cursor-normal-l.png
Binary files differ
diff --git a/data/graphics/target-cursor-normal-m.png b/data/graphics/target-cursor-normal-m.png
new file mode 100644
index 000000000..e2ab79c29
--- /dev/null
+++ b/data/graphics/target-cursor-normal-m.png
Binary files differ
diff --git a/data/graphics/target-cursor-normal-s.png b/data/graphics/target-cursor-normal-s.png
new file mode 100644
index 000000000..09195f440
--- /dev/null
+++ b/data/graphics/target-cursor-normal-s.png
Binary files differ
diff --git a/data/help/CMakeLists.txt b/data/help/CMakeLists.txt
new file mode 100644
index 000000000..82f61d54f
--- /dev/null
+++ b/data/help/CMakeLists.txt
@@ -0,0 +1,12 @@
+SET(FILES
+ about.txt
+ changes.txt
+ commands.txt
+ header.txt
+ index.txt
+ skills.txt
+ support.txt
+ team.txt
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/help)
diff --git a/data/help/Makefile.am b/data/help/Makefile.am
new file mode 100644
index 000000000..5abd27359
--- /dev/null
+++ b/data/help/Makefile.am
@@ -0,0 +1,16 @@
+
+helpdir = $(pkgdatadir)/data/help
+
+help_DATA = \
+ about.txt \
+ changes.txt \
+ commands.txt \
+ header.txt \
+ index.txt \
+ skills.txt \
+ support.txt \
+ team.txt
+
+EXTRA_DIST = \
+ $(help_DATA) \
+ CMakeLists.txt
diff --git a/data/help/about.txt b/data/help/about.txt
new file mode 100644
index 000000000..c4dc0e3d3
--- /dev/null
+++ b/data/help/about.txt
@@ -0,0 +1,16 @@
+ <- @@index|Back to Index@@
+
+
+##3 === ABOUT MANA ===
+
+ ##2Mana##P is a serious effort to create an innovative free and open
+ source MMORPG Client. Mana uses 2D graphics and aims to create a large
+ and diverse interactive world. It is licensed under the GPL, making
+ sure this game can't ever run away from you.
+
+ The project includes the development of both a client and a server.
+ Others are making worlds using Mana software. The Mana World project
+ is the originator of the Mana project. Mana was split off to further
+ facilitate development of other worlds.
+
+ ##2ManaPlus##P is extended client.
diff --git a/data/help/changes.txt b/data/help/changes.txt
new file mode 100644
index 000000000..eae2f5689
--- /dev/null
+++ b/data/help/changes.txt
@@ -0,0 +1,885 @@
+ <- @@index|Back to Index@@
+
+
+##3 === RECENT CHANGES ===
+
+
+The Mana World 4144 patches (ManaPlus)
+
+2010-09-19 New release 1.0.9.19.
+New features:
+
+ManaPlus:
+fix: improve chat resize speed.
+fix: invisible objects with disabled opengl, like pinkies.
+fix: resize windows from top corners.
+add: opacity cache to improve game speed with disabled opengl.
+Warning: some times it may crash client.
+To enable SET \ Video \ Enable opacity cache.
+add: increase outfits count from 80 to 100.
+add: increase outfit slots from 9 to 12.
+add: support zip archives in per server local updates dir.
+add: support update patches zips.
+in this dir local resources can have bigger priority over resources from update server.
+Example dir in linux: ~/.local/share/mana/updates/updates.themanaworld.org/fix/
+In this directory you can place http://tmw.cetki.com/other/update-96b7ecd..eeac43f.zip to fix moggun issue.
+add: moving windows by dragging window from any empty space.
+add: option to disable/enable attack while moving.
+add: context menu in who is online window.
+add: updated russian translation.
+
+
+2010-09-12 release 1.0.9.12.
+New features:
+
+ManaPlus:
+fix: set map arrows.
+fix: draw map arrows.
+fix: improved chat draw speed.
+fix: improved game speed.
+add: /undress chat command and popup menu item.
+This command remove all clothes from selected player. This changes only local.
+add: /attack chat command.
+add: icons to spells / text commands.
+add: /outfit next, /outfit prev commands.
+add: /dirs chat command to show game dirs.
+
+
+2010-09-04 release 1.0.9.4.
+New features:
+
+ManaPlus:
+fix: updating servers list.
+fix: warp removing from map.
+fix: in away mode drop fps only if game inactive.
+fix: crash on exit on tmw server.
+add: server side attack mode.
+add: free camera mode ([+]).
+In this mode camera can be moved by cursor keys.
+add: draw screen border in minimap.
+add: play sound if you receive global message and game inactive.
+add: dont highlight party tab if got server message on it.
+add: change color on players, who attacking local player.
+add: place away dialog on top of screen.
+add: option to disable auto fix position.
+Mana:
+fix: focus on char select dialog.
+
+
+2010-08-29 release 1.0.8.29.
+New features:
+
+ManaPlus:
+fix: walk between maps in e map modes.
+fix: funny symbols and item links.
+fix: visible names option.
+fix: trying avoid server packets bug also in default attack mode.
+fix: changed attack time limit to avoid new server bugs.
+fix: disable hot keys in npc input dialogs.
+fix: crash if client have some corrupted images.
+fix: compilation for gcc 4.5.
+fix: compilation with flag --without-opengl.
+add: new map mode. symbol b. (f)
+add: removed length limit in build walk path.
+add: play whisper sound if new message in active whisper and game not active.
+add: navigation tab in social window.
+left click go to selected target.
+add: key to move to location from navigation tab in social window (RSHIFT + 0-9)
+Key like outfits but only mod key is right shift.
+add: show items refine level.
+add: continue attack if player moved.
+add: attack target after moving to it by attack key (x).
+add: switching to already opened whisper tab.
+add: per server local updates dir.
+in this dir can be placed local resources.
+Example dir in linux: ~/.local/share/mana/updates/updates.themanaworld.org/local/
+
+
+2010-08-15 release 1.0.8.15.
+Download Compile in Ubuntu
+
+New features:
+
+ManaPlus:
+fix: battle sfx sound.
+fix: gui sound in deb packages.
+fix: show own player level.
+fix: colors in black wood theme (lien).
+fix: crash with -p command line option.
+add: /disconnect chat command.
+add: tooltips for control buttons (right top corner).
+add: /me command in whisper and party tabs.
+add: show level if possible in online list.
+
+Mana:
+
+Download Compile in Ubuntu
+
+
+
+2010-08-03 release 1.0.8.3.
+New features:
+
+ManaPlus:
+fix: money display bug.
+
+
+2010-08-01 release 1.0.8.1.
+New features:
+
+ManaPlus:
+fix: improve speed.
+fix: adjust money field size in trade dialog.
+add: show GM level near level in status window.
+add: attribute Attack Delay in status window.
+To open this windows, press F2.
+add: increased number of servers from 6 to 15 in server dialog.
+add: restore whispers between client restarts.
+add: set fps limit to alternate value in away mode or if game minimized.
+add: disable any sound and music in away mode.
+add: antispoof chat protection.
+add: option to auto close or skip updates in login window.
+add: server name in login window.
+add: theme black wood (lien).
+
+Mana:
+fix: fps limiter on windows.
+
+
+2010-07-18 release 1.0.7.18.
+New features:
+
+ManaPlus:
+fix: moved mumble from recommended to suggested in deb packages.
+fix: allow set more then 99 stat points, max 120.
+Work only on servers with this ability, like UFB server.
+fix: show player level.
+fix: improve speed in openGL mode.
+fix: crash on exit.
+fix: dont fix player position in default attack mode.
+add: updated russian translation (Schekoldin Ivan).
+add: context menu to players in online list.
+add: chat commands /befriend, /disregard, /neutral.
+add: allow set fps from 2 to 160.
+add: allow set gui opacity from 2 to 100 %.
+
+
+2010-07-04 release 1.0.7.4.
+New features:
+
+ManaPlus:
+fix: problems with font selection.
+fix: crashes.
+fix: -U command option.
+fix: setup window size.
+add: help font.
+add: updated help.
+add: show history in whispers.
+add: per server player relations.
+add: whisper and dialog sound.
+add: separate sound options for music, game sfx, gui sfx.
+add: experimental support for mumble voice chat.
+First start mumble, then start client with enabled mumble option.
+add: updated russian translation.
+add: safe mode shortcut for windows.
+
+Mana:
+fix: chat messages about user offline now showing in player tab.
+
+
+2010-06-21 release 1.0.6.21.
+New features:
+
+ManaPlus:
+fix: crash on some servers.
+
+Mana:
+
+Download Compile in Ubuntu
+
+
+
+2010-06-20 release 1.0.6.20.
+New features:
+
+ManaPlus:
+fix: avoid server direction bug.
+right direction server send as unknown direction.
+fix: restore main line attack automation.
+add: some russian translation.
+add: show popups for players without party.
+add: font changes.
+To change open SET \ Theme.
+add: per server configs.
+Moved many server related options to per server configs, like magic spells.
+Old values for bars can be restored from context menu.
+add: attack mode 'd'.
+Attack without auto target next monster.
+
+
+2010-05-31 release 1.0.5.30.
+New features:
+
+Patch:
+fix: crash from incorrect utf8 chars.
+fix: allow registration.
+add: moved to master mana branch.
+
+Mana:
+fix: improve game speed.
+
+
+2010-05-23 release 1.0.5.23.
+New features:
+
+Patch:
+fix: follow modes and navigate.
+fix: try avoid new server side bugs with packet limiter.
+fix: --skip-update now working.
+add: pickup mode A.
+Allow pickup items in max distance.
+add: allow add any items to buy list in personal shops.
+add: improve text draw speed.
+add: new imitation mode for imitating outfits.
+Switch initation mode by key ([4])
+add: allow mark any map positions with arrow sign and comment.
+To mark current position while you standing press Set Home Location key ([5]).
+To add comment press right button on map arrow.
+To add home location, sit and press Set Home Location key ([5]).
+add: custom resolution.
+To change resolution, click on "custom" resolution.
+add: auto change position if cant attack closed being.
+add: option to hide move path.
+add: change resolution in safe mode to 640x480.
+
+Mana:
+fix: crash with disabled opengl.
+
+
+2010-05-1 release 1.0.5.1.
+New features:
+
+Patch:
+fix: allow start client if update server is down.
+add: show floor item amount, if more then one.
+add: improved command /navigate.
+add: improved move to target.
+add: improved targeting nearest beings.
+
+
+2010-04-25 release 1.0.4.25.
+New features:
+
+Patch:
+fix: dont show shop requests if shop mode disabled.
+fix: draw items in outfits even if no this item in inventory.
+fix: invite command.
+add: option to hide whisper shop messages.
+Enabled by default.
+add: change color in whisper tab if player go offline.
+add: open buy sell window on selected player.
+Select player, then press talk key.
+add: new follow modes: relative, mirror, pet. ([1])
+add: show server side player position.
+add: manual mode to fix desync position. (D)
+add: add missing help for chat commands.
+add: new commands /loadprice, /saveprice.
+For load and save prices.
+add: new command /trade NICK.
+Open trade window.
+add: option to send shop announce with or without links to items.
+add: partialy right click emulation from keyboard (TAB).
+add: translated some string to russian.
+
+Mana:
+fix: crashes.
+add: clear butotn in npc dialogs.
+
+New keys:
+
+switch follow modes. ([1])
+right click emulation (TAB)
+
+
+2010-04-14 release 1.0.4.14.
+New features:
+
+Patch:
+fix: item amout window size.
+fix: gender display.
+add: trade chat tab.
+Most trade messages now moving to this tab.
+Also players can speak in this tab about trades.
+add: speed improvement.
+add: button store in config window.
+Save configuration file to disk.
+add: simplify context menus.
+add: personal shop.
+To this shop player can add items for buy/sale.
+Other players can use it by selecting in context menu buy or sale.
+To open own shop window you can press Shop button in inventory or press Shop Key.
+add: open shop key (unassigned).
+add: copy chat history to chat input. ([7]) ([9])
+add: erased player relation.
+Drawing only player name without sprites.
+add: /erase command to erase player.
+add: coloring friends/disregarded/ignored/erased names.
+add: New map view mode. (f)
+It remove upper map layers. Good near houses.
+add: support for buggy servers with incorrect packet limiter.
+It try avoid different bugs added in recent tAthena update.
+Enabled by default.
+add: save password between disconnects.
+add: move to target key now can move in navigation path.
+add: command /mail nick message.
+It send offline mesasge to player.
+Using AuctionBot for storing messages.
+add: enchilado theme.
+
+Mana:
+fix: crashes.
+add: redesign servers dialog.
+add: allow/disallow register new account check.
+
+New keys:
+copy chat history to chat input. ([7]) ([9]).
+
+
+2010-03-21 release 1.0.3.21.
+New features:
+
+Patch:
+fix: crashes.
+fix: mouse selection.
+fix: fixed server dialog.
+fix: basic skill in old servers.
+fix: old config restoration.
+add: safe mode after client crash.
+add: small speed optimisations.
+add: remove chat log from debug chat tab.
+add: add chat log to party chat tab.
+add: go and attack mode (end).
+This mode enabled by default.
+add: new mode for go to target (v).
+Mode A - attack range.
+add: /imitation command.
+You can use it from player context menu, or as chat command /imitation NICK
+add: bytes send/receive per second counter.
+
+Mana:
+add: Separated palettes for thems and for user colors.
+
+New keys:
+Switch attack mode (end).
+
+
+2010-03-08 release 1.0.3.8.
+New features:
+
+Patch:
+fix: many crushes.
+fix: mouse attack.
+add: store button in inventory.
+add: allow hide shield sprite (error message as start).
+add: button store in inventory.
+add: away outfit.
+To set away outfit you must open outfits window (`) and set away outfit checkbox in outfit.
+And now if you go to away, your char wear away outfit, and after away it restore old outfit.
+
+Mana:
+add: classic skin update.
+
+
+2010-02-28 release 1.0.2.28.
+New features:
+
+Patch:
+fix: allow enter in NPC dialogs letters, assigned to prev\next chat tab keys.
+fix: dont redirect server messages from party tab.
+fix: npc flood with small dialogs.
+fix: fixed some crashes.
+add: show target player level, nick, party in debug window.
+add: command /navigate x y.
+add: heal players by click in social window.
+add: get player levels from parsing #inwilt result.
+add: visible players tab in social window (P tab).
+add: actions in social window.
+left click - heal
+right click - context menu
+middle click - whisper
+add: damage counter for players.
+You can see it in social window in P tab.
+
+Mana:
+fix: crash in TAW maps.
+add: party windows replaced to social window.
+add: party tooltips for players.
+add: paste from clipboard.
+CTRL+V
+
+
+2010-02-07 release 1.0.2.7.
+New features:
+
+add: health bars in party window.
+add: own health in party window.
+add: build on latest mana git client.
+fix: allow enter numbers in input fields.
+fix: segfault in follow.
+fix: other small fixes.
+
+
+2010-01-17 release 1.0.1.17.
+New features:
+
+fix: D.o.S. in chat.
+fix: D.o.S. in trade.
+add: ignore button in trade request.
+add: themes (classic, wood, red).
+change : SET / theme / gui theme
+add: buy/sell in npc context menu.
+add: /follow command.
+add: /heal command.
+
+
+2010-01-02 release 0.12.
+New features:
+
+fix: random generator in crazy move A.
+fix: improved draw chat speed.
+fix: fixed /closeall crush.
+fix: use workaround to fix clover/towel and some other feature inventory bugs.
+Two buttons, one for equip and second for use item.
+fix: default Who is online size and position.
+add: e? command in crazy move A.
+e? show random emotion in crazy move A.
+add: limit lines in chat.
+change: SET / chat / Limit max lines in chat.
+add: clear command in chat context menu.
+add: highlight target being by bold font.
+add: afk mode. ([2])
+change : SET / other / Enable afk message
+use: key 2 on numeric keuboard or chat command /away TEXT. (or /away)
+add: draw item in item popups.
+
+New keys:
+Enable away mode ([2]).
+
+
+2009-12-13 release 0.11.
+New features:
+
+add: highlight player and monsters attack range.
+change: set / Other
+Highlight Player Attack Range
+Highlight Monster Attack Range
+add: colors in setup colors for attack range and portals.
+change: set / Colors
+Local Player Attack Range
+Local Player Attack Range Border
+Monster Attack Range
+Portal Highlight
+add: colors in setup for home location, collisions.
+change: set / Colors
+Home Place
+Home Place Border
+Collision Highlight
+add: key to copy equiped items to outfit (]).
+add: key to disable game modifiers ([8]).
+add: ping field in debug window.
+add: target id in debug window.
+add: chat logger.
+change: set / chat / Enable Chat Logger
+add: /outfit N command.
+Wear outfit N.
+add: /emote N command.
+Show emote N.
+add: auto complete party members in party tab.
+add: key switching on/off sound ([3]).
+add: highlight inactive tab if player name is writed.
+change: set / Color / Tab With Player Name Highlight
+
+New keys:
+key to copy equiped items to outfit (]).
+key to disable game modifiers ([8]).
+key switching on/off sound ([3]).
+
+
+2009-11-29 release 0.10.
+New features:
+
+fix: possible crush in update window.
+fix: localisation resources in deb packages.
+fix: added edit button to crazy move A.
+fix: allow using other update servers.
+add: auto complete chat key in settings. (TAB)
+add: hide input chat key. (ESC)
+add: manual update button in online users list and online list resize.
+add: set log file name from command line.
+add: limit chat messages size.
+Change: set / chat / Limit max chars in chat line.
+
+New keys:
+Hide input chat key. (ESC)
+
+
+2009-11-15 release 0.9.
+New features:
+
+fix: remove spaces and (GM) label from GM nicks in onlile list.
+new: moved to git sources.
+new: popup windows for hp, mp, xp bars.
+new: more font sizes in setup.
+new: context menu in chat tabs.
+new: keys to wear next/previous outfit.
+new: Increased outfits count to 40.
+Keys for outfits 1 - 0, -, =, backspace, insert, home, q - p, [, ], \, a - l, ;, ', z
+new: Increased drop slots to 16.
+new: Increased spell shortcuts to 49.
+new: New pick up modes g ang G. go and pick up in 4 and 8 cell distance.
+new: programmed crazy move type A.
+For this crazy move type you can write simple program in set / Other / Crazy move A program.
+Allowed commands:
+du, dd, dl, dr, d? change direction to up, down, left, right or random.
+mu, md, ml, mr, m?, mf, mb move to up, down, left, right, random, forward, backward.
+s sit.
+on, op wear next outfit, wear previous outfit.
+d0, da drop from first slot, drop from all slots.
+p pick up.
+e0 - e9, ea - ed emotions.
+new: /target command.
+
+New keys:
+Wear next outfit. (right alt + right)
+Wear previous outfit. (right alt + left)
+
+
+2009-10-25 release 0.8.
+New features:
+
+new: Setting to disable higlighting floor items.
+new: Auto complete in chat.
+To use press TAB key.
+Auto complete visible nicks, commands from Commands Window and from chat history.
+new: Show patch update information in update window.
+
+
+2009-10-18 release 0.7.
+New features:
+
+new: Spells Window renamed to Commands Window.
+new: Command (spells) editor.
+To use editor, open Commands Window (j), then to open editor, press by right mouse button on spell.
+new: Text or GM commands in Commands Window.
+Now you can add or edit in Commands Window spells, simple text or GM commands.
+new: Command /closeall for close all whisper tabs.
+new: Command /ignoreall for ignore all current whispers.
+new: highlight drops by time.
+remove: no rain.
+fix: disable keyboard shortcuts in drop/select item window.
+
+
+
+2009-10-11 release 0.6.
+New features:
+
+fix: fixed remove colors.
+fix: fixed "Allow magic and GM command in all chat tabs".
+new: bot checker. ([)
+Warning: may conflict with other key bindings.
+Check bindings in set / Keyboard / Bot Checker Window .
+By default disabled. To enable, use set / other / enable bot checker
+new: in colors picker color numbers replaced to color names.
+new: display selected target in debug window.
+new: spell shortcuts. (j)
+Allow add spell shortcurs to shortcuts window.
+To use, select spell in spells window by mouse click, then click on free slot in shortcuts window.
+In this versions only predefined spells.
+
+New keys:
+Bot checker window. ([)
+Spells window. (j)
+
+
+2009-10-04 release 0.5.
+New features:
+
+fix: possible crush if open emote window.
+fix: now work 14 slots in emote window.
+fix: some fix for jacko counter.
+new: cycle select palyers.
+Change: set / other / cycle player targets.
+new: cycle select monsters or palyers.
+Change: set / other / cycle monster targets.
+new: cycle rainbow colors.
+new: target name and position in debug window.
+new: magic spells and GM commands work in all chat tabs.
+Change: set / chat / All magic and GM commands in all chat tabs.
+new: move player spell messages to debug window.
+Change: set / chat / Log magic messages in debug tab.
+new: move server messages to debug window.
+Change: set / chat / Show server messages in debug tab.
+new: outfits wear and copy keys in settings.
+Change: set / keyboard / Wear Outfit.
+set / keyboard / Copy Outfit.
+new: move to target modifer.
+Allow move to target in given distance
+Move to target. (v)
+Change distance. (.)
+new: hide or show chat colors picker.
+Change: set / chat / Chow chat colors list.
+new: allow set home position.
+Set home locaton to current position. ([5])
+Go to home location. (d)
+new: home locations now highligted.
+
+New keys:
+Change distance in move to target. (.)
+Set home locaton to current position. ([5])
+
+
+2009-09-29 release 0.4.
+New features:
+
+Remove colors on overhead text.
+Setting to hide or show portals higlighting.
+Change: set / other / Highlight map portals.
+Whisper command in popup menu.
+Magic attack.
+Attack key (b).
+Switch attack spell (,).
+Ability to change default text color in sended text messages.
+Ability to remove colors from other users messages.
+Change: set / chat / Remove colors from received chat messages.
+Fix: Allow select dead player by mouse, if enabled seleting dead players.
+Fix: Joystick pick up now work like pick up from keyboard.
+Fix: Fixed negative jacko spawn counter.
+Fix: Fixed some default colors.
+Fix: Fixed crazy move 9.
+
+New keys:
+Magic attack (b).
+Switch magic attack spell (,).
+
+
+
+2009-09-26 First patch version.
+New features:
+
+Show damage inflicted near monster's name.
+Change: set / other / Show damage inflicted to monsters.
+Select text colors for local player damage and local player misses.
+Change: set / colors. Items: Local player hit monster, Local player critical hit, Local player miss.
+Highlighting map portals with color.
+Allow target only reachable monsters.
+Change: set / other / Auto target only reachable monsters.
+Allow target dead players.
+Change: set / players / Target dead players.
+Quick heal feature.
+Heal targeted player or self.
+Quick pick up feature.
+Pick up modes: small (1x1), default (2x1), forward (2x3), full (3x3)
+For pick up use standard pickup key. (z)
+For change use Change pickup type key. (o)
+Nuke player (ported from qoal patch).
+Debug chat tab for some information.
+Print all visible object to debug chat window.
+In chat type /all.
+Anti rain.
+Change: set / other / No rain.
+/ignore, /unignore, /quit command in chat (ported from git version)
+/move X Y command for move to location.
+Quick Drops Window with 9 drop slots.
+To open use drop window key. (w)
+Quick drop.
+Drop N items at once from 0 slot. (y)
+Drop N items at once from all slots. (u)
+Use drop counter for drops. To change counter use (i)
+Who is online (ported from qoal patch).
+Outfit window (ported from git version).
+To open use outfits window key. (`)
+To wear outfit use Right-CTRL+outfit key. (1-9,0,-,=,backspace,insert,home)
+Outfit addons.
+15 different outfits.
+To Copy different outfit to current use left CTRL+outfit key. (1-9,0,-,=,backspace,insert,home)
+Check box unequip first work independently for each outfit.
+Kill stats (ported from qoal patch).
+To open use Kill stats window key. (e)
+Changing direction (rotate player) without moves.
+To rotate use Direct up/left/down/right keys. (|,;,k,')
+or ALT+move keys
+Crazy moves.
+For programmed moves use crazy moves key. (/)
+To change current move type use Change crazy move type. (\)
+Insert unicode chars in chat (ported from qoal patch).
+Player position in debug window.
+Id in item popups.
+Experience per 1,5,15 minutes in kill stats.
+Jack O counter in kill stats.
+Different statuses in top left window corner.
+To change statuses use designated keys.
+To see detailed information, move mouse to statuses bar.
+Unassign key binding in keyboard setup.
+You can unassign any key in key bindings window.
+After changing key bindings show first conflicting key binding.
+New setup page "Other".
+New settings in setup player tab.
+New parameters in stats window.
+Added Flee bonus and target time.
+New map view mode. (without big objects, for example without trees).
+To switch mode use Find path to mouse key. (f)
+Allow player to speak after death (ported from qoal patch).
+Smaller window buttons in top right corner.
+More shortcuts (15).
+Game modifiers.
+Allow player to change some game behaviours from keyboard.
+Can view in top left corner.
+Allow sit without pauses.
+Allow attack from sitting (quick stand).
+Allow move to last target.
+To move use Move to target key. (v)
+Allow player to move to home position.
+To move use Move to home key. (d)
+Show player gender.
+To change open set / player / show gender.
+Allow automatically switch from bow to sword and backward.
+Allow switch weapon depend on distance to target.
+To change current switch mode use Change attack weapon type key. (g)
+
+New keys:
+
+Move to target. (v)
+Move to home. (d)
+Change pick up type. (o)
+Changing player facing direction. (k,l,;,')
+Crazy moves. (/)
+Change crazy move type. (\)
+Quick drop. (u)
+Quick drop from first slot only. (y)
+Switch quick drop counter. (i)
+Heal. (c)
+Itenplz. (m)
+Invert move direction. ([.])
+Change attack weapon type. (g)
+
+New mouse actions:
+Heal (Attack Key + left mouse button)
+
+
+
+
+
+ 0.0.29.1 (9 June 2009)
+ - Added the ability to change your password after logging in
+ - The leader of a party is now displayed in bold
+ - Status window was reorganized to allow larger numbers to be displayed
+ - The client no longer quits when it can't find the current map
+ - Fixed position of floating text for damage, pickup and experience
+ - Fixed a possible crash on logging in to the map server
+ - Fixed the crash when shift-clicking an item in the inventory
+ - Fixed a crash related to item links in the chat window
+ - Fixed a crash on whispering somebody again after closing their tab
+ - Fixed lightspeed bug when stopping to attack
+ - Fixed the -S/--home-dir command line option
+ - Fixed Reset Windows to also reset the party window
+ - Fixed problems with the context menu in the Brazilian translation
+ - Fixed resetting the height of the chat on /clear
+ - Fixed playing of login song and the music after login
+ - Fixed a problem with the player skipping corners, desyncing from the server
+ - Small optimizations to OpenGL mode when drawing certain GUI widgets
+ - Updated Spanish, Polish, Portugese, Swedish, French and German translations
+
+ 0.0.29 (13 May 2009)
+ - Added support for dynamic emotes and a new way to select them
+ - Added speech balloons that wrap the text
+ - Added item popup for showing detailed information
+ - Added ability to refer to items in chat
+ - Added the ability to see your own name in game
+ - Added the option to hide player names
+ - Added support for dynamically defined weight unit and currency
+ - Added support for NPC item storage
+ - Added compile-time support for tmwserv, as an alternative to eAthena
+ - Added support for entering the port of the login server
+ - Added support for creating parties and inviting other players to them
+ - Added tabs to the chat window for party and private chats
+ - Added ability to set initial player attributes when creating a new character
+ - Added command line option to temporarily disable OpenGL (--no-opengl)
+ - Added support for showing arrows flying through the air
+ - Added option to show pickup as text particle instead of in the chat
+ - Added ability to change the font size
+ - Added support for the /me command to do actions
+ - Added a /present command to show players present in the area
+ - Added ability to record the chatlog to a file
+ - Made emote shortcuts customizable in more detail
+ - Made it possible to change resolution
+ - Made many colors used by the game configurable
+ - Made setup window available during login
+ - Dynamically generate the item effects description
+ - Minimap can now be told to stay on the screen
+ - Minimap now adapts to the scale and size of the minimap image
+ - Non-stackable items can now be sold more easily
+ - Login dialog now remembers the list of recently used servers
+ - Completely rewritten NPC interaction
+ - GUI opacity now effects the whole user interface
+ - Redesigned the trade window
+ - Redesigned equipment window and allow unequip from there
+ - Next level percentage is now displayed in hundredths
+ - The player will no longer walk away when clicking the map while sitting
+ - Keep the login screen from taking 100% CPU
+ - No longer prompt for character server when there is only one
+ - Fixed compilation with GCC 4.4
+ - Fixed scroll wheel handling and dragging glitches in lists
+ - Many more bug fixes, small improvements and code cleanups
+ - Updated German, Finnish, Croatian, French, Spanish, Swedish and Polish
+ translations
+
+ 0.0.28.1 (12 February 2009)
+ - Enabled translations on Windows
+ - Added command line option to set home directory path
+ - Tweaked green chat color to be a bit more readable
+ - Made font size configurable in the config file
+ - Fixed restoring of punching animation after weapon removal
+ - Fixed inability to chat while talking to NPCs
+ - Updated Swedish translation
+
+ 0.0.28 (25 January 2009)
+ - Added support for animated map tiles
+ - Added support for internationalization, plus many translations
+ - Added support for TrueType fonts
+ - Trade window is now resizable
+ - Obscure precise home directory name when making screenshots
+ - Fixed follow-parent of nested and being-following particle emitters
+
+ 0.0.27 (9 December 2008)
+ - Added support for showing map name above minimap
+ - Added showing how long the ban is when banned
+ - Added --data parameter for developers
+ - Added particle effect for critical hits
+ - Added support for dynamic skill names and hair colors
+ - Added support for status effects
+ - Added ability to add equipment to the shortcut bar
+ - Added ability to change configuration during login phase (from Aethyra)
+ - Mouse cursor will now hide when not used for some time
+ - Inventory window now displays amount of slots used
+ - Center minimap on player when it is larger than the minimap window
+ - Extended particle emitters with properties that can change over time
+ - Extended the GUI font to support more characters
+ - Only require a restart to switch to full screen with OpenGL on Windows
+ - Make sure news and update file list aren't cached (from Aethyra)
+ - Made NPC dialogs resizable (from Aethyra)
+ - Made window shortcuts configurable
+ - Fixed visibility of trade window on startup
+ - Fixed a client input freeze when closing NPC script from server
+ - Fixed dead players to lie on the ground instead of standing around
+ - Fixed shortcuts being activated when trade window was visible
+ - Fixed a crash when equipment window is open
+ - Fixed money value on failing to buy (from Aethyra)
+ - Fixed crash in right-click menu when used after a being disappeared
+
+ 0.0.26 (29 August 2008)
+ - Added support for a newer version of eAthena server
+ - Added support for showing custom being effects
+ - Added new features to the particle engine
+ - Position names and chat such that there is no overlap, when possible
+ - Fixed a crash when loading a corrupt map that has too much layer data
+
diff --git a/data/help/chatcommands.txt b/data/help/chatcommands.txt
new file mode 100644
index 000000000..9e37849f1
--- /dev/null
+++ b/data/help/chatcommands.txt
@@ -0,0 +1,74 @@
+ <- @@index|Back to Index@@
+
+
+##3 Chat commands
+
+
+##PWhispers
+##2
+ /closeall - close all whispers.
+ /ignoreall - add all whispers to ignore list.
+ /msg NICK text, /whisper NICK text, /w NICK text - send whisper message to nick.
+ /query NICK, /q NICK - open new whisper tab for nick.
+
+
+##PActions
+##2
+ /help - show small help about chat commands.
+ /target NICK - select nick as target. Can be monster or player nick.
+ /outfit N - wear outfit number N.
+ /outfit next - wear next outfit.
+ /outfit prev - wear previous outfit.
+ /emote N - use emotion number N.
+ /away, /away MSG - set away mode.
+ /follow NICK - start follow mode.
+ /imitation NICK - start imitation mode.
+ /heal NICK - heal nick.
+ /move X Y - move to X,Y position in short distance.
+ /navigate x y - move to position x,y in current map in any distance.
+ /mail NICK MSG - send offline message to NICK. Working only in tmw server.
+ /disconnect - quick disconnect from server.
+ /attack - attack target.
+ /undress NICK - remove all clothes from nick. Local effect only.
+
+
+##PTrade
+##2
+ /trade NICK - start trade with nick.
+ /priceload - load shop price from disc.
+ /pricesave - save shop price to disc.
+
+
+##PPlayer relations
+##2
+ /ignore NICK - add nick to ignore list.
+ /unignore NICK - Remove nick from ignore list.
+ /friend NICK, /befriend NICK - add nick to friends list.
+ /disregard NICK - add nick to disregarded list.
+ /neutral NICK - add nick to neutral relation list.
+ /erase NICK - add nick to erased list.
+ /clear - clear current chat tab.
+ /createparty NAME - create party with selected name.
+ /me text - send text to chat as /me command in irc.
+
+
+##PDebug
+##2
+ /who - print online players number to chat.
+ /all - show visible beings list in debug tab.
+ /where - print current player position to chat.
+ /cacheinfo - show text cache info.
+
+
+##PWhispers commands
+##2
+Most commands working in whispers.
+For example command /imitation in whisper nick nick1,
+ similar to command /imitation nick1.
+
+
+
+
+
+
+
diff --git a/data/help/commands.txt b/data/help/commands.txt
new file mode 100644
index 000000000..bf73a388c
--- /dev/null
+++ b/data/help/commands.txt
@@ -0,0 +1,175 @@
+ <- @@index|Back to Index@@
+
+
+##3 === COMMANDS ===
+
+##2KEYBOARD:
+
+ ##2UP##P "Move Up"
+ ##2DOWN##P "Move Down"
+ ##2LEFT##P "Move Left"
+ ##2RIGHT##P "Move Right"
+ ##2LeftControl##P "Attack"
+ ##2x##P "Target & Attack"
+ ##2v##P "Move to Target"
+ ##2Period(.)##P "Change Move to Target type"
+ ##2d##P "Move to Home location"
+ ##2KeyPad[5]##P "Set home location/Set arrow"
+ ##2RightShift + key##P "Move to navigation point"
+ ##2LeftAlt + EmoteKey##P "Smilie"
+ ##2t##P "Talk"
+ ##2LeftShift##P "Stop Attack"
+ ##2a##P "Target Closest"
+ ##2n##P "Target NPC"
+ ##2q##P "Target Player"
+ ##2z##P "Pickup"
+ ##2o##P "Change Pickup Type"
+ ##2h##P "Hide Windows"
+ ##2s##P "Sit"
+ ##2p##P "Screenshot"
+ ##2r##P "Enable/Disable Trading"
+ ##2f##P "Change Map View Mode"
+ ##2MenuKey##P "Item Shortcuts Key"
+ ##21##P "Item Shortcut 1"
+ ##22##P "Item Shortcut 2"
+ ##23##P "Item Shortcut 3"
+ ##24##P "Item Shortcut 4"
+ ##25##P "Item Shortcut 5"
+ ##26##P "Item Shortcut 6"
+ ##27##P "Item Shortcut 7"
+ ##28##P "Item Shortcut 8"
+ ##29##P "Item Shortcut 9"
+ ##20##P "Item Shortcut 10"
+ ##2Minus(-)##P "Item Shortcut 11"
+ ##2Equals(=)##P "Item Shortcut 12"
+ ##2Backspace##P "Item Shortcut 13"
+ ##2Insert##P "Item Shortcut 14"
+ ##2Home##P "Item Shortcut 15"
+ ##2F1##P "Help Window"
+ ##2F2##P "Status Window"
+ ##2F3##P "Inventory Window"
+ ##2F4##P "Equipment Window"
+ ##2F5##P "Skill Window"
+ ##2F6##P "Minimap Window"
+ ##2F7##P "Chat Window"
+ ##2F8##P "Item Shortcut Window"
+ ##2F9##P "Setup Window"
+ ##2F10##P "Debug Window"
+ ##2F11##P "Social Window"
+ ##2F12##P "Emote Shortcut Window"
+ ##2BackQuote(`)##P "Outfits Window"
+ ##2w##P "Quick drop Window"
+ ##2e##P "Kills Stats Window"
+ ##2j##P "Commands Window"
+ ##2LeftBracket([)##P "Bot Checker Window"
+ ##2LeftAlt + 1##P "Emote Shortcut 1"
+ ##2LeftAlt + 2##P "Emote Shortcut 2"
+ ##2LeftAlt + 3##P "Emote Shortcut 3"
+ ##2LeftAlt + 4##P "Emote Shortcut 4"
+ ##2LeftAlt + 5##P "Emote Shortcut 5"
+ ##2LeftAlt + 6##P "Emote Shortcut 6"
+ ##2LeftAlt + 7##P "Emote Shortcut 7"
+ ##2LeftAlt + 8##P "Emote Shortcut 8"
+ ##2LeftAlt + 9##P "Emote Shortcut 9"
+ ##2LeftAlt + 0##P "Emote Shortcut 10"
+ ##2LeftAlt + Minus(-)##P "Emote Shortcut 11"
+ ##2LeftAlt + Equals(=)##P "Emote Shortcut 12"
+ ##2LeftAlt + Backspace##P "Emote Shortcut 13"
+ ##2LeftAlt + Insert##P "Emote Shortcut 14"
+ ##2RightControl##P "Wear Outfit"
+ ##2RightAlt##P "Copy Outfit"
+ ##2RightBracket(])##P "Copy Equiped to Outfit"
+ ##2Enter##P "Toggle Chat"
+ ##2PageUP##P "Scroll Chat Up"
+ ##2PageDOWN##P "Scroll Chat Down"
+ ##2KeyPad[7]##P "Previous Chat Tab"
+ ##2KeyPad[9]##P "Next Chat Tab"
+ ##2KeyPad[7]##P "Previous chat tab line"
+ ##2KeyPad[9]##P "Next chat tab line"
+ ##2Tab##P "Chat Auto Complete"
+ ##2Esc##P "Deactivate Chat Input"
+ ##2SpaceBar##P "Select OK"
+ ##2Esc##P "Quit"
+ ##2LeftWinKey##P "Ignore input 1"
+ ##2RightWinKey##P "Ignore input 2"
+ ##2l##P "Set Direction Up"
+ ##2Semicolon(;)##P "Set Direction Down"
+ ##2k##P "Set Direction Left"
+ ##2Quote(')##P "Set Direction Right"
+ ##2Slash(\)##P "Crazy moves"
+ ##2Backslash(/)##P "Change Crazy Move mode"
+ ##2y##P "Quick Drop N Items from 0 slot"
+ ##2u##P "Quick Drop N Items"
+ ##2i##P "Switch Quick Drop Counter"
+ ##2c##P "Quick heal target or self"
+ ##2m##P "Use #itenplz spell"
+ ##2b##P "Use magic attack"
+ ##2Comma(,)##P "Switch magic attack"
+ ##2KeyPad0##P "Change move type"
+ ##2g##P "Change Attack Weapon Type"
+ ##2End##P "Change Attack Type"
+ ##2KeyPad[1]##P "Change Follow mode"
+ ##2KeyPad[4]##P "Change Imitation mode"
+ ##2KeyPad[8]##P "Disable / Enable Game modifier keys"
+ ##2KeyPad[3]##P "On / Off audio"
+ ##2KeyPad[2]##P "Enable / Disable away mode"
+ ##2Tab##P "Emulate right click from keyboard"
+ ##2KeyPad[+]##P "Toggle camera mode"
+
+
+##2MOUSE:
+
+ Left click to execute default action: walk, pick up an item, attack a monster
+ and talk to NPCs (be sure to click on their feet). Right click to show up a
+ context menu. Holding [Left Shift] prevents from walking when attacking.
+
+
+##2COMMUNICATION:
+
+ Communication is often essential to success in this game. You can communicate
+ in several ways: By chatting and showing emotions (see above), by trading
+ (with the right-click context menu), and by whispering.
+
+ To read about whispering and other chat commands, look here: @@chatcommands|Chat commands@@
+
+
+##2IGNORING COMMUNICATION
+
+ You may find that not all communication is to your liking. While most people
+ are nice, some may offend you or try to make your life harder-- since this is
+ an open game, there is nothing the developers can do to prevent this.
+
+ However, you can protect yourself from such players by ignoring them. Right-
+ click on them to bring up the context menu, then select `Ignore' or
+ `Disregard' (see below). You can fine-tune your player relations in the
+ `Setup' menu, which lists all the players you have added to it. To open this
+ menu, select `Setup' in the upper right corner of the screen, then `Players'.
+
+ There you will find a list of all players you are acquainted with, as well as
+ several configuration options:
+
+ - ##2save player list##P: Should your acquaintance list be saved when you
+ quit the game? If you enable this option, your list will survive when you
+ quit and re-start.
+ - ##2allow trading##P: Do you wish to allow trade requests from arbitrary
+ players?
+ - ##2allow whispers##P: Do you wish to allow arbitrary players to send
+ private messages to you in-game?
+
+##2THE PLAYER LIST
+
+ The player list lists all of your acquaintances. They are categorised as one
+ of the following:
+
+ - ##2neutral##P: As far as the game is concerned, this is the same as not
+ having the player listed: the player may chat with you, but may only trade
+ or whisper if you have this option allowed for everyone.
+ - ##2friend##P: You consider this player a friend. The player may chat,
+ message your in private, or trade with you at any point.
+ - ##2disregarded##P: You wish to disregard this player, meaning that his or
+ her chat messages are not logged and trade requests and whispers are
+ ignored.
+ - ##2ignored##P: You wish to completely ignore this player. You will not
+ even see floating text for him or her anymore, nor emotions.
+
+
diff --git a/data/help/header.txt b/data/help/header.txt
new file mode 100644
index 000000000..3e60eebd4
--- /dev/null
+++ b/data/help/header.txt
@@ -0,0 +1,11 @@
+
+##1 M A N A P L U S
+##1 ================================
+
+ ##2Version:##6 1.0.12.26 ##2Date:##3 26 December 2010
+
+##2 Website: http://tmw.cetki.com/
+##2 http://mana.cetki.com/
+##2 http://manasource.org/
+
+
diff --git a/data/help/index.txt b/data/help/index.txt
new file mode 100644
index 000000000..c3b1d9f44
--- /dev/null
+++ b/data/help/index.txt
@@ -0,0 +1,23 @@
+##3 === INDEX ===
+
+ ##1-> @@about|About The Mana World@@
+ -> @@team|Development Team (TMW)@@
+ -> @@changes|Recent Changes@@
+
+ -> @@commands|Commands@@
+ -> @@chatcommands|Chat commands@@
+ -> @@windows|Windows@@
+ -> @@skills|Skills@@
+
+ -> @@support|Support@@
+
+
+##3 === Powered By ===
+
+##2 SDL, SDL_image, SDL_mixer (Media framework)
+##2 SDL_net (Networking framework)
+##2 Guichan (GUI framework)
+##2 libxml2 (XML parsing and writing)
+##2 PhysFS (Data files)
+##2 libcurl (HTTP downloads)
+##2 zlib (Archives)
diff --git a/data/help/skills.txt b/data/help/skills.txt
new file mode 100644
index 000000000..5446b6164
--- /dev/null
+++ b/data/help/skills.txt
@@ -0,0 +1,16 @@
+ <- @@index|Back to Index@@
+
+
+##3 === SKILLS ===
+
+ You can improve your skills by increasing job level. Each job level
+ gives you 1 point to spend on basic skills.
+
+ ##4 Basic skills:
+
+ ##2Emote:##P enables the ability to express emotions
+ ##2Trade:##P enables the ability to trade with others
+ ##2Party Level1:##P enables a char to join a party.
+ ##2Party level2:##P enables a char to create a party
+ Other skills are still not implemented.
+ \ No newline at end of file
diff --git a/data/help/support.txt b/data/help/support.txt
new file mode 100644
index 000000000..1ac6c9d6f
--- /dev/null
+++ b/data/help/support.txt
@@ -0,0 +1,22 @@
+ <- @@index|Back to Index@@
+
+
+##3 === SUPPORT ===
+
+ If you're having troubles, plase first of all read the FAQ. If you
+ can't find a solution to your problem, feel free to check our
+ Bugs/Support section of the forum:
+
+ For TMW support:
+
+##2 http://forums.themanaworld.org/viewforum.php?f=3
+
+ or come visit us on our IRC channel:
+
+##2 #themanaworld ##P@##2 irc.freenode.net
+
+ Otherwise see the @@team|Development Team@@ section to have a list of
+ developers and how to contact them.
+
+ For other server look servers pages for support.
+
diff --git a/data/help/team.txt b/data/help/team.txt
new file mode 100644
index 000000000..e17771d5f
--- /dev/null
+++ b/data/help/team.txt
@@ -0,0 +1,132 @@
+ <- @@index|Back to Index@@
+
+
+##3 === DEVELOPMENT TEAM ===
+
+##2 Project Leader:
+
+ ##9Eugenio Favalli (aka ElvenProgrammer)
+ elvenprogrammer@gmail.com
+
+
+##2 Programmers:
+
+ ##9Bjorn Lindeijer (aka Hammerbear)
+ b_lindeijer@users.sourceforge.net
+ (various parts, GUI, graphics, A* and map rewrites)
+
+ ##9Bjrn Steinbrink (aka Doener)
+ der_doener@users.sourceforge.net
+ (various parts)
+
+ ##9Eric Scrivner (aka zenogais)
+ bitshift2002@users.sourceforge.net
+ (resource manager)
+
+ ##9J. Avila (aka Javila)
+ javila@users.sourceforge.net
+ (various parts, GUI)
+
+ ##9Jan-Fabian Humann (aka Mra)
+ malastare@users.sourceforge.net
+ (some GUI parts)
+
+ ##9Kiyoshi Kyokai (aka Kiokay)
+ kyokai@users.sourceforge.net
+ (game systems designer)
+
+ ##9Mateusz Kaduk (aka Usiu)
+ usiu@users.sourceforge.net
+ (several GUI parts)
+
+ ##9Aaron Marks (aka nym)
+ nymacro@users.sourceforge.net
+ (several GUI parts)
+
+ ##9Shura
+ kth5@users.sourceforge.net
+ (configuration, sound, misc. ports)
+
+ ##9Yohann Ferreira (aka Bertram)
+ bertram25@users.sourceforge.net
+ (SDL input, progress bar drawing, Debian package)
+
+
+##2 Artists:
+
+ ##9Clef
+ (tiles, concepts)
+
+ ##9Frode Lindeijer (aka Modanung)
+ f.lindeijer@xs4all.nl
+ (arts)
+
+ ##9Gnulia
+ (conceptual art)
+
+ ##9Magick
+ (music and sound effects)
+
+ ##9Neko-mon
+ (player sprites, various things)
+
+ ##9Neorice
+ (monster sprites, tiles)
+
+ ##9Pajarico
+ pajarico@users.sourceforge.net
+ (conceptual arts)
+
+ ##9Romulo Fernandes
+ razor85@users.sourceforge.net
+ (arts)
+
+ ##9Rotonen
+ rotonen@users.sourceforge.net
+ (backstory, art director, music, sound)
+
+ ##9Talaroc
+ talaroc@users.sourceforge.net
+ (sprites)
+
+ ##9Ti Sing Hao
+ (music)
+
+
+##2 Misc. thanks:
+
+ ##9David Smith (aka catfish_man)
+ catfish_man@users.sourceforge.net
+ (Mac package)
+
+ ##9Igor Morgado (aka imorgado)
+ imorgado@users.sourceforge.net
+ (tester)
+
+ ##9maci
+ maci321@users.sourceforge.net
+ (technical support)
+
+ ##9Rodney Dawes (aka dobey)
+ dobey@users.sourceforge.net
+ (Mac package)
+
+ ##9Ultramichy
+ (hosting test server)
+
+
+##2 Inactive/retired:
+
+ ##9Chetic
+ chetic@users.sourceforge.net
+ (maps)
+
+ ##9Simon Edwardsson (aka SimEdw)
+ simonedw@users.sourceforge.net
+ (network code, Mac package)
+
+ ##9Sull
+ (hosting CVS and related services)
+
+ ##9Vlady
+ (several items)
diff --git a/data/help/windows.txt b/data/help/windows.txt
new file mode 100644
index 000000000..f1d0150a7
--- /dev/null
+++ b/data/help/windows.txt
@@ -0,0 +1,15 @@
+ <- @@index|Back to Index@@
+
+
+##3 === WINDOWS ===
+
+##2SHORTCUT:
+
+ To add an item to the shortcut bar click on the item in the inventory window,
+ then click on the box in the shortcut-window which should be associated with
+ the item. To reorder items within the shortcut-window simply click and drag
+ them between the boxes. To remove items you simply drag them outside of the
+ window and drop them.
+
+ Currently only stackable items like food, but not weapons or clothes can be
+ used with the shortcut window.
diff --git a/data/icons/CMakeLists.txt b/data/icons/CMakeLists.txt
new file mode 100644
index 000000000..41539898b
--- /dev/null
+++ b/data/icons/CMakeLists.txt
@@ -0,0 +1,7 @@
+SET(FILES
+ manaplus.png
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/icons)
+
+INSTALL(FILES "manaplus.png" DESTINATION share/pixmaps)
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
new file mode 100644
index 000000000..596363ba0
--- /dev/null
+++ b/data/icons/Makefile.am
@@ -0,0 +1,16 @@
+
+iconsdir = $(pkgdatadir)/data/icons
+
+icons_DATA = manaplus.png \
+ manaplus.xpm
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(datarootdir)/pixmaps
+ $(INSTALL) $(srcdir)/manaplus.png $(DESTDIR)$(datarootdir)/pixmaps/manaplus.png
+
+uninstall-local:
+ rm -f $(DESTDIR)$(datarootdir)/pixmaps/manaplus.png
+
+EXTRA_DIST = \
+ $(icons_DATA) \
+ CMakeLists.txt
diff --git a/data/icons/manaplus.hqx b/data/icons/manaplus.hqx
new file mode 100644
index 000000000..aadf6b53c
--- /dev/null
+++ b/data/icons/manaplus.hqx
@@ -0,0 +1,2938 @@
+(This file must be converted with BinHex 4.0)
+:"'eKEQ%!9%9B9(4dH(3%!!!!!Y!!!L'DDMe)EhFJG'mJGA0P)(4SDA-JD@0[EMS
++#P0dCA!J-6SJ3fp`H5"dD'8JD@0[EL"dEb"dD'8JBfaTF'*[BA*N#Q%T)%0XD@0
+V)'pZ)(4SDA-JCQPXC5"QFQpY)(4SC5"'D@jNCA)+BLNJ3fK[Eh0P)#G(CA3J5@j
+QEbFJCR*[E5"dD'8J*dCTE'8R)'ePER8Z#Q-T)%PZ)(4SC5"TEQC[)(GTEQ4[Gb"
+dD'&d)("[F(-JGA!X)'0XD@0V)'pZ)(4SC5"TBfpZ#Q3T)%0SEfpcC5!R3fp`H5F
+JCR*[E5"dD'8J*d9NDA3R)'ePER8Z#Q8T)%0XEh0P)(4SC5"TEQC[)(GTEQ4[G`S
++8h4PF#!b1L"3BA0dC5"dD'8JD@0[EL"dEb"dD'8JC'9cDA*PC#"TG'9Y#Q%T)%G
+[)(4[)(4SC5"TG'9Y)'PZ)(4SC5"'D@jNCA)JG'KKG#"jEh8JGf&ZG#"K)'0eFh4
+[E5"TBfpZ#Q)T)%0XD@0V)(4SC5"TG'9Y)#KQD@aP,#"QEfaNCA)X)'4TFfXX)'9
+dBbNJ#Q)T)%0SEfpcC5!R4f9d)%PZCQmR)'CbEfdJG'KP)#G'D@aP*b"YC@je,JT
+M+5"*EL"dD'8JD@jQEb"hD@jNEhFJG'KKG#"`Eh"c)(9`,#"ME'PMDb"[EL"dD'8
+JD@0[EJTN+5"$D'p[Ff8J*e"KFh4P*b"QFQpY)(4SC5!R4@4TG#FJE@9ZG5i+C5N
+J3fa[Ff8JG'KP)'PZCQmJGfPZC'ph#JT6G'9`)$-k)!T&EQT[H5"jEh9b)'jPGfa
+j)'0eFh4[E@PkC@3JD@0[EL%+#NC[FL"YEh*P)(4SEh*[G@GS)'4TFQ9MG'P[ER-
+X)(0PC5""F("XC5Gc)(GPBR0TG'8JBA3k#QKdG(!k,bphGhFZBA"`E'8ZBfpY,h0
+eF("[FR3[E@&M-6!a,f0eFh4[E@PkC5mf,`V6V!!!!3!!!L&S!!)JD!!!!$)!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!L"
+ND@0ZF`!#)'4TFc-b!!!"K))!KIq$!),rJ!#!ri%!JIq%!!$rJ!#!riS!LIq!!)[
+r"!!!rrm!J2m!!)$r!!#!r`3!!2rr!)$r!!#!r`!!J2m%!!$rr`#!r`!!J2m!!)$
+r"!!!rrm!J2m!!)$r!!#!r`%!!)2r!!#!r`!!Krm!!)$r!3!!J2m%!2m!rrq&!!A
+rr`$rr`#!ri-!Jrm"!!#"r`%!!)6rJJ#'ri!!JJ!(F@aYFh4aEh#$!!4pGR0cHi!
+!!U*rJB%!!hYdG@')!!*mFh1+!!YdF!"ZGAGdJ)"iGAf!!(*aF(*`E@jZE@YYEQj
+`I3!!DA!!FQY[!'pUF!"aE(F!!'Cc!("XFJ"bE(!!Ffaf!!"QFJ"aE(3!FQad!(0
+XG!!!CR%!FQeb!(4YG!"cE(3!!'aZ!(&`G!"dFR3!G'aZGRKcECGbI!"SHi!!!(0
+YFJ"[!(9aK3!)Ffi!Gfi!ChTpJ`!&GfeXER*dJ!!,IAKm!!"eG'aQE(4MJJ!)FA"
+aF@eTCfTXJ!$r!2X!FcKYD`!!!3J!!!!!!%QUh-HPHPS0!!!!!!!!(X2@A3S!!!!
+#-4S!!!!!0qb2"J!!!!!!!!!"!!!!)qU(!!!!!!!!!!!!!!!!!,l"!4SH0$m1"cN
+p$`!!!%lr16,qrm6pm1M%r1dS!!#Qe`"MrmB!U2r-!+6rK!!!jTS!L2q*!)rrM3#
+,riS!!2"l!+[rB`#SrfB!TIpU!!$NH!$4rcm!c2p"!-Er43!!T)d"pI`A!2(m'J$
+Yr'L-F$6*"%3[!!0%-3!!4)pC!)N!P$m!!!!!!!!!!#fY!"f,!!D++J!!!!!!!!r
+0kTbX#J!!!A"U(J!!$9IKrr&i!`!!!!!!%R#HZpV9U@J0!!!!D@`c-J!!!qL'!)h
+rL`#4riJ!Nrq'!)IrK!#$ri8!K2m"!2q*!)(rJ`#%rid!!IrrJ`#$rjB!JrqA!)2
+rJ3##ri!!J[q&!)2r!!#3!2q$!),r!!#5ri)!J[m!!*,rJJ##r`!!Jrm!!)6r!!#
+$ri)!J[m!!)2r!!#%r`!!K2q"!),r!!#$r`!!K2m!!)6rJ3#"r`!!Jrm"!!#$r`%
+!!)2rJJ#"r`!!Jrm"!!#$r`%!!)2rJJ#"r`!!Jrm"!!#$r`%!!)2rJJ#"r`!!Jrm
+"!!#$r`%!!)2rJJ#"r`!!Jrm"!!#$r`%!!)2rJJ#"r`!!Jrm"!!#$r`%!!)Ir!!#
+"r`!!Jrm"!!#$r`%!!)Ir!!#(ri!!J[q!!)Ir!!#'ri!!J[q!!)6r!!#!r`%!!),
+rM3#"r`%!!)$r!3!!J[q0!)(r!!#"ri!!J[q,!)IrJ3#$riB!!Im!L2q#!)ArJ3#
+,ri3!P2q(!*,rLJ#1ri3!KJ!$CfGQCi0Q!QGRCS"PL`!#D@PRK@B$CfGQCS"P!@C
+RL!!#C@GRJ@B'Cf4MCQCRCi&QJ@@'!)4Q!QKQC)3!"@CQC@4PCB8!!'H#CJ*P!'Q
+*!!0NAQ4RJ`!'C'CRCQCREBd!!9eMJ`!!D)*QPJ!!C)*QP`#$CS%!"'pTCfGSJ!!
+%9@GPBf1&!!&UCi"Q!Q3!CBCQ!'L"CJ"PJ'D$!!&RCi"Q!J"NCBCQ!'H%CJ&NBS)
+!!'L"CJ!!N@B!CB)!!'H!CJ05!'9PJ@B!!)4Q!!#$CS)!J'B$C@8!CB*Q!!#%CJ!
+!JfB!C)%!J@B"C3##CJ*R!(#$CJ%!AS&Q!@9IJ3#"CJ!!JfB"!!#$CJ)!!'@#CS)
+!J'B"BJ##CJ0R!!"NJQB#!!"PJ@B!Ci)!J@B!!)*Q!QF!!)*Q!QF!!)0QJJ#"CJ!
+!JfB#!!"RJ@B$C`!!CB&Q!'@#!)&Q!!##CJ*R!!#$CJ%!!)&Q!@9PJJ#!CJ&L!)*
+Q!QJ!!)*Q!Q3!!)&Q$'GQCfCQC!"RCQCN!'H!CJ0RB`!!JQB#C3!!JfB*CfGQCJ"
+TCfCQD)*QJ!##CS!!J@B)CfCQD'CQ!'GRJ'D!C3"RJ!!"rfH!CB!!"b0NC@9QCQ3
+!J'B"!!#!CJ&RCid!!'1!CJX!!'0QC`!!CQCPCQD0!!"RJ'B%!'pRCQL!!!4PCQC
+P5BX!#@GQCQ9PCfCQC@L"!!9RCQ9QF@#'!!*Q!'H%CJ*RC9b#!!*PCQH"CJ"IJ3!
+"D'H'CJ*RD'Z%!!"SJQB&BfCPCQCSKfB!D)F!!@9SJQB!CB9Q"'GQCQGRLJ!&C@9
+RCfCPJfB%C@GSCQD%!2m!r`$r!2m!r`$r!2m!l`"X1'eV!!!%#!!!!!!!!!!!!!)
+*)f@Se[,ikFkPF6%4"`%!!!!!!!!!!!!!!!!!!!%(,BcIpHlL`TTmF(+&SjT3&33
+!!!!!!!!!!!!!!!!#''[HqHZmCL3("33%"!8'%84R,`N"!!!!!!!!!!!!!bZKq[5
+r8``#!3!!!!!!!!!!!J)V,!B!!!!!!!!!!!3i[[lPKaN!!!!!!!!!!!!!!!!!!!%
+)"3!!!!!!!!!$0XEqh'X%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!5LkrppL!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8PIrYHJ!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!"echq+J+!!!!!!%($3X$!!!!!3J1#`)!!!!!!!!!!!%Ld2lC0`!53NY
+'6@YlG&Xd'#P3ERae9#S'!!!!!!!!#((kpC8!#@,arrcjrrlrrp'9[IErrrrq[$`
+&!!!!!!!CcrlL0J!GVIrrrp1,X[6rrrrrZiV(qIrrX"N!!!!!!%cfqlS$!#E*rrr
+YF`!d`2rrrq*(!&,Grrrb+J!!!!!!N[VbI!%!,ZArrmdj!!f4rrrrV#8!&F6rrrm
+p!3!!!!$&rHY'!3!kr2rrYa)!"BIrrrq'$3!)[rrrrd-$!!!!!1Mrj5%!"&,rrrq
+Q!!!,M[rrrfX!!"($rrrp-`!!!!!!qIrG#`!,F2rrqBm!!"HGrrrf@3!!*-VrrqX
+Q!!!!!!$irY8&!"1-rrrYGJ!!*Urrrpj)!!!le2rrc4m!!!!!!12pe!8!'URrrq&
+G!!!f`rrrb$J!!&6Hrrq['3!!!!!!Zr[@"3!Karrre8-!!%IBrrqb+!!!EqRrrj%
+5!!!!!!"qqGm3!#RMrrr*+`!!@Hlrrj`B!!#+p2rrF$efN!"f(3!cm1FX!$IrrrZ
+N#3!!EIrrqA%$!!#SrrrXTlkHIk5J!!qTl'%"(RjqELd!!!!jJApL(3!!!&GrIEl
+2DLJ521J!!clTU3)%$Ji+!!!!!!F2$`F!!!!!#JaJcQ!+!!%ai3!!$BcG1!!!!!!
+!!!!!!!!!!!!!!!!!&VQP'J!!"C'F!!!"*EQM#3!!!!!!!!!!!!!!!!!!!!"elRJ
+0!!Kfa$!!!!!%2-"h!3!!!!!!!!!!!!!!!!!!0X[r`&49TY"0"3!!!!!&4,Pd"J!
+!!!!!!!!!!!!!!#ZeqrrjjqE56`J!!!!!!!!&0D#B*`)"!!!!!!!!!JC0`rVrrrl
+mXMF'!!!!!!!!!!!#(@fkM$d5"`B("KT6UqImrrhkdQFD!J!!!!!!!!!!!!!"#5G
+b[G@mUl(,iqhfq[MaZQ3I"`%!!!!!!!!!!!!!!!!!!JN@2ADK`0ACd,UAC5`3"`%
+!!!!!!!!!D@Jc-J!!"G@0!)rrQ3#6rj8!Prq5!*VrM`#(r`)!rrq(!!(r!)2rM!#
+(rj%!JIq+!)ErP!#!riN!K[qM!)ErT!#%rk8!K2qP!)ArT3#%rk8!K2q'!)2rJJ#
+$riX!K2q!!*IrL3#%r`%!!*VrKJ#%ri!!Q[q'!)6rJ!#Eri8!Jrq"!)Ar!!#)r`!
+!K[q&!)2rJ!#'r`!!Krq!!)ArK3#$ri!!KIq!!)ErJ!#&ri8!Jrq!!)ArJ!#&ri%
+!KIq&!),rJ3#&ri!!KIq"!)ArK3##ri%!KIq!!)ArJ3#&ri8!J[q"!)ArJ!#&ri%
+!KIq&!),rJ3#&r`%!!)ErJ3#&ri8!J[q!!)ArJ!#'ri%!KIq&!),rJ!#&ri!!KIq
+"!)ArKJ##ri!!KIq!!)ArJ3#&riB!J[q!!)ArJ!#&ri%!KIq'!),rJ!#&ri!!KIq
+"!)cr!3!!J[q!!)ArJ!#&ri%!M2m"!!##ri!!KIq!!)ArJ3#-r`%!!)2r!!#&ri%
+!KIq"!)Mr!!#!ri!!J[m!!)6rJJ#%ri)!K[q!!)$rJ!##rjN!J[q!!)(rJ3##rjF
+!J[q"!)(rJ3##rjF!JIq#!)(rJJ##rj8!J[q"!),rJ`##rj3!Jrm!!)6rK!##rj)
+!Lrq'!),rN!!!Lrq)!)2rM!#-riS!K2m#!2rrJ`!"r`#-rid!R2q3!!#Brj-!PIq
+A!*(rL`#0!!&RCS&PJfB&CfCPC'CQQ3!"C@52CJ&RCT8!!@4RKfB'C@GPCQGNCB&
+Q!QGSCC)!KfB-CfGQC@GPCQGNC@9[D)"R!Q9NHBm!!'H'CJ)!CfL(!!GR!!"PCQG
+SCS`!!@PRK'B!CC%!!fCRDC++!!&XCi0Q!'H8!!*UE'f*!!&NCi0Q!'5M!!&lCi0
+Q!&5N!)4QT3!"CfH"CJ"PT3!"BQ@#CJ"1T3##CJ&RD+8!!@9PJ@B!CiB!"@4SC@G
+MBB)!"@4QCQ9QDiX!K'D!!!"QJ'H'CJ0PC'TRK@B!CiN!JfB$C3!!CCGQ!@GiKJ!
+"DfH"CJ"RJ!#DCSB!JfB!Ci!!KQB"C@@2CJ"NK3#$CS%!K@B"!'H(CJ%!C)4Q!'@
+&!!"SJ@B!Ci!!!'5&CJ)!E'L&CS!!K'B!Ci8!!'@"CJ"PJ!!!CB4QJ!#&CJ"NJ!#
+$CJ&RCi8!!'@"CJ"FJ!!!Ci4QJ!#&CS%!K'B!CB8!JQD"!)4Q!'H!!!&RCi*Q!'@
+"!)9QK3#"CJ"PJ3!!Ci4QJ!!"CfH#CJ"PJ3#&CS8!JQD"!)4Q!'H!!)9QJ3#%CJ"
+RK3#"CJ"PJ3#%CJ4T!!"+AB4QJ3#$CJ&PBi8!JQD!!)9QJ!!"C'5$CJ"MJ3#$CJ&
+PAB8!J@B!Ci!!K@D!!!&RCi0QJ3!!D)4QKJ##CS!!!'H%CS!!!@9PJfD"!!"RK'D
+'!!"RJ@D!!!"PJfB!CB!!K'B!CB%!K'B!CiB!!'H"CS!!K@D!!)9QJ3#&CJ"NJ@B
+%CfF!!'H"CS!!K'B!CB!!K@D"!)YQ!Q8!!)&Q!'@!!)9QJ!!!C)4QJ3#$CJ"RK@B
+$!!"SCi"Q!f-!@f@"CJ&RCi%!!'5%CS%!!'@"CJCRCQCRCPJ!J'D!!)&Q!f8!+@#
+!B`&QDi)!!'D"B`&QCS)!!''!B`4RCQCRD)!!!Q9PCS!!!@4PJ'DC!!"PJ'B!D)!
+!!'5!CS%!J@B!D*F!JQD"!!0RCfCPJ3!!BB&QP`!!Ci"QJJ!!CB"QJJ!!CB&QP3!
+!Bi&QJ3!!Ci&QJ`!"CfH!CT3!JfB"!'H"CJ&RF)3!JQD5!!"PLQD'!!"NJ@D3!!!
+!CiKQ!@9NL!!"D'H!CJ"FM!!!D)PQ!@9KLJ##CJ4RC3"MAi-!!f-!Bf@+CSd!!@C
+PJ'B%C@9NBfH"CJ0NC'GRKfB#C@CSN!!!!@CPJQB!CijQ!@9NN`!%AQ9QCfH-CJ0
+RCQ4RP`!+C@GRD@KRCfCPCf@"CJ4PCQCRCiX!r`$r!2m!r`$r!2m!r`$r!2m!r`$
+r!2m!r`$r!2m!r`$r!0X!D$KYD`!!#3J!!!!!!!!!!!!!!!!!!!!!"3iLAjV$jrR
+llq,$R@`h%`X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!B86+ARq2[pr2I
+bl1RSjHAL`Adj%J8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$%9+mp2hrqr$L`TG
+b6N!p0N9II+M(Q%38"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!JhS[(rrrMNYA%Y"J)
+#!3%"!3%"!J)95Bep-!N!!!!!!!!!!!!!!!!!!!!!!!!!%Q6@rrrliUG)#!!!!!!
+!!!!!!!!!!!!!!!!ZCd%4!J!!!!!!!!!!!!!!!!!!!!%JMI(rrqqh5`J!!!!!!!!
+!!!!!!!!!!!!!!!!!!$)h$3!!!!!!!!!!!!!!!!!!!LUKqrrrhS!D!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!2$3)!!!!!!!!!!!!!!!!",Dcrrrh28`B!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!RT[rrr-*%!3!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"UDrrrra6i!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$hVhrrr65`!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'81Arrq*N!3!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!N`Irrpj-0!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!errIrrac%!!!!!!!!!!!!,'4mF#3!
+!!!!!!!38)"i6"3!!!!!!!!!!!!!!!!!!!62MrrrUF3!!!#"MI(TaDiLQXVHdTS9
+'!J-PDCL[Z,D[QQFG!!!!!!!!!!!!!!!!$Bcprrqr'J!!')RTp22Yk[VrrrrrrrR
+4Mi'rkIrrrrrrrZQ[1`%!!!!!!!!!!!!"+q6rrqjk!!!!5YVrrrrrrrr`qrrrrrr
+rq2(rrrRbrrrrrrrqYLS!!!!!!!!!!!!*F2[rrmmQ!!!!CIMrrrrrrSP"6F,lrrr
+rrrrrf&FmHqErrrrrr'J'!!!!!!!!!!!5`rhrqU)!!!!!H2rrrrrrabd!!8(Urrr
+rrrrcM3%!%Blrrrrrrk!F!!!!!!!!!!!cm2rrkQS!!!!+M2rrrrrrJ3m!!!R$r2r
+rrrrI4J!!!&EXrrrrrm3X!!!!!!!!!!"Sq2rrf6!!!!!DSIrrrrrq6J!!!!@JqIr
+rrrr0$`!!!%(6rrrrrp)b!!!!!!!!!!#Iq[rr`J8!!!!VYrrrrrrF0`!!!!5Aq2r
+rrrZV!!!!!$[-rrrrrmma!!!!!!!!!!$'r2rjT3!!!!!lc2rrrrqp+3!!!!@HqIr
+rrr+'!!!!!%$5rrrrrm)V!!!!!!!!!!$HrIrcL!!!!!",iIrrrrqN(J!!!!@[q[r
+rrqTN!!!!!%RHrrrrrl-N!!!!!!!!!!$errrXE!!!!!"Fp[rrrrq+%J!!!!E&rIr
+rrq0(!!!!!&AYrrrrrjSC!!!!!!!!!!$hrrrQ8`!!!!"Yrrrrrrpa"`!!!!RFrrr
+rrp`T!!!!!',prrrrri!1!!!!!!!!!!$Yr[rM4`!!!!U%rrrrrrpC!!!!!"rQrrr
+rrp30!!!!!(2rrrrrrfF$!!!!!!!!!!$HrIrM43!!!"LErrrrrr*)!!!!!6cUrrr
+rrX%!!!!!$BRrrrrrre%!!!!!!!!!!!#kr2rN5!!!!#HarrrrrpXm!!!!!9VZrrr
+rq+)!!!!!(+$rrrrrjd)!!!!!!!!!!!#,qIrQ8J!!!$E*rrrrrm-[!!!!!RVcrrr
+rmi3!!!!!+lIrrrrrccB!!!!!!!!!!!"8prrVD!!!!%6IrrrrrkXL!!!!!TMhrrr
+rl@F!!!!!1FlrrrrrYLJ-,8*(24d#!!!Hh2rbK`!!!&2frrrrrim6!!!!!VIlrrr
+rjd)!!!!!5HErrrrrQdClcHrbkD%[!!!-N[ckT`!!!'IrrrrrjPF#!!!!#0Mrrrr
+lZ"B!!!!!@rrrrrrXTFVV[BCcPZUZ!!!%3Zrrb"!!!e#eX,#[D")!!!!!$CUaX,#
+H1`%!!!!!4E@`X,1ikGal(!%!"DEc!!!!%D6ri%N!!!S@&KB3"!!!!!!!!K-@&K8
+,!!!!!!!!#4F@%e,8hPi+!!!!")Vf!!!!!crVp)d!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!*DrbFJX!!!!!#,EM!!!!!"#1rmJQ!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!%H2QZ*!!!!!!"4Z1@!!!!!!%V`[+%!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!jarp`!!!!!!!SZYNe!!!!!!!&6ZI82`!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!q)r2eK!!!!!#kSmfd)!!!!!!!!$A$UX#3!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!%hHrrqA'!!HCVhfLK)!!!!!!!!!!""mkCNE!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!-,[rrrrV[Dh"jrb5'`%!!!!!!!!!!!!8IH#H*3!!!!!!!!!!!!!!!!!
+!!!!!!!!XX2[rrrrrrrrrmRiE!3!!!!!!!!!!!!!!$fA4ZdJ%!!!!!!!!!!!!!!!
+!!!!!"NI#q2rrrrrrrrrBBa%!!!!!!!!!!!!!!!!!!!K&XGU5-!3!!!!!!!!!!!!
+!!!-TMYlprrrrrrrrq+)k#!!!!!!!!!!!!!!!!!!!!!!&(@r1hD0G)`B#!J)#!J3
+D9TcBmrrrrrrrr[Qq@"J$!!!!!!!!!!!!!!!!!!!!!!!!!!NSG-[PhmHYNj5@T-M
+IkrIrrrrrrIcZY9JE"J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"#4e5QGR[lr(cpI[
+prIckq2ITZRNe%3B!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&$4FhC*'U[-[
+*`,+AG8XK%!N#!!!!!!!!!!!!!!!!!!"TG$-b!!!3M!!!!!#b!*Vrh3#KrpB!T[r
+4!+crc!#`rmJ!Y2r&!*lrK!#2rm)!QIq4!)Vr[J#@rjS!L2ql!*6rS3#'rlF!Nrq
+Q!)ArY3#5rkX!K2qb!*!!rkm!K2q[!*!!rl)!K2qY!*!!rl8!J[qX!*!!rlJ!J[q
+T!)rrZ`##rkB!N!$r[J#!rk8!Mrr"!!(rrk-!N!$rk3#3!2rT!)rrk`#0rq`!MIr
+Y!)crl3#-rqd!M2rZ!)[rlJ#,rqi!M2rY!)crlJ#,rqi!LrrZ!)crlJ#-rqd!M2r
+Z!)crl3#-rjF!L[q1!)VrU3#,riJ!Rrq%!!(r!*(r!3$rSJ#-riF!S[q!!*Ir!3$
+rR`#-riF!`rqH!)crKJ$&rjd!Lrq'!-ErR!#,riF!arqE!)[rK`$)rjN!M2q'!-R
+rQ3#,riF!P2m!!,,rP`#-riF!NIq$!*ErJJ#5rjF!Lrq)!*!!ri8!P2q%!*(rP`#
+,riJ!N!$rK3#8ri8!NIq9!)crL!#2riF!N[q'!*(rP3#,riN!Mrq(!*,rK`#3!2q
+9!)[rL!#3!2q)!*(rK`#3!2q8!)crL!#3!2q)!*!!riJ!N!$rP!#,riN!N!$rL!#
+3!2q)!*!!rj3!Lrq*!*!!riJ!N!$rL!#3!2q8!)[rL3#3!2q)!*!!riJ!N!$rP!#
+,riN!Mrq*!)rrL3#3!2q8!)VrLJ#2riN!Mrq*!*!!rj3!L[q*!*!!riN!Mrq*!*!
+!rj3!L[q*!*!!riN!Mrq*!*!!rj3!L[q*!*!!riN!Mrq*!*!!rj3!L[q*!*!!riN
+!M[q+!*!!rj3!L[q*!)rrLJ#1riS!N!$rP!#+riN!Mrq+!)lrLJ#3!2q8!)RrLJ#
+2riS!M[q+!)rrP3#*riN!N!$rL3#2riS!Mrq9!)RrL3#3!2q*!)rrL3#3!2q9!)R
+rL3#3!2q*!)rrL3#3!2q9!)RrL3#2riS!M[q+!*!!rj8!LIq*!)rrLJ#1riS!N!$
+rP3#*riN!Mrq+!)lrLJ#2rjB!LIq*!)rrLJ#1riS!Mrq@!)RrL!#3!2q*!)rrLJ#
+2rjB!LIq)!*!!riN!Mrq+!)rrPJ#*riJ!N!$rL3#2riN!N!$rPJ#*riJ!Mrq+!)l
+rLJ#3!2q@!)RrL!#2riS!M[q+!)rrP`#*riJ!Mrq+!)lrLJ#2rjF!LIq(!*!!riS
+!M[q+!)rrP`#*riF!N!$rL3#2riS!MrqA!)RrK`#3!2q*!)rrL3#3!2q"!)VrK`#
+*riB!N!$rL3#2riN!N!$r!!#1riB!LIq'!)rrLJ#1riS!Srq&!)RrKJ#2riS!M[q
++!+6rK3#)riB!Mrq+!)lrLJ#Nri8!L2q&!*!!riS!M[q+!+6rKJ#(ri8!Mrq+!)l
+rL`#NriB!L2q%!)lrL`#0riX!Q2q%!)2rKJ#)ri3!MIq-!)crM!#9riJ!J[q(!)I
+rK!#-rid!Lrq0!*6rL3##riF!L2r-!)IrLJ##riJ!Krr-!)ErL`##riJ!Krr,!)E
+rM!##riN!Krr*!)ErM3##riS!K[r*!)ArM3#$riS!Krr(!)ArMJ#$riX!K[r'!)E
+rM3#%riX!Krr&!)ArMJ#%ri`!K[r%!)ErM3#&rid!K[r$!)ErM!#&rii!K[r#!)E
+rM!#&rj!!!)Er`3#'riX!K[q4!)Er[`#(riS!K[q6!)Er[3#*riB!L2q8!)Ir[!#
++ri)!L[q@!)IrZJ#FrjJ!K[qj!*crQJ#'rlF!R2qE!)IrY3#Frjd!Krqc!*crS!#
+'rl!!RIqL!)IrV3#Grk3!KrqV!*crT`#)rkJ!R2qU!)MrT!#Grk`!LIqJ!*lrV`#
+*rj`!R[qb!)[rPJ#Jrl8!M2q2!+,rZ3#5ri!!Trqm!,cr`!#irm3!Xrr*!+rrcJ#
+Trp8!S[rF!*VrV!#b!!9RCQ9NCQH,CJ"PJfB"C'6G!)"P!QCQCC9Q"@9QCQ9RCpB
+!J'8"CQ@FCJ4PCQ9PCp%!"2pUCQ9PSQB!CB"Q!'R-!!0JC'CRU@B#CfCQb!!"B@1
+aCJ"Ra3#BCJ9PCQCNCQb%!!*QCQL!CJ"RKfB!CF)!P@B$Cf9ZFC%!!QpSCBGQ[J!
+"C'H8CTS!!@9RK'B"C@@l!**Q!@9LS3#%CJ&SDlF!N!"Q!Q9QD+B!!'U%CV8!!'H
+2CJ&P9UX!K'Db!*!!CUm!!@9PJQD[!!&UCijQXJ##CJ&RCkd!!@GRM@B!A,8!"'P
+SCfCQV!#0CJ*RCQDi!)"P!@C9U3!"CfH0CVX!"'*NC@9GTJ!#F'CPLQB#CfCM[J!
+#C@CTT3!"D@L0CX%!!@TUS`!#D@0NLfB"C@6T!!&SCiaQ!@*[k3!#C@CRLQB"C@$
+V!!&RCiTQ!'AX!!*NC'H+CZd!!@*RLQEY!!"PLfEY!!&KCBPQ!'AZ!!"PLQEZ!!"
+NLQEZ!!"SLQB!E1d!!'#+CJ"PlJ#,CZi!!'@+CZi!!*!!LfEZ!)TQ!@9Nl3#+CJ&
+RCqi!LfB!Cqd!!'H*CJ&RD*F!"QYQCQ9PCQD!C`*PBf+1!!4NC'9QCi*Q!Q9PBUN
+!!'H*CJ"SL!!!C)9P"'4i4'"PMQB#C'4PK!!%CJ"RCQH+CJ9PC@GT!'DL!!"RL@B
+"C@+(!!"RRQB#C@GIJ!!$E9*PCj!!CJ4PC@B!BCm!LQB"CfH(!!"SS@B$BQCQ8CG
+Q!Q9Mrji!LQB"D)Q'!!"RSfB"C@5CCJ*PC@#G!!"RL'B"C@D'!!"R`fB"C@@F!)Y
+QK`$'CJ"PQ`!!CBTQK`!!CF9Q!@KYQ3#+CJ&REiB!b@DC!)PQ!@GRK`!!Cj&Q"'&
+T!'GRVQB"C''A!!&VCiTQK`#3!'B!Ci-!P@B!C))!!@GRMQB"C@@A!!"RLQD)!*!
+!CS8!P'D%!*&QP`#+CJ"RL!!!CijQ!'@&!*0Q!'H&!!"RMQB"D'Z9!!"RLQB!C)J
+!MfD(!*&Q!'@'!!"PMQB"CfH9!!"RLQD*!!"RM@B!CBF!!'H3!'B!CBF!!'@1CJ"
+PP3#,CSJ!!'H1CJ"KL!#2CJ&RDSF!N!"QP!#,CJ"SL!#1CJ&RCiJ!!'@2CSJ!!@G
+RMQD8!!"RLQD*!!&RCiaQ!@9PL!#3!'D)!!"RM@B"C@@8!)YQL3#1CJ&PCBJ!!'H
+1CJ"RL!#3!'D8!)YQL3!!CieQ!@PZL!#2CJ"[L!!!CieQ!@9PP!!!CBPQ!'L*!)p
+QL3!!CijQL3!!D)pQP!!!CiPQLJ#2CSN!!'H1CSN!!'@0CJ&RCj3!LQD*!!"TM@B
+"C@@*!!"PM@B!CBN!!'@2CT3!LQD*!!"RM@B"C@5*!!"PMQD*!)jQ!@9PP!!!CBP
+QL3#1CJ&LABN!MfD*!!"PM@B"C'58!!"PL@D*!!&RCiaQ!@90L3#1CSS!MQB"C'1
+8!)PQ!'H*!!&RCieQLJ!!CieQLJ#1CJ&MA*3!L@B!-iN!MfD+!)eQ!'H+!)pQ!&'
+8!)PQLJ#0CJ&PCBS!MQD+!)eQ!@9PP3#*CSN!!'L0CJ&RCiN!!'+1CSS!M@B"C@@
+9!)KQ!'@*!!"PM@B"CfH*!!"RM@B!CBN!!AKRM'B"CfH9!)PQL3!"CfH-CJ&RDBN
+!MQB!DiN!!@PRM'B"CfH9!)KQ!'H*!!"RMQD+!)jQLJ#1CJ&RD*8!L@D*!)pQLJ#
+1CSS!!'@0CJ&L6j8!L@D*!!"RMQD+!!"RM@D+!)pQPJ#*CSN!M@B"CfH+!)eQ!'@
++!)pQPJ!!CBKQL!#1CJ&RCiN!MfD+!)pQPJ#)CJ"RL!!"CfH0CJ"RL3#1CJ"RLJ!
+!CijQPJ!!CiGQ!'H)!)jQ!@4IL3#2CSN!!@TRM'B"C@5@!!"RL'D)!)jQ!'@+!)j
+QLJ#1CJ&NBCB!L'B!CBJ!MfD+!!"PM@D+!!&PCBaQ!'@A!!"PL'D)!)pQLJ#0CJ"
+RLJ!"C@@,CJ&RCjF!L'B!CBF!!3jPMQD+!)jQLJ#2CTF!!'H)CSF!!@KRM'B"C@@
+*!!"8M@B!CBS!MfDA!!&JCBGQK`!!CBeQ!@GRL3!!D)eQ!'@*!!"DM@B"CfH"!!a
+TC(aSCfGPCQCNDf9MK`!!CBGQ!'5'!)pQ!'Q*!!"RM@B!D)N!!@4PM@B&C3"QC'Y
+SKQD!C3"CKJ!"C@@'CJ"TKJ!"CfH0CSS!!'H0CSS!!@9PM'B#CfPYM@B"BbH&!!&
+ICBCQ!'H'!)eQ!@9PLJ!!CBeQLJ!"CfH0CJ&UDBjQ!@9DK3#)CSB!MfD+!!"PM'B
+!CiS!!@GRM@B!Cj&QK3#(CJ"RK3!"HQH-CJ&RD)S!M@B!DBS!!@9PM'B!CiKQ!@9
+PK@D'!!"PKQD&!!&PCBeQLJ!!FieQL`#-CJ"PKQB)Cf&RCQ4PCf&RJQD'!!&RCi9
+Q!'H%!!&PCBTQ!@GRL`!!C)aQL`!!C*4Q!QGPCi3!JfD'!)KQK!#,CJ&PCB`!!'H
++CJ"RM!!"D'H+CJ"PK'B!E)J!!'H"CSF!!'H&CJ"PK!!"DfQ(CJ*RCQ10!)TQ!'H
+0!)TQ!'H'CSN!!'@"CSF!!'+(CX`!!'Q%CJ&SD)S!JQD)!!"PKQE-!!"RJfB"C@@
+,!!"NJ@D)!!"`KQE,!)4Q!@GTM!##CSN!!'H&CJ"Sb3!!Ci0Q!@GRM3##CSS!KQE
+*!)0Q!@GSM3!!Bi*QLJ!!CB9Q!'V(!!"PJfB!Cii!!'@#CSX!KQE'!)9Q!'@0!!"
+NJQB!CiX!!'H%CJ&REF8!K@D1!)4QM!!!CB9Qa!!!Ci9QM3!!Ci0Q!'@0!)CQ``!
+!Ci0Q!@GTM!!!Ci4QMJ!"Bf@$CJ"R`J!!Ci4Q!'@-!!"PJfB!CC!!!!&PCB*Q!@9
+P`3#'CSX!!'H&CT%!K'B"C@5r!!"RKQD+!!"PK@D6!)4Q!@4M[3!!DiKQKJ!#CQ*
+PK@D8!!&RCB0Q!@KV[!#)CJ&RDB)!!f"PBQ5%CJ&PC*B!!'5'CVS!M'B$CfGPCS"
+PK@B!CCJ!K@B!CEN!M@B%CfGPCQ@'CJ"PQJ!!BB0Q!@9RY`!!CjTQ!'@E!!&EE)0
+Q!@GPY3!#D@KRQ'B!CCd!!APVJfB"C@Dc!*YQ!'@J!!&PCB4QX!!#Af*PQ@B!C+)
+!!@9PJfB"C@+Y!!*RCf@CCJ"dT!!"CfH$CJ&PCUX!!@9PQQDR!!&ECB9Q!'5S!*Y
+Q!'@U!)9Q!Q9PC+3!!@9RQQB!Ek`!!'5'CJ&PC+!!!AeRQQB"C@@[!!"RK@B#C@C
+SR!!!C*YQ!@9PXJ!"C'@*CTB!!9jPQfB#CfGSY3#*CJ*PCQ@2!!*HC@HGCJ&PC,N
+!LfB'C@9QC@0K@S!!"S*YD@9RC@HICJ"N[!!!HEPQ!@GQ`!!$8QCPCE0Q!'6%!!0
+PC@CRVfE*!!&YDS&Q!'HLCJ*PCQ@!CXi!J'B!CjpQ!'H!C3&QBG8!"@GRCQ9PCj4
+Q"fGQC@9QCf4Mh!!"CQH#CJ9PCQ9PCf@!Ci"Q#@9RCQ9QCQGQBekX!2m!r`$r!2m
+!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m
+!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m
+!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m
+!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m
+!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m!r`$r!2m
+!r`$r!)%!G$KYD`!!3!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!-+%"BeBSDPa0IQmrrrrI6TfmL`QAP9-4N4$!B
+"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!"!mD2ALai26iqI[mrIlqrrrrr[lpr2[kqIIfiEQ0A#XA$J8!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#$L"+P0Iir2hqrrrrrrrrrrr
+rrrrrrrrrrrrrrrrqrIckp-U48b89"`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!%'6Z&d[[qrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
+rr[lmjDCH+K3%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')e@Ulrr
+rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrqr2hrrrrrrrrrrrrrrrhLQ%mM#`!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&+@'kqrrrrrrrrrrrrrrrrrrrrrrrrrr
+jl1,BcFA"ZUqPU+k[XVc%bY(Fk26rrrrrpX*`-`i!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!"*@+rr2rrrrrrrrrrrrrrrrrrrrrrlp[)Y*4d@d%R%`B!!!!!!!!!!3i
+I-%YTL+Hre1Vlrrr@J6d2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'eL`q2rrrrrrrrr
+rrrrrrrrrrrRLaD9i6LJ(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!K9"E*Dlh2Irfi8
+p#J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!#8#ClrrrrrrrrrrrrrrrrrrrrZ5kM&`X"3!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4T5Kl2KrY9q-!8!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!#4fe2crrrrrrrrrrrrrrrrrmF@5A5-%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!'P@5c2I"CaB"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!K(Ur,rrrrrrrrrrrrrrrr
+rlE*c03S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!S
+jGVcPS$m%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!GGYEprrrrrrrrrrrrrrrrl+0H*!)!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+Qql`fm1!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-k(
+YrrrrrrrrrrrrrrrrmUKC(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!5eaX*-R!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#9,$qIrrrrrrrrrrrrrrq,KG)3!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!-hJ*T$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!"&Zh2rrrrrrrrrrrrrrrGef+J%!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%56AC4!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!BLHMrrrr
+rrrrrrrrrrrLH23`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%*9*2!3!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)D2arrrrrrrrrrrrrrrHCK`"!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!"$M!Z!`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!5HbprrrrrrrrrrrrrrqXcd*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""!(!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)Y[IRrrrrrrrr
+rrrrrp))L!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3%!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!$,XAlrrrrrrrrrrrrrZ9Q%3%!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!bc&qrrrrrrrrrrrrrl46JJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)Ta2[rrrrrrrrrrrr
+q[MX#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!")Vrkrrrrrrrrrrrrr,Nf!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!"QYq2rrrrrrrrrrrrZc-3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QIArrrrrrrrrrrrmXLm
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!#Rl`rrrrrrrrrrrrr,Xf!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!0
+Hj[rrrrrrrrrrrrh(3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3GIrrrrrrrrrrrrre%m!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!#@kr[rrrrrrrrrrrq9Q!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2NrA
+rrrrrrrrrrrr`K3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'EPrrrrrrrrrrrrpk3B!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!kb[rrrrrrrrrrrrh+,`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&Tcmrrr
+rrrrrrrrrkP`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&SkIrrrrrrrrrrrrD6#J!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!0F2rrrrrrrrrrrrmaL3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!f(qrrrrrr
+rrrrrrr&8!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!5YcrrrrrrrrrrrrlT`m!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!"ZGrrrrrrrrrrrrrZ8f!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!#bP#@'0VEQCD6MJB!J!!!!!!!!!!!!!!!!!!!!!!!"8e6PKMDfpPANXd&!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!91crrrrrrrr
+rrrrkK3S!!!!!!!!!!!!!!"-[0MBf0MBf-4m%!!j#Hkc,eplPk1VVkHALfp'qQ@)
+N!!!!!!!!!!!!!!!C6iZkcpVLjHMUkqMQiGV3Y)!m#J!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!##RrrrrrrrrrrrrrYXP!3!!!!!!!!!!!!"
+'ZZ$Ji1$Ji1$HfXl!dH,`qrrrrrrrrrrrrrrrrrrhkYDA03%!!!!!!!)eMXrQmrl
+rrrrrrrrrrrrrrrrmmH1jAa%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!"9r6rrrrrrrrrrrrmH`S!!!!!!!!!!!!!6Frprrrrrrrrrrrrrrlrrrr
+rrrrrrrrrrrrrrrrrrrrrr[ICH3i"!3)UNGhfr[rrrrrrrrrrrrrrrrrrrrrrrr[
+YZ$d'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"qRrrrrrrrrrrr
+rrp`R!!!!!!!!!!!!!$[$rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
+rrrl`U6`ZJGIir[rrrrrrrrrrrrrrrrrrrrrrrrrrrrrli9m-!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!5[,rrrrrrrrrrrrpI3`!!!!!!!!!!!!GS2r
+rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrklqlfr[rrrrrrrrr
+rrrrrrrrrrrrrrrrrrrrrrrrql@8+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!"LDrrrrrrrrrrrrrq-X!!!!!!!!!!!!!&$Trrrrrrrrrrrrrrrrrrrrrrr
+rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
+rrrrrk%N%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11Irrrrrrrrrrrr
+rNa)!!!!!!!!!!!!!DrrrrrrrrrrrrrrrrrrrrrrrrrrpqIVqrrrrrrrrrrrrrrr
+rrrrrrrrrrrrrrrrrrrrrqrMlrrrrrrrrrrrrrrrrrrrrrrrpbKi"!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!eirrrrrrrrrrrrrrG'!J!!!!!!!!!!!!U#rrr
+rrrrrrrrrrrrrrrrrrrriiF+NUmhXr2rrrrrrrrrrrrrrrrrrrrrrrrrrrrrqlGD
+aSEEFm[rrrrrrrrrrrrrrrrrrrrriH`F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!*-IrrrrrrrrrrrrrZ4m!!!!!!!!!!!!!&jRrrrrrrrrrrrrrrrrrrrrrmk3
+k"3%!%Q$(qIrrrrrrrrrrrrrrrrrrrrrrrrrrrpT`'!)"!bD*irrrrrrrrrrrrrr
+rrrrrrrlA'3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!01rIrrrrrrrrrrrrp
+U#3!!!!!!!!!!!!!PX2rrrrrrrrrrrrrrrrrrrrkj%J!!!!!!!$@qrIrrrrrrrrr
+rrrrrrrrrrrrrrrrjBJF!!!!!!!KJk2rrrrrrrrrrrrrrrrrrrr0@!`!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!%TArrrrrrrrrrrrrj63!!!!!!!!!!!!!!$6)rrr
+rrrrrrrrrrrrrrrrrk@B!!!!!!!!!!%hDrrrrrrrrrrrrrrrrrrrrrrrrrm!Q!!!
+!!!!!!!jqqrrrrrrrrrrrrrrrrrrrqCi'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!MfIrrrrrrrrrrrrqR(3!!!!!!!!!!!!!!3Glrrrrrrrrrrrrrrrrrrrl%&`!
+!!!!!!!!!!TVirrrrrrrrrrrrrrrrrrrrrrrrF3S!!!!!!!!!!#R2rrrrrrrrrrr
+rrrrrrrrqd`i!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"%lprrrrrrrrrrrrrfS
+(!!!!!!!!!!!!!!"2pIrrrrrrrrrrrrrrrrrrmB!!!!!!!!!!!!!!6q$rrrrrrrr
+rrrrrrrrrrrrrrq3m!!!!!!!!!!!!$RrrrrrrrrrrrrrrrrrrrrrU+`%!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!2NIlrrrrrrrrrrrrQ2!!!!!!!!!!!!!!!!'(rrrr
+rrrrrrrrrrrrrrrrK1!!!!!!!!!!!!!!5arrrrrrrrrrrrrrrrrrrrrrrUb%!!!!
+!!!!!!!!!4[Errrrrrrrrrrrrrrrrrqp4!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!"M0rrrrrrrrrrrrrkiL!!!!!!!!!!!!!!!)H2rrrrrrrrrrrrrrrrrrrX8+!!!
+!!!!!!!!!!!#Pq[rrrrrrrrrrrrrrrrrrrrpd#!!!!!!!!!!!!!!ZdIrrrrrrrrr
+rrrrrrrrrmQJ#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"-I2rrrrrrrrrrrrrI3X
+!!!!!!!!!!!!!!"54rrrrrrrrrrrrrrrrrrrdLJ!!!!!!!!!!!!!!!(M[rrrrrrr
+rrrrrrrrrrrrrkdJ!!!!!!!!!!!!!!"kSrrrrrrrrrrrrrrrrrrrcG`)!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!GPqrrrrrrrrrrrrrYA!!!!!!!!!!!!!!!!)DVrrrr
+rrrrrrrrrrrrrrqT2!!!!!!!!!!!!!!!!@qIrrrrrrrrrrrrrrrrrrrqr,3!!!!!
+!!!!!!!!!&)lrrrrrrrrrrrrrrrrrrr@&!`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!$TRmrrrrrrrrrrrrf6`!!!!!!!!!!!!!!!!Y`[rrrrrrrrrrrrrrrrrriKm!!!!
+!!!!!!!!!!!"2j2rrrrrrrrrrrrrrrrrrrjNB!!!!!!!!!!!!!!!2Jrrrrrrrrrr
+rrrrrrrrrpj!!!`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%mEqrrrrrrrrrrrrVL3
+!!!!!!!!!!!!!!!!jfrrrrrrrrrrrrrrrrrrpa`B!!!!!!!!!!!!!!!"%iIrrrrr
+rrrrrrrrrrrrrrh8$!!!!!!!!!!!!!!!,H2rrrrrrrrrrrrrrrrrrpSi$!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!Hkrrrrrrrrrrrrrq'$3!!!!!!!!!!!!!!!%Adrrr
+rrrrrrrrrrrrrrrLE!`!!!!!!!!!!!!!!!%(Jrrrrrrrrrrrrrrrrrrre9`!!!!!
+!!!!!!!!!!!TfrrrrrrrrrrrrrrrrrrreK`-!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!%2frrrrrrrrrrrrrfF!!!!!!!!!!!!!!!!!9[rrrrrrrrrrrrrrrrrrmh!#!!!
+!!!!!!!!!!!!!5Z,rrrrrrrrrrrrrrrrrrpK"!!!!!!!!!!!!!!!!$Alrrrrrrrr
+rrrrrrrrrrr4m!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!C[Mrrrrrrrrrrrr[8J!
+!!!!!!!!!!!!!!!K[rrrrrrrrrrrrrrrrrrrZ6`%!!!!!!!!!!!!!!!"@jIrrrrr
+rrrrrrrrrrrrr[#i!!!!!!!!!!!!!!!!5LIrrrrrrrrrrrrrrrrrrmQX#!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!#'qIrrrrrrrrrrrp3q!!!!!!!!!!!!!!!!%SVrrrr
+rrrrrrrrrrrrrrqX`!3!!!!!!!!!!!!!!!',TrrrrrrrrrrrrrrrrrrqM(!!!!!!
+!!!!!!!!!!"D8rrrrrrrrrrrrrrrrrrr[9!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!+ElrrrrrrrrrrrrZ#X!!!!!!!!!!!!!!!!FSrrrrrrrrrrrrrrrrrrrj4)!!!!
+!!!!!!!!!!!!!EqcrrrrrrrrrrrrrrrrrriN,!!!!!!!!!!!!!!!!'k$rrrrrrrr
+rrrrrrrrrrq`q!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`rcrrrrrrrrrrrqH'3!
+!!!!!!!!!!!!!!#Hqrrrrrrrrrrrrrrrrrrh0#!!!!!!!!!!!!!!!!!#$mIrrrrr
+rrrrrrrrrrrrrFJ!!!!!!!!!!!!!!!!!LX[rrrrrrrrrrrrrrrrrrk58"!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!$6rIrrrrrrrrrrriX-!!!!!!!!!!!!!!!!-GMrrrr
+rrrrrrrrrrrrrqkm(!!!!!!!!!!!!!!!!!*Mhrrrrrrrrrrrrrrrrrr9I!!!!!!!
+!!!!!!!!!!#V'rrrrrrrrrrrrrrrrrrrJ$3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!1,qrrrrrrrrrrrrH`%!!!!!!!!!!!!!!!!mmIrrrrrrrrrrrrrrrrriN38!!!!
+!!!!!!!!!!!!!V2crrrrrrrrrrrrrrrrri%d!!!!!!!!!!!!!!!!!-GMrrrrrrrr
+rrrrrrrrrrF-)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!m[lrrrrrrrrrrrpV!!!
+!!!!!!!!!!!!!!%crrrrrrrrrrrrrrrrrrr9c"!!!!!!!!!!!!!!!!!#rrrrrrrr
+rrrrrrrrrrrr02!!!!!!!!!!!!!!!!!!jkrrrrrrrrrrrrrrrrrrkT3B!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!$rrrrrrrrrrrrrpPm!!!!!!!!!!!!!!!!(Crrrrrr
+rrrrrrrrrrrrrme3$!!!!!!!!!!!!!!!!$XVrrrrrrrrrrrrrrrrrrlJV!!!!!!!
+!!!!!!!!!!%,qrrrrrrrrrrrrrrrrrrH'"3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!2lrrrrrrrrrrrrS9!!!!!!!!!!!!!!!!!q#rrrrrrrrrrrrrrrrrrr`03)!!!!
+!!!!!!!!!!!!NdIrrrrrrrrrrrrrrrrrrSaN!!!!!!!!!!!!!!!!"8rrrrrrrrrr
+rrrrrrrrrp'B%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!q2rrrrrrrrrrrpe+!!!
+!!!!!!!!!!!!!'*lrrrrrrrrrrrrrrrrrrqXC!!!!!!!!!!!!!!!!!$hDrrrrrrr
+rrrrrrrrrrrq2#!!!!!!!!!!!!!!!!!PYrrrrrrrrrrrrrrrrrrrb4`)!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!$ar[rrrrrrrrrrf%B!!!!!!!!!!!!!!!!KZIrrrrr
+rrrrrrrrrrrrqe`d!!!!!!!!!!!!!!!!!9Z,rrrrrrrrrrrrrrrrrrhX!!!!!!!!
+!!!!!!!!!%BMrrrrrrrrrrrrrrrrrrqmS!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!1[qrrrrrrrrrrr83`!!!!!!!!!!!!!!!#R8rrrrrrrrrrrrrrrrrrbi#`!!!!!
+!!!!!!!!!!!"[krrrrrrrrrrrrrrrrrrdC`!!!!!!!!!!!!!!!!!CSIrrrrrrrrr
+rrrrrrrrrj"%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!fIhrrrrrrrrrrmmq!!!
+!!!!!!!!!!!!!-r$rrrrrrrrrrrrrrrrrqTN*!!!!!!!!!!!!!!!!!)Rdrrrrrrr
+rrrrrrrrrrq*8!!!!!!!!!!!!!!!!!#'krrrrrrrrrrrrrrrrrrh($!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!$&r2rrrrrrrrrrbcX!!!!!!!!!!!!!!!"$rrrrrrr
+rrrrrrrrrrrriH`F!!!!!!!!!!!!!!!!!Srcrrrrrrrrrrrrrrrrrcd%!!!!!!!!
+!!!!!!!!!+G6rrrrrrrrrrrrrrrrrqkJ+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!+rlrrrrrrrrrrr&0J!!!!!!!!!!!!!!"PlrrrrrrrrrrrrrrrrrrrGF"3!!!!!
+!!!!!!!!!!!'irrrrrrrrrrrrrrrrrrqp,J!!!!!!!!!!!!!!!!!blrrrrrrrrrr
+rrrrrrrrjL!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!N[VrrrrrrrrrrmNk!!!
+!!!!!!!!!!!!0Hrrrrrrrrrrrrrrrrrrrp6d#!!!!!!!!!!!!!!!!&mArrrrrrrr
+rrrrrrrrrrkSE!!!!!!!!!!!!!!!!!%,rrrrrrrrrrrrrrrrrrrGT"3!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"Xq2rrrrrrrrrrccm!!!!!!!!!!!!!!"5Brrrrrrr
+rrrrrrrrrrrra)3%!!!!!!!!!!!!!!!!ad2rrrrrrrrrrrrrrrrrrP`F!!!!!!!!
+!!!!!!!!'AIrrrrrrrrrrrrrrrrrrpNN$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!%Efrrrrrrrrrrr83`!!!!!!!!!!!!!!'l6rrrrrrrrrrrrrrrrrrYm6!!!!!!!
+!!!!!!!!!!%cFrrrrrrrrrrrrrrrrrrq%!!!!!!!!!!!!!!!!!!elrrrrrrrrrrr
+rrrrrrrrd+3%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*2$rrrrrrrrrrpT)!!!
+!!!!!!!!!!!!LdIrrrrrrrrrrrrrrrrrp`!m!!!!!!!!!!!!!!!!!CZIrrrrrrrr
+rrrrrrrrrp(!!!!!!!!!!!!!!!!!!&*MrrrrrrrrrrrrrrrrrrqB@!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!8brlrrrrrrrrrhN`!!!!!!!!!!!!!!#RZrrrrrrr
+rrrrrrrrrrrbL$!!!!!!!!!!!!!!!!!#!m[rrrrrrrrrrrrrrrrrM@J!!!!!!!!!
+!!!!!!!!EYIrrrrrrrrrrrrrrrrrqb4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!fAr2rrrrrrrrrR8`!!!!!!!!!!!!!!1[hrrrrrrrrrrrrrrrrrqi-*!!!!!!!
+!!!!!!!!!!*Vprrrrrrrrrrrrrrrrrp0&!!!!!!!!!!!!!!!!!#25rrrrrrrrrrr
+rrrrrrrbU$3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"f,lrrrrrrrrrr9H!!!
+!!!!!!!!!!!9ArrrrrrrrrrrrrrrrrrrkC!B!!!!!!!!!!!!!!!!#Vrrrrrrrrrr
+rrrrrrrrr`M!!!!!!!!!!!!!!!!!!+ZrrrrrrrrrrrrrrrrrrqiS+!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!",rArrrrrrrrrrf`!!!!!!!!!!!!!#h6rrrrrrrr
+rrrrrrrrrrrP'!`!!!!!!!!!!!!!!!"Lprrrrrrrrrrrrrrrrrrqa(!!!!!!!!!!
+!!!!!!!!mr[rrrrrrrrrrrrrrrrrkE!F!!!!!!!!"$#Y$5N-S#3!!!!!!!!!!!!!
+!!!!A`[rrrrrrrrrrI!%!!!!!!!!!!!!3NIrrrrrrrrrrrrrrrrrrq#J"!!!!!!!
+!!!!!!!!!--Vrrrrrrrrrrrrrrrrrrk!(!!!!!!!!!!!!!!!!"PRrrrrrrrrrrrr
+rrrrrrrP-"!!!!3-FCDI8hq6Qj0r+M6!'!!!!!!!!!!!!!!aqr[rrrrrrrrq1$J!
+!!!!!!!!!!"D`rrrrrrrrrrrrrrrrrrrN'J!!!!!!!!!!!!!!!!"*errrrrrrrrr
+rrrrrrrrrM3!!!!!!!!!!!!!!!!!,Grrrrrrrrrrrrrrrrrrrq#d"!!BTMYR[qIr
+rrrrrrrleiB!9!!!!!!!!!!!!!McirrrrrrrrrkBI!!!!!!!!!!!!'mhrrrrrrrr
+rrrrrrrrrrXF9!!!!!!!!!!!!!!!!!',Prrrrrrrrrrrrrrrrrr4h!!!!!!!!!!!
+!!!!!!"'9rrrrrrrrrrrrrrrrrrrS'`)BIYlfrrrrrrrrrrrrrrrrp+-D!!!!!!!
+!!!!!(F6rrrrrrrrra$-!!!!!!!!!!!!Lk[rrrrrrrrrrrrrrrrrpP3i!!!!!!!!
+!!!!!!!!!H[(rrrrrrrrrrrrrrrrrh&-!!!!!!!!!!!!!!!!!&l2rrrrrrrrrrrr
+rrrrrrVNF3-,er[rrrrrlpI([m22lrrrrpii2!!!!!!!!!!!,F[lrrrrrrrrL5!!
+!!!!!!!!!!$,lrrrrrrrrrrrrrrrrrq)i!J!!!!!!!!!!!!!!!!#6r[rrrrrrrrr
+rrrrrrrkP&!!!!!!!!!!!!!!!!!!Fd[rrrrrrrrrrrrrrrrrbD@rPr2rrrrlej,0
+e6MNqCVR`r[rrm%X!!!!!!!!!!!!`jIrrrrrrrreH!!!!!!!!!!!%6rcrrrrrrrr
+rrrrrrrr[BJN!!!!!!!!!!!!!!!!!!kMrrrrrrrrrrrrrrrrqa$J!!!!!!!!!!!!
+!!!!!!#6ZrrrrrrrrrrrrrrrrpU'Fm2rrrrriei8Z"J3#!J)$$(VTrrrlY!!!!!!
+!!!!!!"@@rrrrrrrrri%+!!!!!!!!!!PZrIrrrrrrrrrrrrrrl(N3!!!!!!!!!!!
+!!!!!!!!EZ2rrrrrrrrrrrrrrr-Y0!!!!!!!!!!!!!!!!!!!"1Icrrrrrrrrrrrr
+rrr'hX[2rrrrpjTXZ!3%!!!!!!!!!"Clirrre!!!!!!!!!!!!!8McrrrrrrrrVb3
+!!!!!!!!!#R$EhGhGhGhGhGhGhG*S$3!!!!!!!!!!!!!!!!!!!#@SiGhGhGhGhGh
+GhGbe2`!!!!!!!!!!!!!!!!!!!!4'fphGhGhGhGhGhGhARl$crrrrr0&N"3!!!!!
+!!!!!!!!!5H,rrrm!!!!!!!!!!!!!(+ArrrrrrrrI2`!!!!!!!!!#'Mdq2Miq2Mi
+q2Mir)!3!!!!!!!!!!!!!!!!!!!!!#5ir2Miq2Miq2Miq0a-!!!!!!!!!!!!!!!!
+!!!!!!4)p2Miq2Miq2Miq26Z4m2rrrrZk1`%!!!!!!!!!!!!!!!!CeIrrr`!!!!!
+!!!!!!!!#8I2rrrrrrrpK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+'FZRrrrrkXLF"!!!!!!!!!!!!!!!!!!V4rrrr!!!!!!!!!!!!!!!IUIrrrrrrrjJ
+B!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&2FrrrrrE-P!3!!!!!!!!!
+!!!!!!!!!'GArrrm!!!!!!!!!!!!!!!*@lrrrrrrrfcF!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!ba2rrrrl)-J)!!!!!!!!!!!!!!!!!!!!lh[rrr`!!!!!
+!!!!!!!!!!"ZHrrrrrrrrC`B!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%jR
+jrrrrjNd&!!!!!!!!!!!!!!!!!!!!!(AZrrlT!!!!!!!!!!!!!!!!!%MGrrrrrrq
+`)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"Qj[rrrrf$$J!!!!!!!!!!!!!
+!!!!!!!!,Y2hrqkX!!!!!!!!!!!!!!!!!%)Mrrrrrrr",!J!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!--$rrrrrbLJ!!!!!!!!!!!!!!!!!!!!!!%rJrrrh9`!!!!!
+!!!!!!!!!!!!!0F6rrrrrrjmB!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Z%q2r
+rrrpU#3!!!!!!!!!!!!!!!!!!!!!3U[[rrXmF!!!!!!!!!!!!!!!!!!!$CqRrrrr
+rl8%"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4YErrrrreLd!!!!!!!!!!!!!!!!
+!!!!!!'VSrrrlE!J!!!!!!!!!!!!!!!!!!!!@QrrrrrrrRK8!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!"+4rrrrrrq9&J!!!!!!!!!!!!!!!!!!!!!mbrrrrmSK!!!!!!!
+!!!!!!!!!!!!!!!!jb2rrrrr`8!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4phrrrr
+rrf%&!!!!!!!!!!!!!!!!!!!!*Uhlrrrf@3B!!!!!!!!!!!!!!!!!!!!!!!*Pirr
+rrrr!'`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"53!2rrrrrrrdB!!!!!!!!!!!!!!!!
+!!!!GQrErrrqG&J!!!!!!!!!!!!!!!!!!!!!!!!!-M26rrrriH!S!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!%MMrrrrrrrq3!!!!!!!!!!!!!!!!!!!(jRerrrrcM)"!!!!!!!
+!!!!!!!!!!!!!!!!!!!!FVrlrrrrP4!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!DQ[rrrrr
+rrrp2!!!!!!!!!!!!!!!!!#qTp[rrrqa6"3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+fbIrrrrh'(J%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!P6Zrrrrrrrrri84!!!!!!!!!!!!!3K
+3b[RrrrrhF`d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)e[rrrrLH$`!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!V`2rrrrrrrrrrh6X#!!!!!!!!!JBTP1VprrrrqiB@!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!0Gi2rrrr&p#J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&)Iqrrrrrrr
+rrrrqaMi0"`B(#4!aLpcjrrrrrrbD(`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!4bjrrrrqYQ#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!KHmIrrrrrrrrrrrrrmlDGdB'b+`Zljr[r
+rrrrmRb-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Gjk2lrrq4D#!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!%4q,rrrrrrrrrrrrrrrrrr2VjqI[prrrrrrrrqD%P!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!Ckk2lrrq0H#3!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!cR0rrrrrrrrrrr
+rrrrrrrrrrrrrrrrrrrrrrr5A(`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!Ciirlrrq0R%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!-kb[lrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
+XL"B!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9Qf[lrrqZ$'3!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!'3-[qrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrphR80!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!92cIlrrr5J,JB!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$PMCr[rrrrrrrrrrrrr
+rrrrrrrrrrrrrrrrrqFGA!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!3lY[Errrh&9a)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!#0fkrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr+U1J!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%KPHErrrr
+NL6))!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!P
+#U2IrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrcCIaX!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3EFrrrrrmaQ`M!`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)YGYIprrrrrrrrrrrrrrrrrrr
+rrrrrrrrrrrrfXe%$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!(3+2VrrrrmE&Q*33!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!%QDV[errrrrrrrrrrrrrrrrrrrrrrrrrrrrrrpd(iQ!3!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'@r
+,r2rrrqfdF6F'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!F`FV6[rrr
+rrrrrrrrrrrrrrrrrrrrrrrrrrrrrk*e'"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#$U-i2rrrrrbaT0C*`)!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!aj@MF,arrrrrrrrrrrrrrrrrrrrrrrrrrr
+rrrrrmUYF&`%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!"*-S1crrrrrrZ#mPQFm&`!!!!!!!!!!!!!!!!!!!!!
+!!!%--Q+2Yq$mrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrp,9N)J-!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!F9+,[rrrrrrrpk-khQhPG3LXF$3-!!!!##aBQ29CaPE()jI[rrrrrrrrrrrr
+rrrrrrrrrrrrrrrrrrrrrlkeI*`8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"(%kFk2lrrrrrrrr
+mm1,9bF+lY,'aXE5j[mI5hZcmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrijP
+6)38!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4NmIXlmrrrrrrrrrrrrrrrrrrrrrrrrrrr
+rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrfa(Bk'!-!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!2+9@Eh[lrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
+rrrrrrrrrrrV3KdJN$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""8U@*M
+8q[lqrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr[lpm,Yp4#-3!J!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'%KmmG+MApI[mrIlqrrrrrrr
+rrrrrrrrrrrrrrrrqrIclqZUpLPJV'3d#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!)+%KN`9hfK`q(bp[Ihq2MjqIRjq2MhprEcj-QXL'%
+k(a80"J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!)'#Ji5&Kid6&eQG(f%JACdE&e12#3@%a!,"`)!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"TBc!i!!#,r3!!!!aU8#!
+J$3U(#J!!!"4QG(P`DR!b)!!!!!"UF$)J!!!!6fT`-QJ!!!!@D@KNFJ!!!3!!!!%
+!!!3("`!!!!!!$f0[E()"!!!!!!!3!!!!)Q0NC@B!"!!!!!!!!3!$!!%!!!!"!!!
+!!J!#!!!!!`!!!!"UF$*Mrdrr83!b!!!!!!%!!!!"!!!!!!!!!!!!!!!"!!!!!3!
+!!!!!!!!!!!!%"`%""`%""`%""`%"rf3!)`!"3h*PBA4[FMSJ5Q&c8'9b)&CPFR0
+TEfiJ-5ij-$!Z-Ip5!!`!!!!"!!8%"!!"re`!%d"!5%K35%K35%K35%K35%K3red
+!&!&!3%K)8%K)8%K)8%K)8%K)82pG!"3#3%")5&")5&")5&")5&")5&$rA3!8!d"
+!5%K35%K35%K35%K35%K3rj!!!!S!!!!!LV`!!Iq6hi*J"l@m(b)#dNiZG-XK4XT
+fj("!6"*11`1B(l$Qkqed9FE#b(q-T,ibMdae$mZk9A)h9`5UFC34-iA)$S6ME#!
+ZM1LLV$CLP-V)b-mh2pq#3"'!BLMAq$EfbNC,-F)D)4AF0daZk&fM9U#-'$E`F!@
+abff%[(XFj0,chV4NmP*4I!+(D*f(,6"6#r[Fq&`j@28*cL89XF%#$pq!+"&39+0
+[hi*J%B"0FE#'U1X0Q-Y,T*e"Z3$fG@)iI3G%eYFPKTk&&@G$,(+Jp@S!"-I,9FH
+Z"pQ!LU*XXEK,Vc&!pV@Q2j!!cRTm)25i`b"NZVhR&b[IQMhjT-r01"U)S)!,jKp
+Ce"3V2Rp9F98$qBK051ZL#M!YdHfZLV80FPfIDbYY$[VcPeh3I4B'V38)LUr!1F"
+Q`2Cr"papc"%lbNlR-mj9)N92TjHqU$I36FqK9S"l(,S8-X*dDNfChdHE-R[pdQF
+T3p3(E49DVB[C'&YlGZeX8)94l5kV8lPIGHD@k"BbhJmKb8K'!kK$EbJ*$KGc8kk
+$RbYhhm"NiAhDmRJ-iLbT1&4UJaL`aKMVXr92T'42Z$Q%MG[I-,FKec-AA)J&@"[
+[(BdadY1cp`06QBVmH4*2ib["+LlpEmr!pRi(XIJK!"U1iTD(Gr`+G%jV6NiC*0H
+S"FLdRI0N%5CV[-,)qamI9FM,9`ZT-Pb,404YaUmek80DfaUG9`Sk23qDR+JL48q
+RPlkSN!$G`bUk6*mpY&DLAG*fQNPL568"$AU!VVhrFAirA%QQPSG-V!RH9%b9jkb
+GK10'*T&J2(f`@eY,p0D'kk16ZJi%PGjB!CSa%,JQ[@3lDpb&HLJ#h9F%r%Q(9Nb
+)"4+Q"VGRXI*XaEh)BIpYrGBpXIXm[+**#qhZjB$IQMAjSmr0-"U)S)!,R!XGE[d
+'2F(Hki0cF8Z6)d)k!4p@03H-AeB4GcC0cKEK`G1fH"&14V2YI8()0mJM!*c3RaV
+4"V"Ik#G"P%FBZ6JL3PADR)Xqh08hqV*jP"BUMJM#BN&QAAR,53IU+QGSU@a8VVr
+YP'lAkI2*XZrL9&Y,`ldc1GpakeBdhN&D9DAC'fPi+Pf,6aDHQTpf9-A4+&02E6H
+5Sf!m((iCYd40UXfK82)%GD+mHGXU#@8@2)@cVQc"-2hP1mahXUjh`UFJaUT"!a4
+c2)b90%!'Xqhc6qhVIc[2`Zkr1jjqGe"P1d[Dba"*DAR@1+[56P1mEbMk25iF-`d
+elZA,a#ME628I1iVMYrEP`Qql`'cqF1L''f'L-8$CPNhcJhkr&DTP83F,16kcH9L
+DiVU80ILUP!-I'jLb[p*CHXI8S%@I"2&4N4Z-$,TNk,H0SQ*3-pJ&-Q((VTa&rH'
+6(PXZ0K66b%-)1a#0f-I-!i-mQY-!0%"GpJ3lKCdA!K)LpE'Z"EM-"$HdZU$PlHh
+rF1jXRbhRVYEGSM46-,d""hS,'j[Yq8J'P"E&Xl,m&`Q15fMEH,6"cXD!$G80)61
+GSI&4pQ1ZZX$hdPVKY+5bY)jCRHfI5d+D[,CXKh5jjDS"r'PhG*h&(!JL`IBbNQ-
+E,2XLiJ8$2Hl3X3$98Kc3[`KRh+Jh`#LeFBdhQ9A+Pj-G83kR'IMQS@M#(1Kb,dV
+h@!h'TZV1"D'[DX#NVQGN(J)U(IXCFGBjSdB-e`Ad1E2U3i06i55k9S0dj)DYhB(
+I4ih*[a,3R!(dX,I8iV"rZ@fQ+*!!R'cGk`2)CjaRUAL)j*IZ"9D9,MRE8lDhjA9
+I5EEKk0Yl&(8(@#H`qT9%T1BmIRjh`m1NGk9(HD86&,aF#[dFC8cKLAkHBeP,mFM
+jc'[lF!4c%AKUpPA8fb4IZTNM6S0F1R22l(M0S['fmrU-[iNfV0(CIETLJ*dNfDr
+dAjU#C['aAV$K&Tbb!I2IDLHR6b,cKm+ALI*CjM5`Dr8`mC6+[kpi#fM3*P4b,la
+[GXSMAR8#Fl5IfCM'HMb9&qp0*Z,c+'J5pNZaR9QK&@Gdl4cSa$Mr5pf*`[99*8*
+Mk5$Za6d'qV`4EI0h&4+(j,C&pML'mBrTkB@3!(-10&Q(#TUM,V()f&J'4%,JUI!
+VZAmLjZ+#apGPYcL(cY1lR*NNGL(akcD'Z[aBA9pDI8-h@RL'mdj2bmBl*d#8fei
+h,A2D*[5PPB[(ff22`X'(ff%!CS(VVRii51(eA@PkJ#39@JrSFph'C&2#a5JfZpD
+,qlCX,Qr4pr1MhVrB5V[B")T0Qq$dR@F9qr#(5-S%X5h$dKMSi%4[C`G'B4GJ2Q(
+r0j*dh,lF-DfiA0Qelr0&$M+$J(Lej*D(DlqG+5NJMA#PR8(F2FFIC,qd`C[[QK*
+UiJbemqKlkm[0``r)r`+Ml")i[PNK`TRfJGfZEG-*"13D-QN[@(3aVM[e&NLc4X,
+!FJTXQ$`#INS4#UMKfYm)b!NM9PK!Ke%(2jZhKrFI%@1j+42dD+$ZFD!U,dp#9`P
+KaRN41@,SdVC$KiNV012La6"PF11+AQJShYcbjr-jBG)e4P@2A1peZ,SiXY,DV(E
+0`12YcHrhB64[4@1#h2hcBC8#1f3"UR-3lkVCN!"NddU`cLc@+(M2r8d5cf4GdED
+drE8rf'd'lZEePS%9eEG$$C!!4A[!dP89SSmJqm#3!&$YH,r,m[1$meIqJ,H6a`q
+fa"@k8cckKZRR)@Sk9"*Yr$UUV6emc`)DYfTfp`mGp2l(6#RKA$9%[TrF[Q!&*3#
+LI'q6BbDf56UDDPV4bf(INQlJEkmiNrVXB8*hjh!%UG2"6Hq6"Qej$*N9j0-J,fP
+dql$DD0#[,KmSfb&,e'0UfbY(QKG@aI`iNcKN&jD21LcT6,)'Fb`Mf#JiFq*Z4X%
+PDS@)3Fq&aG,(CS1E*NrX[NFcIq2-4FR@jqpIHi(V%#LNNEYMXUk+GVE8%9fD,)Y
+`Z%h1*0P,e%-Bha+%F2f&"`JVl2ea"dZPr+9FiRI3ci$2`ZUr1h*qGcKPH!E&d'Z
+pV&N)6SI9cZS4R&qL%AYjI'ETfC!!c9l%4D1MPDIjPcI0"1md6N`eIC`KFpXc,lM
+9J+%8[S(DM1CPL16qZ5T2Fie$''FiUBh"&mjm`39@pfc!T@LB+R(C-#Xq01C-h`l
++qR--)Qj$%X[jXqhYAaPk+fame[V[6a-kSkcfBTj#ZAja"e`4H8dFAKCb+FCi"Jd
+F9R4Z,LiM&ZPhkH$hp,mJSK"cFS0Zq3k,r4K9eaU(jmjP3[EjM&Z[#R02M#[PJS%
+`AG*Q[K38ELXM9f&1&C3DNrf'6Q@,4)fQEJKIhR"#C%R$jBcI4MpAr[3#F+E`"aV
+5,F%T&DdMNB&Gi!dZ)rDIf,hfI444mR'PU[6q!CN'*Y!eL'(V2+%SRkF5Hki6J$S
+&jbR*!F4K,e(B%'CYD0)5@P3ld[LM%4Y18+icUb6'5PJSR95N)k*5@!BENCZ4-M`
+Fb##FMfc0'CI"XZdH*$XD4BSNjEfKKbq2%Hhc2T)!VVK*!FqP'Q$R0Ad)l4-M!IN
+Ue&BD5d4rVR8I`U1JReP+(p)G32IDGF&1YbSb*f`4CL`b(5eJU4CU8X*krSc+l+`
+(QieT950D0V3EeQm-D`FH)*PUDPqckq0%aiDd180@UDrM(i0U"q,,aKr@1[pR8TJ
+JQPhaAdU&hrEcMC!!!CJH#K*+j8`C-,,"NH6$[+Z('PlBUU'@,2,'q31UVXb$-HN
+V9q)$@I[Yc09Afk#k5+K-cfN%Q)Xafp2"Lc&!Q)c*`*0Fhrm*qq`G#fR14H)'P(C
+B@%ARJkCb4[f&d04S8AP`6+m1PM88PLBh8iXaA#RrD`(ZpPGf23BGkPAlEQLrCk*
+*0pIcI&X-j1$[3`lmL%`iH)Fii3AardXMMa&pd`Np(%Q@#B#aXaB8ZdB@Rh&Pdf8
+9NV*e6PqQ)cr2`kHVmqR1IRdkJ)r#k[&AGa-4VHk"eDq069Z6Q(c(*%-QJd6bE%a
+KQ%P%(I@f4Jhb4S``9'k45@rKX'EY#ZMT'aZ[FQ@(N!!Ym6R*A2H*RTh-p[0U,pk
+P8XR1ikD6D[dYQl@i)JkNf9kZ@TZ468T4UVA2Kip&'#hrKQrLL9Q5,R%d8af-bp*
+iV#N--D%J)!(iS$fiRjEN-V3P&4+5NcUBTd!Z,Rj)Y[NHar+C)[aip3,DFSDSC%"
+qMdN(62)&,GL0U$!86'GREp`%8je&V@,f2[H!qCaq#il+@XTCd99Pb2VlSqTp[LC
+3N!$9HKXrMS+D&,h(&98BmVkPXaFKFaraTa+PM9d1jdT#fVIakDXC9X!c("$004@
+IVhfLRBe$[pa`$-%Ahmp&*H6m-%#kYMQVRaP6S8ehSPiF+p[,01qqSaP%S)p(-JC
+Vf6(qDjLjNEfYZTN-ReBf5Jj+dIdmNkK&-e6ZEI"UmJQ-Gm#4DKPhjr+)$Y(&9rf
+`VBI4-ai5GC8H1-!#13V2jK8l@0C(bq'l23QPDId&TrV'5qBZRhG4C@%bI@F'KbE
+4)%1&d(cmX+!BHMdHAR0EM#NmH`Kb3$0%'`+054J2BjXKM5BeLA5Q5fA4T1T@REa
+fC"halVhSZ#dmB69+%dK,6YY,c'T2CIc)V'aCp#BPf3hrA4[5UVL(RpUJH(*P#6,
+PI3*')&2l5"D9J2(3&iYYRpRG@-T3k9RbbG1l,K8L0#6GiVDQK9YR*lDYL6Eak@X
+9HQ#*bj[aS9K1*fdMNa-AEjbKlT(e`J0!iV$mPI8[NrG1JISYcVPZV%IG5%K[",Q
+[-4PPkGVJbp0pS*bEV1L*Z6'+m8q[GcIBLf)PpLmCHB9J0cR46mX[['XQAUVLimM
+KG1-[m(%pb-YA!REc!V0G'L)ird$TM'+,B,fTddRcXAQ1QGAS)rST$m8l*jTa'43
+['02[iU,BQHQ[K+kES)E4TqG*!C0kXmSbE,)Mk&$RIPl,'1[)0jX*BlC*#QpPbAb
+cE2)A,21YMpLTfXqLaKDMN@r)-Mm``l%CE8B"[kX0aF@X,NCb&r+Gi2pJRV#0Y-4
+fZ*dV2Fa81a`baZr'LT`*iL"@K*d[CF&5`-#NrVY9UPq*"32mmR,ZMZa5RG!b)k)
+FQ5l&@D"lr!B42rIPN9+e*6@kbeTP9M48MIH,B"EDj1fSLa@Y!k!I(cKNl,AclJr
+@D5EdIZ-6$6L$S"L)@k+b!m1l-NRDD00LLr[*$h'k!JfHUl,Pjfb!dQle445N*0*
+h[aedqMb'8*X+NP'e4'A!AKH@0CTRY,@8bNj+5hV+K)$#B#AK(h2YYGS5F+2fjH%
+dEf5S"+[DcBK"@1cDM'p$DNa+ElcV[V-b@`)a,E$+brJC$mDP`"ll1IPmPS+R(5K
+JVIL#0+)'(4!@kXeVk!lL4-"6UB-T1LRA3rJ83GPapF*)1ADqiFh1UD*31Y"pH%a
+f)h1XX!bl8h%F4rLh+)PC+*9&-2%-65S(QLAhm-m"I[Qmmcf4m$EjpmF0QqB*$VF
+lP+mA(*D,9YfFbYXJi%2AR*l2S"1@p*J$Lr-+HUaiI-'#d5(G*kMMBp98#U18@hh
+(Y,RI5*(kKl9,&MG&l)+8bke%6rSKqe`1,M%qU"H(Hjfc'F(ck44M5cpP$a0!9hR
+0D#ec0G3['ebqEAU#YUpH4#c9+,e"(rNQTF&Z0f4`h4iL9SC#YKGK(XX['rJc3XF
+ZcUhZ+rj5aP%Upe[&L[ifm!*B+eMD,PMG(Dj&8Q4#qGk[!h(qR00Lmc3RPrU!mh9
+AkMBUm@j*UrPeeYA#D+QG9j3Y'**1M$,qaNmpXQlbN!$Gq8-beN3PE-bSEN&KGJN
+H"Y1P#6*[-R[k+BPrZhTh`(DhR`8a4`(5d&bEF,NmYYr$b*JcHlfP%qK!C*mN5D2
++9UjA&+LIbPbbL%BDTI[c'kIUTNJfMG(%6Z+qm@mSd51TX1(N!6@`!Hf"r00ifQ,
+"Vk6dBV&FrM$ePY(Ja1iFaNBH9f8[B%ZIFD$5m$AEAY0K3HK2D6TIiAIR1d@A2`U
+`MV[N*Y5'Z`&raT`M'kr%*i6L&M"BqD$99djMA4RY1L-ckJCQ*-RAXhDEa9ar2CT
+[TSKb2[ic@CTk[lKV"-F%hF+hSkU@2QHl&+R@Z#d!p6E2fi*NC(Z68A)T'D@+YBm
+klT%0h$dMPkE++G0QG4''5@9-K(fcY#HQ4H@+Ml)JSA&JD0daDmj,Fd!dC4P[jM"
+Ej'6-ILZcf'b2r1p1H%X"!dpQk0,LY0a0fmc@p&Dm(M9PXHQAbe5QCh5N%h2aZGT
+)-)FLB%Z,M!Y-Zjb"l$A1k)XG,eFG4HFQUBV*cepNX(Zh$54bF`eJ%NZPj1)$pc$
+Mp*jXB83LJ-S2AmV$6ih("QeMVpR"JTB2f&8m)YLC66b'f`&`80l&h"5QQBV*mUB
+41Rp-JQ2'!$q-h`YqAA)#+8M[8pJb1Q"5pB`'JfU4qr0r8QifK0GV@eIM$[j)"S#
+)eVNq$AE0a',j8'8Q&HZiRG5rE$'@1j,Cd9%&e2+Ndj-bjSa0Y444AmIEd%6m0qS
+r$S%!X3-UYmJRGr,RZkJi1rde'TIi,XBUBZK-!9mLbbRKS#,TiiFB9d$,"M#bA-,
+CUk[%JBe1q%+-MSjYSFa!449q"BGFYpjf6X"SdCT!drfa&Sed9-qDBc@-HFCIaQr
+MrA&r3T@8R"+D0H`B+1m*8#dJ@j9IL!Hjc(9frSd1@)Q@GNaBYk)Rj+lZ3!RAZUL
+@N!$Z3-BcdQ1mbGBSK%06aGK[,Y8)EcA[dXUa)Ur*b3EPl-8(1QYGDF&[Bed+Z&9
+NESS6dGGTUNr3IFlXeSaIKJCM1MR[Fr%Rc"4rU-f`UETdIT!!KhC@$S0(Gm0D4LJ
+mY9L16YaR'`+ddZMf1DYL'm,m%j&TMS$cC30H"JpB9a()TP3@'(caIKDJ8%'K95&
+Vfl-SMDVHr[j2)d6-RV,BrCCB9JMc6mC%Z-d8Rcl[rN%6A`3GL#,CCC%k'P8dVbM
+FmkLe0d3F$T!!l*M*j41di5b1C%LeQMimD*DpQGU+HKXB)&9DGiFp!%CCY[3r[dq
+6Na+aQb(TPfJ#$DCJM)aP,Rf[3NFbM!lm4PRLP$#(T4156*85R*Nc5kSGJE1T$,h
+l#i)a#%'4@bP2a&(ElJ*h[eHC@r86rPf"iCrYEJDLHBpMP@333h*)J3JJjIVG0Vh
+-C`#!JBLHe%"(6C1+"1LcD12U$f4P$rbH'#AA[N9+QFPb`K)P*@I$J6h4'XcfEi9
+JBXh5hrB#kp4A"!@#Z4A%!#8YTKlKJ)cJKAG@,NK")lD8$(AcBa0pA`1eYI-CGk+
+)"G#X+H@8&&M#$DE4E4(Q)KBV()GVK4f-&EI*,"HURGbTGe(J)bF4%EKXe8+5G##
+IIUM8iCP3p(3`&A&k)#N[TYj0aiFLVVf4m)Jh9TImSA3[AdJ1e'@2rLTi4T8"XIT
+-2SI6lJGMN[6&bF6T2b`+J-FQfBS3-qlm5a%4)H65,U1+i0bYTVpa$k2IUaI9b15
+-jQQ"61BHE8cNrJ93!YSDe9pKSMF*8M9%VFHT*kJ1[F92HJK8iclB$Nb+Ci&dPE'
+"rV1J[*YS)*fQ-+cc16Y(XE5@rSjSUpP[&QMD*Q6r3'*5eGipYJrfh8@CHkR-p4(
+C0GMm`dQ2M3$U!EL+p"#k9Nl3CHd#R($'G#6iqCU%S(LqRQV,))4MU0KRHCUflJ0
+Y+JDpd2Pb2[b`[eD`*@KXlRPIpiI)aQ"'cUkN54GU%Dj@bDXi3GGZTLU,c*QSck2
+!4e%HYHb*NqAlS(rVKRB(c2%XeDBB6'ebKT8S$+I!ZpAL-R)rYD@6)@'pU'c&SpV
+T8r6P%Ci`lC-mM$1J8&0%6@YBSGIB!*jGerc4-AI50aU+S@iK%$+B2ij&,GqDb'U
+'PHfmZ,X`8r*N#86[FZ`P!RX36NGNElDrKNCrPV(a(E(,F0cL$m2#lUlaZ`FAY-0
+1)M#U&aRk-dL,$jN1piMV,`m[E9UDEQK&CK'#dhqcr0fEA!Tmm[`HQ4V,A!XYPF8
+LAY2,q%LiDkHR&kY"&GTI2Hc'BAL%!%2-qT&3,*9BlTC[$!"0k5!G@I@Z1FRIiZ$
+VYjBq!Dai-$)e'Ipi-,dS("@VAQ3N'c-aGiPja8TVaY2Lf")2dHd"IRrD1)iQp98
+"SDZCP[H@"P&6pqpm2A5[*@fhSd@#a6,aP0)F4@BXdN%Yi65*T6BXrhjj9[YA#G[
+CTFbC1%Fjard4JUZ3!*695k@hBbr*&0Vh$"Li08HB5HS'[m$1RapT$FN+RT4Rj+b
+B&@H6p9*6B+-RS-SSMC%md8VdRF)(JXabdN'LDr$B-aV#d'[!`0+[id-JC(D8fAb
+V&Nk!0ErZDC0KNddiQj2jRcV'l4iRZ1h&CM%qZ0ZQl#&SaL5`qF($G156caHJC!Q
+f4RLXcEF@9eeSp#a+pX`(l33kPCVD!QK%D*f90(E*Y+6E"HdVi9Q@rTEJ9GlZ(ll
+SK9kb-0N44Zk9!4ZG"Y1&FGUUV$X&1pf@iZ$lB,UC!%G21T+lKakbm0cYi3@3!-5
+QfaLJUe(bV((#`JDQaBjFDD(k4S4R@IZAB4pV46qYd+FDbbd`!I2l-pJNNjfmi5q
+24,kiH&XNPfTqC0SH6cq!cm1P5r2SkRjp(i#[U@ia@B$l'1F9hi+cUL&A@i,4#cl
+%BBI-3-DPT6JPJrR&DKf&CmiR!&c&dIprY@L*I2A'%KXFiqVmpPKKf&qNA5DD3p1
+eE8fT3K1QX40p8A&2`&)*H'@4Y8b'J8Z4bI#3!)bE9ieiiJ`YAG!ZUaDTP`jbBR2
+(R'lAiL5Sp$i2V9()9*Y"A*fl$%CkN@r(d`3TmZfCV5jMmeM-Zk4C6CZPZ5qmd'T
+MUr#b8(0)h*PiPaa%'UN,'lqhcV#8AJH%ccp%p`8!N!!F'Q!l#22`qKTYipd8%k8
+P[SHBp1-96Zp*H-R!'a0J$P,E6'[qR-T2j-6BC&c[4DX9HF&B6k@m+6ZIHX+KD)i
+fI&(XJ6[V3`qR`Ai@0f%SkJ!Kc"3AJH0pcf(-Xja#I+'"Sb[UIF[Le&De18meAq*
+TX(IE*Ci!$h+YAXf!E`-9R1P5&"ekH*qD4)Z%qMpZ2R[!@1NlaFT+0!0e2DFMN4h
+&iCa1U9R9-4dK2'K)8md9Bf2'S1`"%VRC98DD1d3"*-@ECDbl"h,6c49MK#0UeGD
+10bT`'5K6J[,#-p+k!PVHlA`LDi5pG9r6G!lVVUQcpYD6UU-91J*DU9jMQjHpAIF
+QHM6D!C[MN!#3!'IcV`lB+TM[9*bH19mmSS`R1HAi!`&5`dTUb8P(FLQ8Qj5ariR
+cND[H8aa8iXi*ICHlQV!6mJNb)kh,bP'khJVr99rE8Bq9-$da*#$lZHfl-c[1drA
+0$aR&dBQ3!%J$`MJ$Bf@8M0"kMU4#c#"Mr@#hK'LLNDlfT*Vi$0c4lL2aN3b$GZ1
+0+5K"JSr*P@qChXTbK6*b!%bemrD52+Qc&))f5M!3eFp$2"'K)[U8NHMPc2SaL($
+)HIS@IF@+8R9&XT'64YL04kJPp@3ceMej0m[q*IfI"iek5Sa0mHbAC(ZHS)V$K`4
+U[j3Uf84P'3b(U5JEiEZJ2N2qHR!G+L4TE,Ge&Sia'5lCJBQTLN+a949hSS!#5ia
+Jc0%BHP*H&[#1Y3f,2lBkXF+heF0N1$Bej[iNbXm-FN+!b+"-!JpQ!"XPN!!##`q
+hRkcI*ZhkiK02h"eqbEA%1&(ahiS,`XPD'@'L,CUc45@A`q4'4lY#MS`KQ8'0Mf0
+Z,4p3`5(BX9kAr$Y`J-K$1@BSar()%9fQ!AG2"(iX(`lF"#!RBUXGEmMYGVG54CH
+p4acm(NkkA5-XI928I*L!2@K4m%PA8TrC&EMcjD-)iS1cE0%h[!!e4I1H3K6-'25
+L,lEq@hlFq&MNlTcQKS6@*JX54-B1Q1MQ`4+ihhKRh9SBkYB25e@REfrq2+SSK[2
+4BS9QkCZ,R`0[+BM1d*r+NFmZ00cL@krC!GDY6RUZ'JeVqlp-r81eHBXY2I)P*dI
+p,a(cPKUBh4Sd,Tmb1LECGi+GVM4jR262*Tp,$pQeLieL)e&p[`4TZqpNhS'`*D#
+YTfRk$m3U(`,NGmTL-TJKSMiNI83PH43885q@YN6q("'q(Y#$S1[H#l5FHU`BSE)
+!pqVi'@ikmmq&Cr#A4Gq2hZN4Mr9DMe@1MhN*Ki!j[i#SeI2MRdjm#P1%T"bJIiC
+'CeM0AC+ZI+m`C9+VT)#(D&BEZbK`Tk(k0c$ikfkqB+6cTk@02FTPl+BaLEhphcK
+K'M2PS'$2V1!mJ8(FUN`4$%jjME[VIT-D'$#'8AMjP92&TLJhlcflXpJ,F[-`klT
+j,arjCXYNr)%R2H)@`)G12e05+TM!PpiGdG+ID[E*i#UrIh[pdM,rIT*,pGBR$Pd
+$5f6+"[amaUphPI-+XmXqR&(KG2Cl0liEhieHARm'bVpr!+bA,3e"Bfk%r%4NbZF
+P(c8V5LKk,$b@M`PrVmd8HZ[NFS($%D+BIeXrHeqcK3k!TUA$SiA%9[#AVYq3!,Z
+#``ASEUIk,Na+JhHU`M5rjJSa!1Y2#Qfr,PQCG4A9+6XDDlHLbmiCBJ9lMG-Q4E,
+HjS&IJhj!K'-"&iq*ha#,Ia8$Ra4B)R2J(2,r3Ur"-"D2X#B@p6P[[-9+GfRd*ZN
+2b8MBM)EcM'Y"e0(VXiBH%%mpQALS"0Al51&mD(S$A`!3&+BYN5MLiQ*ZC4F"-SM
+U@V$HpfMAVB543l62-LfMI*TX,qQ"Z5EhifEk+PHUHl)`pX'NR[(+6eqULREh5rm
+*kbc#Vh'Xm5@hZq2Q"Eb$81k3!-j'r(*'AVEIUT8[6I@Y&lUK9UANUX1`+G65Qc[
+YJF$2(C[l4Ul,V'LY#0653FhHkU%*S%i'a14`jcK'3+'D$5d4a'2'hUYicHGqH&!
+LlpjP$3PJemD68bi!QSBKINal[8'"2kF8J#fpA[fj+rX!),Z#(i"ljlI"3rp5hcr
+2`p61r2e5Sr$e#pq`29qA%A59+MGBCl,02Y3Y(h#'qXqprdJQ2P%L,&NBKlF"ekf
+3!&Qe*#*TaPpIh($p#LRAL5hHVLLlfS5@(#SiZ&,cr"rFJJ(&5!I2AF*8!eEdB0)
+p3AT#5h4kRNBrcJJ0XG5+L$0-(1LBKSL#5(2K"1jjRQ$)$S6dVKH-[*1YQdV8)pp
+IAN3pTJP%mVk%#*[qVR$GTQ@1$"SiY1!Kj(Q*+k)cBISI53iMEjh5+h`D8I%!j6K
+I24*Fi5"QJ3b+QVAei1TiQ##k9JdT+dSUA[&H5F#@$FJ#ELX,(SIdHr@I#qRNYC0
+Jc32L5PYfbkAS%3H&MIZ6V$9eC0$e*-JFQKfb)dGN9TC6lRCHTq@(#E+@0!dVJNq
+FFZ,'N!$MlT1N*(5XKhMkA*ea`VN(@Z0p3SeI@%($l&8iXAQYhJ6052IF3-)#hGe
+1@QF5[`R''KG%ULB3iJ`2C23F2r21Fh%'jJ&CEGI(#i[eZqN&Z!5+JJhrHdbcBpb
+UM!2FS"BNl4c)XhJI8C@%YmE,-I-pd`m9`L3J2G4ZcYMP$)F&4QcQMQA65GP!NZ,
+DR*)LEB!lFl)[fM[`#RRJ#!Q9U!`ATY'-fRP2$kZm@5Vm1Z32iJ1!GUDLH'1*REc
+p256r"4P'#@cC9+!qk*,2DGDUY-[%AJF"Uc(&1ZPhblS&'M44)U%#538l%6lG$fc
+VPIdJ-!Jfk8Y-c@S[JYB@j@"cY82ml*iTSX9aBT*QC%9r$Z5Pd`eefH-PElSLR3J
+pc5*a'GN34bT#DG+3!,6i4b!qT5Q8@)*I#"l(%HrN6dQIVaiS2&jM65Zh),br!-1
+iZR*e+C2h2hT,CHb#@Gb`C!28fLCfNeE$)BiI`+VjE)fd+#@Bm(A0,f@S2Iac$'8
+`VNc[&',0LU2V(!e4'YD!dq-i4(H+d@X"YjqDreh*h9+TdL8!Y`4D1Lp(i+`AYYJ
+KVGc#8UAb'BmF-`LiG9a2AiSeJGB#CkHkf0X4T#+%6HG9"`bF&Yiah4"V%qkhcY1
+eiNG0ClK`jCa9h#A[4Y+jRe6Y2V2HA`0A1%!f##,2X6FjGY!Xk3mRmAci6DpXZip
+3V(4R8MTbhU-Pe!$Z8F@+,,+bR(aDUJ@B2,-[["3@MdYiY*+6jk3b*p00E'1e)&K
+QC0-8ATM4P@Uic86(5DI+ZbPb-LbPNrF2%4HmVLji#I%E`[A+#$SacU5e-KcQm26
+mDGrkIEl23P"@e'Eed+9AP!k#P0M$ZLL@'TCDT)MThD%L%NeXq,TSq@T'X9`*'@j
+&VI-[PR)PF'hZN!#%-)%dRENMJi@-maPh"%%m'("P)TeiHm2YCBJ+E`k68-A'IXp
+80BIDUe$aqJ#JkR"(ZLChR@dZ99`BaUmVf(`3Gqh9CYT,K`c,iPeR2)-D4Ypl1fX
+1i@+kjL&PPm')"6%[&KeCQ9a[Fq4bfd'Yq,NTeADV'd$d1,fMEHl!HVYR'R2FPMr
+!SQ+XlJdA49JqK$K(JCjl3(X,iEikj(61bB1eeKM6qp14-06HJVF@NPEc-L$KRQ@
+b[ZY$"8U%G)XUb!YV!q9[P@bU!kAG3JU3!"JP9)1,RF%33[%kB,N+al,Vr*DlXH`
+e63-!QY`1a0A4Fp1rRk1hd,"e8H9p!Im)2"1+b3,k"1b#Jj-RN!"TKfFEFGRP``U
+hNV``E5jScj+j&6HBrhDfG#aVBChjXDrpc1",1r+4Z8m8&j-P@h"$C[2![-KFqUC
+2N@!F'AqVY5R5L'kAL9(Fbq1(i-"N%#h$CT,eYdKhLP&0E&E*)PN-f82ifi+)jem
+2%$%Aq'iq*mGKQj&V*+c3X`GEX)fA6amQ46Jd,Hf)EFK(AdT+S'h)(LdZC3BI3Eb
+iPrpm33Z$JHeamfmeEM,ea*hb)i9L8afdIdS#Hjj[(NMNFCN0D,mVkN[H896kakj
+43b2RJKmQXS(4m#0[c((ZrIh+Gk6$2UheXZ,Jj&bN4m-&RqfDU#30@UU*JZ)cHHh
+46fbiYk6@EH(NHbGCrMSPHqelS++J#9AC&j*TDYQ(IP`BHYZAA#'6XG3Z,pIlBT!
+!PLeFbqQqc3#MD0CQ'RDlbHd"B2j([ZVMRj+IKbJFKi4k8!pKbcl3$VN`422mcpP
+8lD&$K1IJ9MP6[(R)Ypjk[CJZ1Lm+N!$UQ'"SD*H&&95PTf",jbr3`9Ne)FZ*30Q
+k-ech(Kje(jp+pBUl&5CDl4ZTD8APkH[%ZckF0c,"QMRkA'SGjqE!(dpDCf+rmr$
+&LA@"m-%rJS'SUL&djrR'3'!+,L@)mG52berrESpZaI`cT0l`[lA,Q(b9M6KSF6i
+ZiTVYrUZ8@qfie3BAlU([CLSR2MQr2C!!C'ThVCK&R6dTQBb%*,KJ5dR-j@DVYT!
+!!"DKlbYLP@LSbH%)cCB8qp%h+iIZ),$-Z8#3!,(2"c5@MHrpN!#f@,h08[lUdU!
+d!De-96p6a,YbVhJCdcElrCaTI`BF5L2%dG$&1P!VbdpiGKIR2,&F[ZGibi+K4mj
+iBA5QQ8Hf!Gp'ci`ICd)QK-C"eC3(qELA'5@9ZdNU*%e9-mk*e$3Y39YeF&qhMAF
+TR++D!Ml0XqCe-G-2ES$NC33XZNbQZ'j$0LPQqQ[T$iAqRF9PK@Q1,A,$91RUk'P
+(4$[5fph@(LmfheS56`A845Fa"dZ#)0mB%Tp0b$+"l(MN["r3P@BffiAp59"kE1%
+SRkBc*rE)QVYG%&55br$6FJKK!Nh01$`04[&rl-$I+MrR8(PI4J#NMLKDY4)fl`2
+,RLcSE`aqAr"m"59"B[F*bVikj0(TXXM[(ZLEj,5LRmZ3!"1rV!(NQ!*Rp1l@NAI
+(NU'jDf'Pl6h15QQr43ciY)@hYAi2R`%ipp6rB*40@*Lf6N2Ge9U`1VXLhPPX(AR
+!RLXe4X+kS!l5IJ"hjAHlp9Alp1[B"8aNQP*5eFMKe',XC%mmS"dj)+I8N4#2kA!
+!`[j5+@,Y#k2[AR9#Z-!)9I"HVAQJ#(DkK3d*0&NBqlb435MPXMJ&AdC6&pr#eLk
+k!f&VIFcF-9j&+2VZBjq4ch$J8+FdPF"G(FpX`KT5Z0e$6UhbJI[c6E$"ADVDc(c
+PklMp!5SHAXDCPrjh"Dp5"F(i(p**(NKd"TY2Vc0i%X+L91#hQ(U"&b5%PK(FKiM
+8!B,@&jjCQCLF5B0G`%CfiU4KEj9G[[l8(1E$Hh,hdL0CjSr%'FBA2mmX#VjUi@[
+EeJ@)e[)NSf9)FGG"QSPULh0bY2FTH80SK*9N18ZQAE4@A%j)@Re*'E&A'!i[@'a
+T@bYRcTTq0qKCR1'eJS%kXMXIS%QDPUM5jrmmT`*-0RU#QZ@'E9,+LJqRF)aT"RQ
+U%G6ICqpZ81h56d`lbqNE#N&2&Z64'dSaci!'KqJVc3r3(DF1b&22&65beD4@NZ-
+Q5Y9Mdmih%V4EH86maUUBAI3C9IF6mAZR0k`-f82`+GND9#Vl9QmhH*G4(GjH,1D
+UX[dZZKC","d2)l2GNFLdCfcqCUk[JkPP!D*h1R"*@AT3)3Nh2MGXCl'++LTMkfp
+(NZ35'U"-S'HK35j)iE0UHP[iaSG+8ihjdrTQB"H1GF!!P*ZMG(6[GKm,59"Re6N
+-kGdl!,*Pc5`mrF0NkB1[0eF$CCq9lQbA((iDaJNV23YR`T6qIJ,di+K"e'"!!H-
+N)L%5j`kBD"'NNmZh'He$L0d,!KbE9k!EK)4%2Im*hJ'pD+%JA@V,Y3VZ&4F9cTi
+E#2TVY4[MYC3iNq8Dq%-9"mE*UhkL'Q'mf`mLT5e%#"%DRdpC)Q)jeB'abNpYID+
+Smma+E3bcF0e`Mh`j$A*p%4V0)b"9p$%8[0A@k-+GA2Pi(EpK2F&MF(he&E2XH(j
+fYr(aI&69Hrm[MlI8,2B*K#+Z8MIB)qhT0a,KQ4l+AS!keR+SdD@IMr8*b3U(1Aj
+#hAYc6HNq@#HE()S#+B%kqpLi#J!GRkPkG11E&C-lI`3aep([al(e1*phj0XT1#%
+CRFZP"C!!*93NmMfrm&0jT8iQDid)TZ2!KIN6N!#%)3jTm5M,@Y@c"c'i29&MfQT
+hmbVHc[D!AUAPqriX)"`95F@r56UMJ-M%lrCk8,F$4pS*`f'bpQEi,KVL3c['$pf
++9cU!80K*NC3VJZPRYb,`BpG-&45bfMIZp'#ee1`+C#DMSTpb(9QH5DSf2*j[*p`
+K'bcM[mP#kZM*DUZiHdima%9(Z3+LIh*k@l*+BFA#2%TA12[9IQ)pbp2E4U`[e$-
+ar1H'-TYl'r*`3qMZEH3,5Fi!XBd4H-QL6DE"aD`q+lc#`,Lr*le,HHKCA4H+*Qp
+edFUF#f0mG,!A2aiiDH`-q8B2,PcLMVFjQM2DVqEaVkFF,`JmdF4bL%ml&YKdC+h
+lBq-Y54+"jpk4B[3[N!#hRkS0"XHE@@-Zbli3QIdmq5&N(Tdlqj*RL)6Uj`9jBF)
+3,'BhjLHBKeAfrGQZ&,$G2i*%b"-F81k6S`qI),i+Sf"IPMh+)X-&TRZH!0)90P(
+a2XkpCr4hUS2i[-`jJ5&Fpe428UYAlqXZXCE2TUj+c&-J"b*e&'L5"l(ElU6S3Mk
++$45X9LbiieZXb1H8*HXRUEKK*r#a8MVQ[5B8ldQ3!(lc*pj[1cNer+4UdpdR-cr
+9F6QL)bJBMql4bppUppTkBJ[PkIJ)3%(H1*mG0S`3)NQFR''h9NKmAhfPfUE2qGR
+,'BDDTFjlGr5LA&Tq59qN%,pT!Lci@pfc`+!Ee+pf1qiPa5XF1IZHb*80@!ki[1e
+mSL+*B"$X+V6bfBE+Jj5$ckYpCe5*aHD0Y6TiiXFdkE0fhX4JfC@HK,0bRNH8e1a
+$U3bMRe%P#pP$mELNFhi)Gqlm"Ca`4ZGjLRN1D0!VY(PPiqdlMHNY!V&k&E&Rr,&
+C`q$@BBp1TRJ-G)+@48%(rVD[%Z5CX8NPrHrdV2MNlheG'J,%$q)'fU&@pqdNd!b
++@#d!ITK!SV)PSUUr60C(02CB'TGaqKHbl4)bD9r)DV)f!cC58JI1fGeLm9XZ!rC
+66+YZ`TXANlU1*6PD['ak0YqVd&ZqZS3riN(Tc`'I*'`LVfRAFHi`YC9'D'R(5"E
+,i2DPVN4Ak$9#3E!iXe3hZ2ari@i92m5-JV0GQG"qRh*'TH&)"SkbqriB-Ma4,b4
+Z1A!eTd94-C42&e5B8EjVKlZR#1h)IDFKURMeGd"Qe4f@RPCP`#CaIfTk#92-f%E
+bl"i,0hEk-VL-!38fJZeV,-d1UA+XGD''0h4ZdLkN&6D+&9R$k8eC4G#Q1k"0Jjj
+GQ"[k+9e1lXX*QdSrbd%U-NQ0YPf*2i1-KKh[U4pGh[&5Nii@R-`4&+(QK`$-[V@
+)8V!r0"LD"`12hMjf'YbbCbaGKFIEk+FIEk,-2Yp%S12LqNBhbYPq*`UB[5hY36i
+fh5li6m#hK#RF"0aedlrc!3XhV+4q%#cmFY9pZfa"L2BYZ$q2T4*+TT2M00HS6D@
+NI3HdHiYNjVmL#*N&9#pdD5m+G#@J1lN!Ti%$1Ed&ZcmEN!$ZlUSiH3N1il@(hJA
+lL3@L(B($B#(C)aAh%*ITQRh2b"9Ch)!2qhZ@[FmhHHC4VfJcpecfqd,KX"Z@5NC
+ScYTD55-bfjkd8VT0,me"8"r[EGiGJ`U2"&h#K,5#["a`TKCHSfL%0hXP-I,T1)1
+`jY"@3b![ZcB+3j*4-!XC)#6hYT[-&FRNF$HqAb!i!$e+Cj[BB-c"XrNDM8lF&[k
+m`Dk+r1GGVkbVk'Y6ihcMda2&,c6#A1[UrT(#AP`CIMUX%1Ym24-jfr`f2d-[%'Q
+*eH*k0CaLH`U&ZGZN4NT1A3RdFK3#(k8,'aTpjfX@L#DU$44r$6j('PEB,F[mYjQ
+[G&KXC)a-Z[fL5+*3&(VJ[q'%h15$,9$A-hJY8&+8)#HaDEep82J(KY)C(rm`@pX
+LQaU*J["p,[ff)@hPDq,14HZD+Cr"IH%)9@JG6*IZ*CRip$[U0015Rhm")l40lbA
+h3Y*4KGBMpRrlA(8,-KT8llQU)1M[S1,Q)1XXfkbeB(l6hkYBXk3kU&aS6*q%T"4
+HceSap*R2i%+DN!$DMp+!KNT*q'BLZrUS+cUrkPcS5bd@NUifDPeKRh"LiCRJk[A
+MD`N0Uj+(C8Qd4PkNj)4#hr)iDiQ4#L)G$$"p46%Slm(D+fCQT4XrR#qd9%kT8B1
+S8qa$R@m+L*F(fh[)QA+0Uc%2r4+XeNV9"MD+qimlVe'%EE)hh4!lbX1#BXNfML"
+8D0@9[kf"*Bh94,pUV0EaPr`aU[@,94YXl"eJ[D1KqSK4r%D[qIpBA@R&RSKA%db
+TCF5m0SfNECSXMX6I&rB6ldhf(DD+l!%D[AU@$T4hDPhZq5bdGDe0Tp+qQaPiR@e
+hQE%JC$[XXkepK',T-Z5FJHR(6qLIHfNJCa#1mfFk`($T*iN(k02,8VKkqF[U'$p
+VFmXmk6%q"T64M&IT9+@SHRE2Z')*Z#CVq(hIJ%DAZ6!1,BD)HTP'C-m4MddX5*C
++lN*UV%m"+#JH[DEJXG[NfD$+d()3B,*-D)%-qiEK'3idkle9S!Y!r[BlqQ55%!R
+h8*&FrZ6RmkH2,$DB9X%eD6r5IHZJ%kmC%4Fe"+p8hfKmB916Fq5QC@b41$R"mhr
+[35HX4Xp60CGT-#Jmh,jT6V[('X$bScG1(XC++TGpq&#R`B+T4UEGbp3#Er(+6Vf
+mI6E6*klHkcQZZ*!!J[KBTGm,M-AH[%9cLl8KD*iibXTFG"CKrN91V20&`@[9#+G
+q,f&R4[m'e3PDG)b`+MAj+5XT+5FBBBBrY!`IHKV#C[-iq,+b(M`"+L9aZfZ#D&5
+,#$+$&6c8Y&QeLZir5BT'i1)e8%qB9R5E-4iT4j1YFDI#,YhX2i*Nk+%r00*YKEH
+IkNd&TIp1'2j(j$QfS#4dZX5"BlU-(M$E(EEY#2,2ZQ@1-6'0(@mDSfkP2aDHe@X
+8rc8XB&Z-`!,aialr!$p,Id2h%aJ8KBf)0K(pV+91[6*&iZh5QJ$BBfRMR9Q%B#+
+aNCi2X4A[%DKTRI3p1paTF@-kT`BE4Z%hF5b,5%!h$XH3!&[h(+kAjXkdR'Y2$p,
+#RSIG'T0q,"M"eTICYA*QqSZCdICE4qRQ2Z!jTE5Q0cD,5RP0ai[H0aVpEYp)"GU
+cEBd)q8JH5YSAD3kP(LR490,"Q94Y!SdD%YeihPi!k-3H*1PPEbfZ&+ACG&1$QCN
+5XlaE&kJL&[`1X+l&6%rd*,bqJH2pL65L@aQrq8c&&*@!P9!LU$b)G[[LU(14Hdk
+N6S-Y+N%Ir0IBiq&6#U@'J(T6UMd(*+NPhXX$KG6qTY!"5H99H#(lc(6,5$p30dh
+SE)6RcPX01JCGVC,[6Ylbl2a#)UD$aJl@l`VMXT+FXEf2hF@qcSFj6-G*24LP$c&
+J+c5MAkf4iX2-2kIX38mM*JX&(lQQSdA5)dY$Mrq#P4eYC"QQIFkK3d`6DeVj!6&
+L%6EdH!@CS&b['-Cm9ar%JBD`q9FMAR+Nr#Lp3%'hP,fV)8HkJ&"%AT[H5hhQpG&
+Kr%h*hp#$cb)BmD@E[m0Aa6fQ[P26QciS84cIeR(mde&UFHMj!4a,DXj))dD'M)E
+6L"bR+GB0(qil*a,LkEUNqTQJceb!Z6R1i1+CJ98(2`"QfLfqZI"8Ui#3!$(ka9M
+X(34`1SmImDBSEeG#"8(MU%"UCTVYKYU91GD(e"$@pRf$IU[fIm2"(*H#p@`**LX
+dLrarH*k'RHZ3!"dTcDU5BI`qmN0Fi[i(GX*mDrekIC6e9Z62KQ8GmST,NVF,-eM
+R,Q5-G@(#6)$hmKG,4p3@8PfYZ,r$mf(N)@$EKepHS0PPaFH6p6)9S)#Y%k)fHVX
+GSPk,Z,QVB$YJBXf`DDc+LV($j-"Z(NXaF#HDcbp#C0HDBc30Xm#RQL[B,**46KQ
+jD0HI@frae9SVB[i4KPa!QPmE--UkpASSCeTYb"mRlh!"4Zh&,fQe1cjpclh$(YG
+S1$rd8c)H4Bp9)l*-jj!!6DG@UPRT9N)Y(9$!4mB,reh18hKeLJdd-UkKHaF',Z4
+AmcZkeQ6NR`VP!((jN6l4EGZAm!2Md@Y(QaQk-1LCTe(R9qh%pdK"[mN0N8A)5eF
+9Z61mDRE$%,(BhdP@&EAaic&8XP)$TZb5d%`d@k!6XXZ[iS[aIP(hdP,YV2cR`Q4
+5Ufab#f6rG25FKfPM%"Zejh11E+8"i"cT51Mr@0LDePYGJP"4'Ka-D#-*RXFbc6J
+q+K+VB(KXI3JkQM(DbYNMiCI5&UkRbr-)"34pUrY!UjSdAA+ZCDedRk)bG%09`8N
+&'XEAZ)JeM*(p-pDTcN6Sb6%SdD+5m&R[1(UCe&fRK["hQ)2KiSFjkeRDrC5a'#J
+B@d1pTZF1NY%qbYqjNp%e'"%"b[!%adMBZ5`CBbZ3!(dl'0ZA*#-fllPXS-ZbPV2
+I@9iEjfj%ZlcbLFkcf9cTLmpQ5R[$l%h@URFMq4!)8!LD$FpPSV)9@8iS+`I"*"9
+ILQ9hYqjaLbX)*Q-Dph2#N!$Yi#"cb)+rRpFq34Z,$e2b8K+#lR%5qMVTYj%bl!9
+D6K&*N!!qbc1R*KH9Dd9G$&N2X8cCf2T[jjM,hTLl4Z"AqNXPmTHN,h6464d59[)
+dkq*9#PNHF,h,`R+MmZ!FbT2M(,251NKC%DEEF54l9l+FPiDfc+VqlY[$fh+09qJ
+#bSbYM@'Kh6P"``hA5d*f4%NI%4'(Y&l-rEX-3-N6mib2RjlI@9TJP+e*ZjJ#YX!
+`I1'(l0Tp!G&,ffbc#H9Dk&CSlMqG1hb)iQUble9Y2[V8QCNUA2D0jI8P$XF!D,2
+@JL90qrp5LB!e!`NY6'!4Y8[*)6`C$#ihKZV*VrHJ4+KPq4Q**5"+8T!!+6*$1-d
+XA,NQ!l"@20DdjS"P,BXV`J@6eV8Da242SPGbbQ+G$XHr,,rKPlUL48J8(@BNJf,
+DBZ[a5R+#,5eh*f2qU#0EjJ1"-&bbL10MX,1M1,Zr8[E-FSc`hBfE$'N!3YN`bmY
+X%KLhjJqFY[%j!1Xm1*!!M[l985"kR'T5M0`E"VR-ZB[l2$b#qf8ecSG#%UiED2F
+Lp!Fb3R!#0Y9*V`XLHRq))GblR9Y0L+AfbME`l@C+)0r+8(`HQBUe%Q4RY3[l9+3
+U[b*S6NVb(hJTUA#-cmNf4#'21MfIAfYB(0$MS39'R4LH%MA(-%fH)'GE6p3*1-e
+R&raS1jV1T[UKP6G$6cJ)pPk2K%!ZYf5%YMa@MSf'0,!A6)"k",kS0Mq4MYV1BXR
+CpX2B`c#r`9PD$JP,ThqUTbJ6RllXkR6jbj9D@9Q$bJLT"!(GXPXa9mm!K[$+LT4
+*QdET(Ge5BS0&T%9D&d@FTjDKjqKKUXmlh%%0MF"BS1cfV"EK62P#F0iA4HF2-qp
+Ch*cXE,2VP%HQqFeLc2GhGLX$GPk[2Q`!KMNZKKmKXaq4BC(i20AH20SLb%LZl`S
+*XiD-PLZZ&j8a)bk5iKp*!kFRalpmaN$Mh0R[c(+R'5UB1qKQQCa$acT"Cd-YRC6
+"#E$"Q-SkS4MBLYdJi8bdr(UQ#Kk&4U[RZa4[l"0*ATReF%bKL&3iNP5%PKFU*aX
+)jd6l3*N%H!m-(&hi&(#dBV9aKbBHBbZ*f)rB4Y)DjG96IA![PplYiRapQ@kN!`R
+mmq"#+3Ai3lJqj$GCN[Rk9-4CJNikJUMiZHGhZ%*L`PK@&0X4fbh",Ddi(92k&L,
+DfAc#I+L&6JE`&(61LH+L9Dj51`C44eC&5rX"2i0bVCU3!0il$R3Vi1Ze`6XER@i
+rp`AM3A3jmKFFIHQ#l1"1!CAm#3p8eChaXf"cqq`c,A+ER#CFMllT"ehT0X[GGmF
+G*Nf!cm26`RiHQA(iHNJ!jrYK344+I+)!HeGCU9VFQqe&T,E"jEMFp-4j82"HZdL
+iH($Jqj-ecLC6!TXbYB$("q6RB'4*+XXB@SI1kk,qi!C1j8S(Zdj&9+),!)H$Dha
+jPaHhBKA14R(dF$Ul,paV6VM`ZDd@J)H-mUV4VAJXDfXP0S@qiPQA'+!9)Xp5[P%
+if!P24RecmR#I*qFjfUJFEf-8B4C[CUH#jC!!#HXDEFl+lh8FVKabA32DB&)e0@B
+pa,Kb'm#S`c!ZQ6$kF,TQUBbf,MG`SS,$d61JTM[aAlTIbP,Y6TFpbUU1p#k9Z1(
+"IAqiZ-+Aq3cYmrc"XFD$m61mhY3TD"-[reIK"5j++D+)Lr*Q2SM!,NFjJ(4bE[Y
+MNd3@UM[1XiBRkfa5Je3qpRE8H&eIH+B-S%!jE5+&%D%k)r9HlB-&pDlR`r4KdSK
+"''8ekGHcmlFQj&4r`kbN(#`d%b'k)eNK9H$QRG1IDGJ[lK[A48)$(d%Y[bDPbeH
+b"UXBdSXEERD"!JDeBAlm,[dHX+S9IeNVSE(TG52S%"bk3(,[U9Hli649HrHiIlD
+TIEJ@GpfZA%3cEj,hN!"QA6iY*9XHU$*hXZU+8@*k"4&H$0HK,`jJX5-VArhR6[p
+1Pa'Nr2C&0#%VdRH0LZhbpD6%6$K$rZ3l#RJa!GfKj4%1Q#aa"03`Kb)J+lY%6-L
+eX#"Ml#S'N!#eSJSF1"`T%Q6jLj0Q%A(%b$NRTr1D8iQ&p6,4I!f!U06(ZD'ABE!
+95rmLMG9%Elakf&UXhh$krTT&!,jE3k!AJUX2jGFE!SK,#mHmVkb+@hZ2V$0!GS@
+S*U5R8FI9"U$c[30Ip1F9MSM0'9LFa@*DMA*`1B!3)r1pJV"i345j'2+q*Jh4a*m
+iaVc43Q9SBXSYBSIqe0T9jGD,E'YT8@Q$'Rb&*q`pS"R%DB,+ma0KR%3'dP4Z0(F
+bKp6'a("TZX5d1,JUAU@d4EJkecKZUJA'XeP&TQ,Qr`TCRFGCd-J9(jpaI8bL",F
+9ApeZYj!!kH8F!lhMjZJrlVR@k9bD)k$2%U%)ZXl3(i$)%`@R$h4'Dlf3!!%pT[K
+3YEdPF@T!F@[LNF[S"*m("D*9q1(,S9i5@hhahQ"r+ADM@e#6N!!j,FNYl85,GTR
+"aj+&KQMN6G&9R[EeBAC*lJJ`NU(PV'4H5P6F4b3@m&JHA-&@$#2[LdHaHNYM8MF
+pGR4[af%3J80ZQ*ZHXpGSqP`U4X0$i0lEmU$S&Gabp9r!p-p&jrI9K9YhET8F4Sl
+SJpmG5MfJK862hp*1(GQ@UV$Iar26&J)r2!h42peiZ&[6+J`*U+3UYB(CBLpjaPb
+6e1G'ql8bbb)VFJX1V0L`JI)I$`CL156JG!UA1ZXa[%#XkJf$Vjj`,5e49K,Z*kE
+CcFGT%+a-,q@'3!CP-ec9@amp5f!-jraA630SkChYBhJd#a-idr$I`Y6'dcNp')U
+RVQb%ECQG'E+!@B[X`R*jXF[64`q"8&Y(41GqDJ0p))B064c#d2BE`Rq%6ZV3$6r
+UrEKTm+-G+k)i(,)&9PKb$KV(2VNmaS43JHZDp"*mTjF-SeBZ[2!$H@I",P&U%C!
+!Ei+0cPr!"4aA9R!efTdE'5Smmd`ff5E84CI@%UqTH6JTlD[@5`kTbr6TCjj'YIh
+laD1"r8V*)N#qFFCrq1r[hU)h9`ejIe*@aDc0G9@9Rjc@ab'1qYH$43NPA(p)NqT
+)'VKSKH3pr%9JZCDd8E'MCI"h["!hQdF-(NJS!XYpHK2iN@'"!pD(E#PZil%SQkA
+f8Ip5cCDpUd+"!PLl9XF[LrXqUk+c9')@ac&pLNBlA)Hhdijr[4Q4!p6IZ1[,Ued
+**X-89TLk(-0AK85fE&&b6IGNrh-8CkN81A9MH,@#TbH#'0-LQpTR!NGkF6qV"ES
+$(L%CQV*1e#,+HBb0cbrX@aCV&Ge)+#E%[8bNIR&21piH3("F@8kDe)YR3jK`E$5
+'9MiZJPP-%QNaPJd[-pjCdYl2b@1NRRHYj"'0EH(aR85GK%LKK+pNq0e-HkJk1q@
+h3QVq"[DGL8",jhYLrA))0VrYU*h!8e`hF5a8mYc@B&UA4XRr)"-0E'XF!6f#Llc
+*dP"e*XQUj`UdmJi$0biSlU64+`@60&!lDm3[BeZ%50!crDcV@La0d+[jHL(4,Nk
+TlaRYINAi"&JB9Kf$'Ml,HGXfcijBi)!1IU4b3P`jlT1P6%'r8e*0YUlN$p@9G4Q
+Q[m[rHpFTXp`)N!"i`+3&)!"GG0&YqSm*2'd(a2-E`e4+Ib(-a(Sr%MVXiFRPJ@3
+hGcmfr#J$+M*-KU5iaJ&J`Z0Z3IdKNGSJMd*i4bjCmCiN2##UcGI4(FCTINdE-Y6
+6Fh$P)dE"m4(%k,0U0V'NR-AAUAq5KI$j2K5Tmp!jYkqANMphH94PlGQ5Dp!1@8G
+5kM,H6iSF`p3)eH3E@Na`N[T%`Bqk@MNSN!#,MiIr%#AlN!!qJY8lC2)&MAQTdFe
+54`8Y1iU54P58!42@UH+!kH+EC$F1EqQq*VcU5Pkbb2,lHFliE,Gd1Q1dpb6Chkl
+A+GEJ*J%"VPC+3iMr5`$I5lbSCSEC3fQc$"p`51&m$Ar[+NMV'p9EEmi6V"U6,aY
+(0@"l8A10DSV``c'dGePVpf!JH0lFqNI1%q'b20p*#H[[@2-HBmDBi)""p[I&4Lc
+@2R-*8)fNE`Fj68KCTDbJk2mE!P[M1hV0R2LfeiU4+[GJqLFR%[Ur6B!r*VE'Dmk
+h'M%P$#-lCfSfFXGfKGQf44U3!$66pMHiB-*%VG*,9P#RhGb936cha+h'64!H(U$
+9c4TSb8(dMBV+U,0(fG)`2+Gdr`8)RY#p-S@j#fX+[SRFQM0Y$TKrBJYU+NJfka5
+j6IdZ3L"TED,1*kK,%G%"NdD)'e`'d`4VqSjB8X0bDTk(b4jpjTIhYm[5LYS[GrL
+0M6llUVHTdc!'aq)P2l-QM-KajhCJG!f'aU!Y,bBd6#YHpI6fmijHYNYSl'RA*aM
+P5Br542'bFSL`KmAJ9&$qqA$X4p`5h!QF623Cd!68T,`mhCPQ1MChd*D%FH99b6V
+j$S-9IfqGmII@iCZc@m&XKCCZ9"`V2E!cE-lpGS[392A(YECGAJE1hI`@r,4aYik
+d8*m$Ep%![#rqpC4XY@#I"qq85$c!f1q@!r5,F#3(,+`R*k#FqDeA%K-0DSq*B'$
+QfaL4-136l0"`KZTScc)6PKU6qTGRZp)SaUAD50+M'%mHKa9ZI`ZU4R9"RJ(YHNR
+PG#4*22$fS,9jS*)Pf8rA31(qDGl5kY%D2qXR1kSPBkG[dQl,YXPZV*')CfqQejq
+B#dMaJ`C-"2*1VL[RRaK6lE+$2j+*[XJ',,&fl+36I*`j4fXrp2+mpQ3TULd42p1
+qlBTV4TAFF$IqhFVV6cNiY9(VR[QQGGr5pScfbDI&'YhR9Y(rBIp,!BEG0fE`VY@
+ZIc%TZmBXf*RZ#BG1!#K4I",KG)BcH%@#ahP%N`*rZm%14LE8Hp@"eJafki2i0LD
+*AEjc$+12F`RCqm9qV"eXUpE&b-XjY5ri"6'5T%0I4(+Nq-,Sebl`)d!ahDY'C#+
+YY'dN$"lj6f$RI,P@b"FkB0e#Rma[`'iNS4Ad3C0@V1U9,RT3,pCHMq!F)&l3Vd#
+@)E0ajZf`6G@6Ba,b3L`qJiBXY#J&`REmlYLErD4bY1&6Y(CHi*Gck9iBA4d1rci
+(-N*NJA#kdm1R-pT9MRJhr-r65@Rj8FIhr9QI[)&cQ4LFaaGD3TB'"ad5Dl[DH($
+dG5Bc!(8HCr#UdB,BVK8DcS)Yiqj84Tp0Xe'&l[86K,!#U25e[F(dC9XdNb*-dD+
+AL*6c62BGX$(-)%+@i1DeA85lbdVYHZ,JD5)DHMhqKrPaqrjjq'@qFK',&RMTM#(
+j%Sf-k"D@,&XJ8BT1p9(1f6)&dGGbRPl&YY+"4TCaTa3(-RI@8akfX()fr"[-XjF
+ijP"ZaGTj1NhKSj[PF+H88IX%rB09f"6V!HrHdSe%r)ceN5EQ1JMkeL2(CB3UqZM
+)dAP(MSP*Qh`IXF82mTd#+T60)'S[6JcF5A4mTdiEhL+Vqi'6kXII0YE!@qDPK"X
+'"(,MX+l%CqYLE'RHA96'"E!jqR4jcDSdrZmY"5NViiaQ&U"VGR5JNf&aI&%dRTf
+cRX6T!CaALbbP+Cf$[(p[m+Qp-II1L*X6,L,30ZCJ(N(m)mXYcTdRH5E-+`0c+*B
+BSSGP2)44VaH)`1Xj38F9`Jp&)jNPS0bYeD@9&[de)a)rZ)1Gak5E@AheQI`"rCF
+SbiXD&pF)!d#b%9TQSDXll#F3,HaN$3KPcANjJi`5eBiQk*U03Q)2T`2%TbjUIKq
+dHaRFEl2Tf%P[GHJi5#dRQ0pHRZ)e9(!8&NFEcD2aR+5k&pUHBmf1!'A8CBi%%bT
+RV!6S'0PrK[e`imZ0VBEZZY81PJR4,rH!d5Y"`,dmIK*H*DR&CV,`AC&&+%lh4mV
+D!*`qG(3h9ip9qG4[a6+"UPeU!H2D*-%e+hGR[LTU"+hTG5ZH0!D3!$eY9l[cP&3
+3BpCj1@&!MFRaUDHK'GSEGehdP$B&L%PV,D%)i(N'9GL*iE,3mH[35b2-&2a8R$-
+e1hX48A6("L!5D!48#LYc"'dlGTa!aULEhDrYD%!km3G*)#Lr2p*)X'rFVm@0MCe
+c+UhhlEJ[`B4EE99rS[$)V$K69S0rI"a*bar+kIM#mYV#G2@VS6`"ME6'!XfYL"&
+l)#TI-E*jH3Q(A(0N&QV8GJ)J6&lK*Nar1H`VJk)RZAJ(KAIK0#H3!(pe`6$Qf&+
+4aYdJFB(,pYUN(eQe9J@%EVaPGb+*BqKSMh-5pRZmp)$FN6A4-AA$BjEe%XPb"!!
+8@U1I`5VFQ+5jMpfNM#4"K3SPr8hGXQ4cl!ar1j!!iH[4f!MbX-%+IqI`h2p`e&r
+KYpr$S2eq'hYq'SImpP[jleirKVKr#lIiD@r`e`$@0rpA[5NHr0Tf8-'D0#[EXP'
+q1YfTp5D8#&!Kb[pLhdLN-'8[mF,TKGq#a%VEPPdjpRFbCN6d61GX!DZjhT+ULcj
+PNNfhPmlI`Ub4M`58XI%NCB9%KPKMpAQ!20qTpe3ql14!XE!),L%Rd8"T`i&rLAU
+hQKV9cVjI-+GT1XP9,!Lhp(4*R12*k-@cbHAGRc58eh`rBN34IQR2MY,Ae9U$`E8
+0(*i$lJNJ'1)Rl#0LpH%d4C5aY2,hrGQFXHiZ,Xr*(l@T4-BI%rh2(c%kU@!m8Sf
+VLSaTS)[b%MTjA"BSP@!$61$hI!@N(YYSqdIbfi2`*&9Z@-"!*G9i8KdU(J40IfH
+jX!49pGb+dm4"GZ+AKc2mPV[A0S*SfEJ$8+2@p*@&rZSrDG!02H!"rhRZY`HEmjB
+dArprXe%q5q5)41qp!YhUjJ@B*$'9kf'-eKD'e)+pT'#Paka)NM00a`M)18!%XB3
+r8cq"aHSk5qQPZFES,m28acI(EGXiQl$r&21UL$(D'4K'3FS!*B`KqTRm$Lp4dPp
+0,Fih3AiHTMQq1flCa0f(q8mkU)-FCU5ib$P!",'%2e-rJFAU1N[TTER'k#r$e-F
+hafhE1*Z`ra6cUSJ[p9&+BY+K3-NZ)D-4cJ"A-M44!1kciRNh&94kBV)@$94iJ1e
+QDL$k6&''I2dM&rT"B[eiTae@,9qJ+!Q@i,TjT(XQDF64i-p""p@L%1p&1!Hb1H3
+2Xl#bAa"kJ6L8(l3,ZHJ$[DdU1D3*PY[L(CfN"(lBIq4bhrPHIk)FH)QE+`(NS`h
+T93Gf0qP9`I`E"lESd)@KTQjiq9Cl2IE%4lQ63U[06q(qLHNM&$fr@+MX`ZkF5kV
+-KB3pMM*SYVr!'fY'XDl)8N8"3'GYA(kSFLihQi'T*Ce[jqDrq*'h'06Pqp1&@k!
+Kca-r0dIlE980p[0,+hIrEf2B!15m*4KC4&,kc@bY(Yh"*BCL`(BMA0kTli'M`!F
+Pi5M#bL+AeQYPD2EZ#5`c&J1a'ZEe6eCm-!(*H%S`XSLPpCVC@MflJNX-aB$X4VQ
+p2acj)SJU#40J*0UTC(92hMQ&*-0,fLM0E%1j23*XY(Gd[E)[C,6Lk*(4XT9AB5r
+i6HrYmmKA@GElIa@QfhiK4j)N!%'X`1iY8$8Vfj&%23'(A1lUbdmNFINEkdPNmp&
+i1IQC5mljLChbP3Jl$C42,C`DR0))*E&c'Yc+%F@XJ`eI1+MJjRe'`1afQIb[e@B
+6E5bc@$a%llh)"@DJkc&[iB0P$D!"-c)4"A%k`T+kbY%3kPK'Q+F%FHlKlP@c(le
+)`h)T'P9!3`j!N@L2miPNiHHbMRG3Gk82B8`5KD9U6'4ibJXcL+lq$KC)FKdG[Hq
+S*e)q2X+4ma"RbG6TBCrj+USG63Tk49h[DlZk50d2%T5PG91p,MrrIUNN'[am"ZB
+XbRhl3#q(KapfqPH!a-`cE3XDV!$Z5kUSP3*$5aGeM1+B!c&U'ZlUI!'DaR*Ki81
+AK[9HIMCA&U,hf4fXJ#6F6DC'j"CZraKqR!hCRZ)CLe$AGe2J$0BcN`m+(,`hU[2
+aXVLe&ll)l@3"*Z*Y-MFJXhIjKq@q(-pa$-@SDlZTm!CV'FQ(K3jH'p9jq0PF@S[
+IC(Db!*0a0TNEN!"CZrc$IdHjHB"8&j2d6i#U*p28ZN*Pr2pH#KUJcbjr4*AFNT'
+@VrhZ,`PkG-$(pZ3$F1aiJN2@S8LJAIQRJL-T#AI"J0*m`Eci%bZQ#Xle$YiJedp
+*$6LVAX"P%&aabb[li%-2L62**R*ke9(fh$pcA+c%ALT05$9"pLEl*3qAmVDk(h-
+&2[6k-KLBE-rEpQ0)CkPYFDKY0k6AD@6$Xf[e`ka%@q'3!(N@DAXQ+$2$RKX9AIK
+&@ZjB0EqaP+P@JBBJ$&ka@2&PH'*T"fX3DMXaPpTN`2cNKJSfE#(3VE![Xmc&J4d
+`lXlG3)6K[HhG`5%i(YI(#Qk86rbY#-+DBiVlcih46YHJLAMNb8@RYNDUB,bpLXi
+9a2EFYA5'CTH)DRIde#P8h$r!,QE@8rl-cK#0PR!"jjKjrh%L-[KieCZVFTM5hJV
+bVZ$9Qi*BH2)bMbYSGh'!LiPjRJrr"drkbZ3''[GTRRmerNNcf5"*FadhEe&,aN[
+&#H`!2iG$lffkG@U3!&'5f[%K!A#DKITq[II+N339i)6[S-V0!SVJ(`Y19iD6rfS
+FBKf4dm@LAPkKKSF3pN[[+)JM5D[LYA[drA[[P5))+m%*hd'9QJ89`$i@R+m0*rp
+81-3l)kH,4,bp3`d1)HbAhP$R2`eI&D[ITq[II+N339i)6[S-V0!SVJ(`Y19iD6r
+p3ia$XMTiY%[,e$$3iKl*IH5FSTP5C@-PVI'TqP8(T1+&!`I)q8ZDN!$1RI-B6lZ
+1!GEJU8G*I5,b2mQX%#,30f341I(qTSL6'JBabcfi`f$BE@2+AfNI6UNXQ09#LNl
+`TEYBNe#B`N8(MI-8'5&`rJVI$aic-XABP(#B1Mj,5cTJlKfm6Xmf-KTHF#p'iS`
+&DdL9M!%9HB*2"S-3rc$'hiX6[U'X"UTPfPhkmXM#pN)&HDBHe`I%Ge(IT6i`(#@
+##S&E+6fc#*rTiPDAi-B95BlJi!Z1HJ[CJH63Y(GQ9Q%#@RTfkET")IbXR@UUM%r
+LLTQV`SGYJDZD84LMH2jlPGlZi0ldj'B%G#Z)f8d0V#VJ%`%RCYQmE256p80D3M5
+l6SjFEXk#QRTKfLRPNP`,4#I!2ajKmCiMNR(DeIlL9I,rIqZNe[hIeBkRf83Zf+M
+mJ[8!S0rEabCQ0hp$![$mb+@KGd(9UYl9fdV4l!2[61A1`lGQBK`Ybm(,bZfhNbU
+l(,PKjTaG3PK'r(Z*2hFV4l!2[61A1`lGQBK`Ybm(,bZfhNbUl(,PKjTaG3P45NT
+a*qlPDFJh$cKcX1hCQ)F,F["bmVYYj-UZac!GAH"1H9r+Ue*aA4Q$N5eNcUQ$&KH
+l96+G#2U2@`CiVAl"f0irQa055A1kMQ&`VSQL5ELAF4iQ*6cFChj$6k'6qcEa*-2
+pUX"-,BII3)&4Pc+#eC&#1(-f3jkR)f@MPHK4hUeMUf($K'!2(9*f,%ZIfqM3"K5
+h)B540f0b!Bmb8!4(8'TFflB,DjrE80I[[30J,YQ0A2'JX0Y16T@5*QlMTqY88$U
+'4&RdBkS`VTMHr(X(-"TR29NfUI4R+*EN)5!Y,RLpmP!&&k4FTcdHP)$`c-+lA&r
+r8[Pkh6)))SFK!m'FH#+%fT%JUX+(9NK6,@hV3jRY9J'*R,eSGR*ep)c9X$0AhFH
+$$)TBFY2&NUP["GKI4V!-61AV3l16Vk4QVB'D[Zim*)*f(,6a@N8XPBAdD`$1GSA
+0rNmkmQY@`-eIGai536X1@RLIq*-p#-SD`2pafeAX8B@2Va9RQ[NRmU)i`[!U-LM
+KI@bGkU8NDX'K3iMeE1mTfa,#6AfA%jPdhpmi1pGjD3BF"-,am)V10KpaX99ZBLQ
+)Z$pDBmY9V@%rFM(QZL!#9bJDhCFIGE##2pfZ,UXCi(reNZ"3f('CcENhTDSZ(&F
+8ckVVUKLpGj9Jr0YCGb&!Xf!*PF-+qUGmC0#0&4H8iNjhRB&CU'8Z`Z0ibae4VG'
+LTkF82ce(9-`*#[!kI,Ah9VqXJ3#4RTeL(+jPXp02VLD6@Zl)PKPPcaM$`94IZRS
+80AE4QFh"eA,BJ-2Brh6QZ(U96pHda*ii09%P8BPpcRBN03`3lKF$2P)R*rKa+aK
+(SJ[@Kr&Um#fV@D6#D@N%Y-YUSccbhERi9GZbX*3EMG,N@Rb@PkTU2$cdpbp$4@U
+PYe&-hm'[1ee!lJqYRSKNGEd-dh5j&TmPTHUDM`mp2F[3d9UTEG460r"VcYG31i2
+VCk)C(@iM,2bj&TmPTHUDM`mp2F[3d9UTEG460r"VcYS4"riE8RK5IrKI0F(9rGH
+UX35MRHJbrK"IZL@0(0"(h',iqaYCB)H([l,lNSYp@(JHlM0pYJmH0YqK'E"TeJ+
+"6bVbkB"%qY)qf,-3`5J2L4[Zd(H[Af4Q5j'AYMEiU%04-qlr#&+0`1F88YJBJIS
+F(03P'jFDe#R9Zl5e,beplm%E(Jd+ZdPX[cI6N!!e[L1j',G86JeEN!$NUr!RUQP
+MT1@T1Phj$fR3#rTDf9H15Pb(QPEIVP`5JP,MA5Cj@3Dj4eF%S%&k3j`caI-i")H
+iQ+%p,c2*MHi(lj93he@T-T)k[+6(LVDP61jrUj!!D8(cB&F!#l5bXTlAjSr9Fpl
+KdIIV8)k`K2SJkmSm6fm%HMZc)b+T#QE9lN9J+&5#FZPm!%hNLYIbVN`SNT!!R6k
+b'Xme-3eY[arN0Ke9!f%93`0pA'q0e-qk4`Z0Gj219*[RGal,MNeDNG6`(DDfHIZ
+Rkp3T5*I)(kKY5Bc2JS2RQNMB88V4m2mL[HRXZ#epI+R*K5UfMETZ['VP2FPcHXh
+f`VSDa'k1+R"'(#GH+"F&CZ*-V6@EhTl,JYIAbTbB8UYSfkEVaUj6h*FhV0qD+)C
+50dF91#-1%km8#i+cF,E40C[HRXZ#epI+R*K5UfMETZ['VP2FPcHXhjSSKP)h4a8
+m*"efS0#f,*Z,X#mSUAc%F00H5U@I#+UDI)8i3djCe%JCC$YLQ62qDBmiY++&QrS
+jQkh*9%"K+p0FD`h-[ZLkr&T!CJ%!LcR5HGVi+DA,#c4,(,'8!"28m4q!FmfU-4T
+1FK%K%UfAAc40Tp)$#e1&c&F+Yk0@FGAS4YYliDIlC0['L25C2T0MMFmP0)f(AI@
+29GkJB#eImq*QL,Im*S(4K2IP"&09'%e$j![$SJIBCeHDjh23m&#"J5b4CfBhT[d
+ZfIhjFNN9KeJDN8)iM&Jh*kq%(VmqmCbh5X9mKY9,QRXmr6NB(Q96rhr'YHrK*N"
+YNqdVAVhMf4c+M!DIEh-2A!b!icZ8Pf4bcQ%[!pcK5r*N-DZ,$'M!DFV%dA*LE*j
+4TFT+b1R-*H"lR#Pq6)BeF@'0'!dj@*SZ6%f6bM5j5+SfjK,`2Fi8[bC$'VL`aS`
+'R+a0&bBQbH8DA+1j%ZB5m$h1&,mQ3aUiX-D-"TbX64FQ*XRP'PbIAr$`8qRD2c$
+-X**Z*0l[h#AYN!"`S8iU2CjQa@IeR-dBp!FLH!L`@aT2VP0,ZGTe*5(m``NT64k
+*%HNCl11ifccPe1UAl6HKje'R%Cb)Ced0H3LCl4-leC4fb#4SaIp8R)I5'fM%3Cd
+GY(YBdcTJeadaR%kFfZcQf$SUG!YfreVXFql$h4cr-(lEUc5p)C0Yhj1PUe$rCHa
+',42,L+Z$'@&6-32LMM)V6&6GAD9Afm+k(2D'ac`9R+BR#EPF%P9p[#ZKcfKXFm&
+CbQ*`Q@%C+VlH&G$RY$Bji+cP-6K+A98U[Yi9d1Hd0MRJV18a0iE8Y[B`d@D"%,a
+pCF%NJ4HH6lbB2l+Y-fA$Har3rF0@T,9k`jRXQpk%R04ITbKBp4`GX`m0aY(,U'J
+*SpZQNd$NQD9i-LI9`FB6mi61&Jd,ANX6$m`%q26ib+$62Y0fAiQ-b-i(Xm0PSc[
+(+iCHP56NNCcbb6Z9m@XDH+([SadJQiXeUBJbr+AC`48-Vf+SVAb-[*F)*rm[P9R
+IrfU+XNDmU*A%AkQA1!UAFl-3DTD(41Aikqb&VCd'hrprdCpl)qa`5"b@A[i(6rm
+0UHXV'3q#Z8c-+#jU&#%1NZTHrJG2rPmhPQEiVrVj1HQ%A03S3KdPe,hm$Trm[Qm
+XcI&IpI*U-L,QS8)3k5kPlq"drh,j[,-haArAbB`,&qS8)3k5kPlq"drqAcH@C[L
+[q[L@CE[6UeFq0GVb3ZqPr8jJcbFQaY5,`,iAXd[hNGaG`Zd'`hE1BkP&@qKZKd,
+3KHQq*4pZfL[SikVU#!,M'$4Q&9ibLBYRFF!Dj#1,Gp0Qr$kbJ-5`pc*)K)KHFIU
+RjA)GL#c)%p@m1[XG+KX-S2a[l18CeTCQbdR0`MrEZ0*SL-XKq)XYZ[P16D'k6qq
+`!V3cHVXHVqBpBAJqShZ+Cr!@,L`@UYI)9%i-9"f6S9h2+'pCPR+IFG02i)hRVIp
+rd`1ejb0!lq2+RG0kF!(U$kiB)[[jNbbqH)b+iT*YIkq#8ZA3[@h#Qa2rIrchG)9
+c84Q&'$2,+pZ('j&c@JID2k`[lJLc1'FJR,J[p,hV3kC16!$LUdYSAp'LD9KM#DY
+d@(D,fGF&rTHpD(6*bB!F9@PY#rSd65X-B69ZMET""ZA"IkA[@KdbFQ!(&9TE3[k
+0%dV$'%eESZ%LpRA"IkA[@KdbFQ!(&9TE3[k0%dV$'%eEIqI`hYrKUlIEY[IEd*i
+rE[0qh8EpZeRlHJM(m0SllG+,lGD,lGZ3!2'N(di1iaH*l&G8D-mIN5LVN!!dYP3
++-VrcN!$-GcZpNjbZ&eaCDEE&)Dq$`-cF%)r@m$8pCkH6il-j&YrQT`3ji3TY$A+
+1jHhB!Q0')Z4h2'QjZplN&Ff*KR$%%3TDLqM1bZI1Tf9$AA1[Dk%dlp'2NB033+@
+h$9Ahbrjf$h9`Uf#e!F6R8ZfX&+"kHSVPFbakS0b@kKQqSJY'A)ELr#IVKK*@V$l
+6+mp5aZG'#K2SNX'"D19`cQ4(&R29EDh#q0"CpKRh2*!!5JfCj4k"4VP65Qb#+r2
+@5XI2SCYPKdcfU*epB(D5h-VcAUGTmBZPPRf+LSQXk8amrL9c3DTCDK[,-,4aAD2
+53pd46XCD9edHBQpZp2P-UIA6p*S1C(Q1)afhE@9ZRhdHQc"i&+m&C#CikrkfZFS
+16E!SP48R3cJdqIC,jJ'H3@S'%J)M@+a`AP9IZR3@S[pRp88"EBSd+%DN#L3pX9#
+"YM4IH,G[FHa83B&Ukqq9JfI)E[lhLq5X%flfp!2H`IBhP5A0+4mMJq8"!&VC-5&
+ma5G-8)b#GmUr*S3r`5$AqDJA*PTX0iq[j)'qaU9TK(KpHMTkZGBKj0H'e-bADdp
+68ESDlT1Cb4'54m&("H6ZQDD&-j(IrhL)K5J#a(rR(PMpY*FF'E)jj'p9Q#JN&EV
+4JR0i@`13!!6,&)cJ[Y+1GdPlUNd16Q!#J3Ak@cVlp%403h@Ik-m`)mR*ii'AHZ0
+11[0+#(jCA@$I5iQR-Ia6m08`e@b$bqr(SRk(krV,L"LkXqMb#9-4Z%&VTK[[8U(
+PHMbKmL`!R*FcX"c@#qbDTZ*iQ51kMD@(mhkF[SXPq1"Hq1&ArP!UG-lAU8JA!'Y
+(q1ecJ#jZJj!!)pG@!i%AcU3CacCe3b-eel3)6N-Z8"I0LqIDJ6dZN3HH9AfeQ$h
+kV3IH`9rb-ZN*K$E55a"KhfDZEmYE`a(aAi-Y,'3eN!!B)K#ThclFr+#'TR2NYA'
+Ji4Q6j3AKIhr1HZ(!bK@Q&r0Y&dKH*6*-TK@b,jE5kVEaZa38b95Eee&H)!B'@Zh
+j(A2)5VCAMjZFX9SQ`8"`%f9YIZM`,@1DZE9-(cb'0S9[FAQIr`#%)3KQ*-0B%8K
+IJQ[p`(%8ZRG(Ki%#T2j-bpYBM86MfY`)1f`4*ahhAl6$Vfk0J5EHE+qdpJ6S+H8
+9Sp%"m3lY3jiA,lKCRC@RlQ-ADd5%R)$!S+d,5,E$plia+1+EqdUmQ0l(iFDD,`$
+9,[!TJV)*1Sl'*MQq,i"%@[#fqKPqp#+QB!Fmi$fkM8KY"+"R,djY)@pZfiP14Mc
+TU&U"m4P)+i8hKEH)U4mSHKN5,(`S5fD-kRJi*MIY)$Y4CQa%G-3`U6JMbd!HK(@
+YbF233D6P&(QD(f[QD$#fdZ+b`$i5k2YMH1,U$%mCiJ*&`IG"AbS"`cP3a`8YJpF
+GZlPRrMSUrU`BaSd9UMmmXKD9U6'4ibJYqbHCFYQMXFME'[KTXrHD6hCK$98r#rd
+4P6U(@d(EC,#EC$)Gjh'Z6%FVCIpF!M!c$8iCrNXk!Y8aqqaB0h!-USPq%&FPepc
+C3E#bZ(-V!2i2iT1ZGfKk04IP(VH-+p-EZl%fPNpcraMP5fSaP@,-0%PK+Lh[D+H
+AZC!!`GBZ#YE"JHZd"8pjlfZISlF)#6mjK+rDHlKTpRqhd&aD*-CZbE!*k[1i"Xr
+(RE-'(!%8$,@4fA@jSb(Z1iH@Cr%53bPVRq1(m"&BIGGfP1T6+PK8S&`e!iff0%@
+R3BmFTAP#d-0rHTXbZSRh*B*TK2@9r0BaVm-XUGX('#XbmDU`Gk1#VpFMGLVP`Pq
+YEL-3+Z[%cH-+(kAdl5*@2dcVc#ph44QD4,IX-$S*4[3SdJ)rpDil4F`FpP,flNU
+Z5hBLe"@XA1"+ZBa6IR(ijd0T[9!M3E"S*QJ10UrMSTE(ldG)3r8lDC90@@[[++c
+dDPa@2Y`HTZZk+$rpbmVN80Y)!c@H)2@X2kDJ6PLi-&q!L[&FZiP@CFN+49pqr86
+`prk4%a8lic#`RPfpd+3$!+Tp89[N)U(%40)J1k*&j0rF!B#0L59+SG%1dKBmpd5
+acT1Sb%8M*LG09X`$K4ZHCSC8I,heqYp!p'rp8JBAUDV)i@rGY,)V+lYADCV(8AL
+FY5"(QiKmUjB"#(8qG1#iJHR'F6QU!4&e2Tl*1XBJHTmaQ8q)(K2U5+L3!-RAKk,
+TU'(L!Blr0!a9CAE%-E4+Jf0a0E2lmMhlFZZ&D`V,X,Diib'j@fh)ar&4lK[5SH1
+H,J+dhP!p8@"M@[MT%45(EFIPlJ&NhC-TQDr3HK2A8D9c!2"GjPYIZ8j'Ql5[Uf6
+86kPLjP%)j8PbViMl68BP9LDBa9l8'TXNr#kGXFmV20%Q"mEJkMmJ3YeN*!6PYQC
+-!IeX!4`PfNETI0iaiD*h1(EdTV#%R*``*qN9d5k'`Jd35Z"P6)$hQjr8NNeGh`R
+45m2(CA8[afr6#c',a[5YAL3G[9kI,hh0,iIh3N`SVZUJi'9%$NGfL))YM$4)`f5
+QVH"82bdAArSi5K,*X6bA)VmJd4#kFfTjPD+Qjpia`I3G[-T[RCF%qbdDe8m8a5X
+4FEd@B!AXA3e1[ja*(F[@kikVZrLQ9l)8r3aM5`%"cfYH5%(%`E3@KYb2pP623,[
+FjJBTXT1!1$QL[3K2,bX+CYFlEMZ4'@,QV$0bPX61![JG6hiV,NCj(L!pL#GRIU-
+jm#DU1`8D5%2*[U%X1lhGJ!BD`"`@,KlaG+Y9C3!C31#XMl3Cl1R3)R'6ah2*V1!
+"!aZ*JRTaj1AK5q5[EEd`Ip%PVJ4UDKd#E2+fQ)pS*E@jJZU6%9aarKG)#pAbc#f
+Y!GM%2dG4,$&cG52b)3VV([I,[3[V*P!b*eiT16L"`q&N"&IJfXQr1LjZ`-bFHA*
+A)&Q3!!b%dBX&SpfrQi-&f3P))j&K(UAef)kpFJLIaZX8PK%p$IX"0cS'"hf&eZc
+f-[E+'FrJ,2p42(TeiG22pqX5*GHm"rcmFj-"[lT[YB`c3PZ8[,iVJ8A64Bi5'e%
+"rGD[5RA2e%022r@+pq5"H$&RX%+Eii08lK@(Ier,k1f$Y[dk,Y[X8bpF-5b2RI,
+TK'AJR'V!GdUmU(K,*dKMIIb1aq,SdB*GPl+0NrV)P4QS$$ZUU2"D#8fS)Lmd3SC
+j%JLhbp&a8$+[c1'q%'*erNkR2pRFS-1mR8A$[9i@6GNKF609%rF#MmV6*J)LdXl
+)QXd[m)[rG*Mir3Z#25Z-'FjTpYq63fdMfh-Zh-2Xj#'l5Pia1Tlr4#NU)VmCY*l
+3$F&H9jSYQ,,q*c*Xj)A'(dHT0@[`4Y1KYFDG+JL-)RRBK0fLX)0TS'KSq22D8U!
+VCSD"h`5(C,riq$b0$9b$60aNAa3NCQrK25P1E&DC@Zbl*NXa4qI6I&I[F2P&c%C
+'4kBL$A1VNdQ9UJ4bKc@dQkfeaUGB6XLU"@`TBBf'D$5fS,#jUd!(JhLQjYT6AX-
+&G*E4Qh9Hp2F*U(Qm`(A8fJSEpQK5j-,@"ppJ5N!a(L4XF8TkkbUUaT%Y,rN(5-N
+&@"q,16[eDRrPkp!#(mb[RaGM'EHYr`)ppcPG2P3!1+[k`q&+QFl3G$m0)@B4N!$
+1QbJ3Yj'[T"i-UmIJh3lpYqL1+ImiM%AlL+A!p-kV6SeUqT2*0'0)NqeUMk&X)c!
++ZJ&E'H0P$4rDLYQ[5aN8B*Mmb1QjN@(54F5p1GXaLPc0,i(hr'$rAj1i'cL@qpZ
+K%f4P`h4bS-er$*IY+b$cZNCT'3T#4J++&c-P(#F&,DEr-k-&BE%)D1!a2DX4jkV
+&DTN@F1b2BZ,QiN([N`+5N!"C"*Ef6"cG)G)J0ad1A5Ar$*2,ET)3,,1e$CVih#k
+H8j*46I6[rG5Z0LNCHm4Pk2mLfYC8q@CI[[faSS&S(rpri6k#%*pQ$QQfDK4IkZ(
++0!*QX6BN54FkXmPB3ef"adR1"(UfAJ3Z*k6cFe#ifL&)Ada@9*KB5F1X-fprA*!
+!j[p!Xa`KF*GmIJIdf9+!08lcIL1[5"9hMHqaB&JbrXND-&iebfN"`Yq!l59-%pe
+NITpbCb8SDdLm`VeZR%kE%-IQ@k2$Td2EZBZ-ihVC(B8MV4YGmd,J[cNe@dZZ')D
+51TIIbh''ThYVbDla3F%FK-`E2+QU&rXA[*ZmjRJHN!![i)JCTK4V3f"6I,)XL!4
+#$cPk4EHD0ihMj#'H+`m'5a9*-PSHT@ep%E5--GMZ-%5`#`8pc353!*P6JBES2q!
+JK*N!Dq-#J'*0)lT`3eRJ!d4JZGad60Rl,6,YMaHjH6$hq"JCp[&)9I(D%L@8[N`
+kDHQI`A&a2m1aqRlK15`15ZSdFe#Q1Z1i"+RFG5G(ZM$2QHR4!VK,'Gk'aM%jR&T
+Q(pISMeNfcLcP(4I0GDQk*CDY4q[R54TIlYq&'TQ6,2$Y0IQ'e2DFe"%Cb6VdTAa
+506il5NMC(+Uj)r(Jj'ak&qq!8LBSkiSNI'`IDlek+,mH5LN4ijk9F-hM9r$%`RU
+[DBq1%1Mih!Hd68RkK4A`6"d05YdSSKkdbXk`5-Db4(--P1haeFULALRFQ8Eq6l8
++B#L#22M5#6L-T+pqP9!CpDJ$UJ0B+DrKb1jYNk&)$T,R'Hjp+6Tk-KQ[GPcm9iQ
+Vk5Qr2JAaVdK$m1He)()GXM`Y@cIIAI@bSB3bL,l$8)@rm4`8pH(BbY6e#Tp0RrG
+`DRE0QJ%fCIp1230JG9BF#d+i&TG*ka[kVA(#mCkDKNbQeA0J!$bfc*B4dF*m$8q
+DYdYXkKVrI9EJ`MRaSfH&,Gc%@8k86MVYAhp4Tr#JFc(q"%f68,f[FrEMjel!ZT@
+"VU5D6Se'fS#5'jU"QIBU%GTL8hXCa'',Y51!Akf9S"f'kV[NUS@K%a!2T9A"NF[
+"04,r8MDaYXp9q"[bfrmkqei%hmZI0e&5e1`0(EIU@TiVa51J@P"4'0,0E9P4GL!
+Q8AldmR[Lc)kGjIK6a9Lm`2QE%!LBPSF[jQ2hpVZp'Da%)1(X*k,j"&IQ#S5RVFR
+J8DF`5Gaq"hi3$h)a"S(#em8QGVK#*d)3D@b2iMY"Ui$SrcVQ0rpm8@Iefh@AdIC
+iR1I1m)blQPJbDYCak@H9h+B'&HSY&LH@R((R6!e!rfjcciDU"Dr`Z@NZT*NSaM4
+3ejcmer[3*N5S%*98fB[(9q+lmQhkc!V3G-)C0br*Yd-da'cAQ9hS!15PhdC!BIa
+2@j+G-X[)22IUaHDU$-rX&Sahm"#qdXaY1LPVCF8h#FaVT-rf45G$R!R[`5$AfIH
+3!,04ml1L8K024MTc"6c'J'iN`-5"060mU9U)&a8#-0',13B$,l36S5r9cA`+Zhp
+9%FRBLrR4YJ&Q#2J0IeEZbd),!4BS'c`I'Aq%B#$jlE`B0$(Y9`+B3icKC+ZiPMd
+6BS`20ARQdRrB34q%63ZMfVVCXhPJLR'-L'K8`HEe"[Ba%VJeR@N(8iA2aV1BcpA
+8hPE@+3eG+Q564M"EeV@6U(*(kfVQKl#)1JZ+%6N)"kFi)VMbiX3krQp%5"#0cR[
+jkpX8fmSSARN#*RDla&$-DAleiGA#BAiTVLm(0T`N[lqYAI2MBaB"Uph2XE-S3dZ
+q16d#4MJ*C'65-C5SFmC#-EE6P1FeH)[ceSAhCIVIbkY"*%0KccTVEm5!&Y+CErk
+Q@`bXL,([h4$Ac-ahbGRk@Xp#mKc&hNd2)1dGlDrR2[lf'!L1FlEM"GM0@&a2U,r
+NBLG#qh(![qTK*kSJmpi5@C1LHE5f0i(P0GH)p''f%%*P3TkrMaPD'$%%Q@'8R&"
+2$M$Kih#`'Tm)&ML0aVEDY8p1ZcC2lY,R"qar-`5rT*pl3N[L5VcGNGT(0@C9(M[
+FBq!-6fUE5&5M((3jRLG&L[,r@h1TCjkF0Npm1M%1Q'h%I-%3i6GT-BSY%,T*E3[
+RjQAX9IBcp20B"+`l[)cb+Zlq%EQ9K+'26ULfAYSB%qpdIrprrekqP"rI5T6A(VV
+lFeC5(3)Q+YFGARJDrT3#!f)$A12VZ8!hrA+B(Glmaj@[p(NPK1A!Aba&ESU(b##
+*SCb*IXe12K(8!HeTij!!!b`2&TP%0%&8!(Gq`V93@!J@j#$*39A39XHEma"K`S-
+L@6XCNq!hRjNVI%ka[0+Hb15#&ejZlh8FYK&QSDJUe0(RKJc,F*laI)VDc32MQ',
+@e@FVIpHK"Yb2YddSbKXGbbBk-CNZ#S'[(qS!jY#G9L,R93SS#L&PU&[252,,P%)
+4,LR"d2hQ0+-Qi*e@6DrqB%&-cLP$D9%eYKAXp`*2IZbqD*N6eCU)U0DX`5mbUEh
+)Z4FEEXV)A)BNk&Gd`ZJTbe88e!*Y*HkM0F)BZJ1KcH"*U-h*heANK,d-Y*eYJ)B
+$N!#J4I)&EXddMB$*RCbbjG@MNM*0L-rDX!hGE2eMjGiQ)F'QrecbAFZHRRaD1JK
+3M[aIMlG%0j0D*r'4'V[*M$jUY#Tf)&6E[JrpdH52"M!)da`DQ-lU9VC"I$-F0LN
+5al!25[q&r#b[kVHG9l158[&1)&-P0HjqP"2C`R4G%aAA1[Rc2LpQK3'16hL190+
+TiPaZQ&0mfaSlUTjV4lD(#Fi[m`UZ)@#MrEaDhEBbLId0d``P-E`R0j(&fEk5[EL
+#pmdE,cQF5M*C&0DCSQfc!j48Sc*a'3(e+*DRJS`3jDr'A,V4808[XTJ1NGE03X@
+#V,U$@M!b''BTTlj!h"Icb(5KK5I!3D+&'ARA2,GfP@p5HXCYm,ikc4f&1JGUf&$
+UHFRApEC-0VXhC[A$VDrK1aZb*9TR[YBm#42ERHJKFA"f*2G#r4ZXiL6[J1Afp2m
+qhC5qhTCrKeNCIEdQAfl1r`G#rf(9[KqhS5rEV"I9Z4qhT%$aCGUVp9C&&YFMd2G
+jShIU,!,*K+8lVCc*R)r2*d&N$MHNfhcmZRXFTi'9@qK@8Q`bfpRXLEr0,KpB`Z+
+ZaIFC6IZp+@`rYq+bbU%pq&j99+"m-C9qq@`he1mIVX,HS`ANHlHf82ABabR`IJ$
+5kCL[Gj9$"[)QeXL+2YMCeqU2KBDXGTM%bH"i46p60IBp@1bq0YT[&rVKbmR"ZE)
+Fm#%5eD$%A!jP!m3*'eimj&"BXI0l$5G&q@L6aTM!AkfTA'I(K9'2mMcd"bXi*Zr
+KF9V)JhVe8Z!dAi+b@0FSkE$lfYHR9Pr[eBSC-XhhJM20#`6hQcIHEHHlR0)F0i$
+R-[J0SfXFF,EXr@A)M`S86$!Aj@HRakZJ58aEl1K5X$bRS4i!-j!!2@M&4S@Y,0H
+f-pM+ZliG`TRUC14@dN@Aq5i[32E6+,ZBa'!,lPjE@-A[%D'i%T!!C6J&EXqrl'a
+9c1L5BEH'jTKpHAUl`4ZHbZF!0N3J@QEVXMVN84cUCH")B-ZDXjkHKq&ZXG885`h
+@%aA'FGZ[*f[Erek")Imqm4&mb!VZ@R6F'ml-aJTbe+ErE(!'mYhG9PJPmaCUGFi
+EHf`1@SX3UKbJqr1r'Ki,0r$RF8)C$V&@I,kP2'@*QNH4e%@[-%c5S&fmUiSTSP`
+XD5PHlp'#Q4*3PUCjiTj!2X&TBhp-kj,2A19Rh%rbKRh&FJp4hfX#e$&(*S$'EHA
+(@kB6he)jr!Z`0dZ%j,,I8fD@6V)a#a`6ddT6ZA+dl98YDhE9VU)+rBbRI!4HUqa
+r#@'kXm$DpD$4Y@Z9@I(pIIf&QBXr+hSk0hL#5q+%Q0VhT2dU,k6(ThM)D6k`MHI
+lTdhqbr9-YJbXN6V)Y*PNVL)*S!#D'J5!6+8*P[pZ-bmK+i''PJbRH1TCLGf&UKB
+,CZ,H6kYI3#XdVh8VlEZeQ3lV*mp0ap#!qmR!MCBI5VK*X8BkLURp95B&9U'$Y0(
+$#ZrqF1dV00*+TDKi3Z[DYr5[rM(UT69+#60YCM)V`l#Uc(S@)+@Gj8D3!'Ii'"'
+pRp2r6XEqY-Ca%@a9"3@pH$J@a3$rCZ%hmJC,""r6$V[EVZ24KX9XqrUk)(42KXB
+hXiPMBU2Mb(U+9RQ8E%i`M1![H(1$")ZeCM"(!jJ"-3d58FL$'q8KP!d@pj!!4S5
+kLJe@6H'Rm*r1l'9DpS)8+Q(L4@2Q$!q!qj8(+FVYCpZ@Q&I6eFX$4(,$`RAi6eY
+3!$0$%efa[5CQi+rUBlB[r-lkFE(LH"kjS9A0KVSkdac4#!d'-rpD'1FAZXYbX6[
+eP'Q[Z["P9`l'ch*%*SlPY,LJU+8m[+%HP)9c`+Sl[aa[RK*FN!#51S&r06@EmfE
+LDm8Y5D1Xmf1+3apV,JTAiK4CV4+%CGB2NRdE'k,Tf39aS'Q'XD!&!3LP,LGh%"1
+q-HR(TPi5BirDDaVQ5`+!S['G*Xk86lZk2H(XcRAH05pQIr9fTa-@(q#)djU3!(B
+Tk`lF&+2TV!51$P@%LejVG5RaU*&'r`C*$YfHcE2a"rQ!eMlmld"@pccqBKV32[m
+P'qqTKS$!kL&4iD1*i$E-aA81!aX"ic(ZUIm66'p(K'dk13)9fVbh9RHJ+&DKjip
+b51KFS,Q2N!"cUF3VN!$-H,jdN!!C#r@l'LLDm"f24UIYGrei#eH12&[e[J&F!D!
+Q-!GEU'D[[1+&f#PCkfFaG[LT)#qqqe`jd@rXi54Hf)`aEUKD!b9#6QSY5Z6"fpT
+C$mbCf!Xh2RlFqG3&!H[+)jNimHrd'i)"6T[$$qJiGq"ZQM&(E@9kKSHHNSh-d$Q
+(Q[[,KlE,3R+[(dR"$X(Fk8UI6dhpRPIphj!!qk5ZfXKj4eZDdLN&QFkDbc")d14
+R1hh)Mp1NRVBe#r4,$AMNB)f,mmf1-Mi[BQq*8JqkhH"U3*J23)QJ1NQ`-YhFF+!
+ILBT"B1T@aBL48cidkhZ4TR(5P$9+i(0"FPUHEfSZeE2R16k)hAf#R)EY,,eaZMZ
+6E3("!j824hi8+cT6)[IAKY1'dSij'M[l(9#KVTNSCFfFpkEGlrhlhX3h8l&3bp$
+T&L'TQPQ'eSCX1TV!QTb-mMKf&aZ@&a[pf956,jIR69jfXVGfDlcZU*Nc5b!Qf4D
+MfIL'VQ1Grb4Ed!D!`!@bNXek&BTcMk1*'e[EqA$V4afZEi8p[iI&@U3i1MDAchN
+1B6UcLRL6YTQ(lma(&*24#5f*HU[a*)b3!2IRQJ0TPc*Yj!cT(%@Gb[R2"K"0**M
+MJq602GZ-6SDT(MBr%ErEf@f`iMZ&5bR"S3I&6a3[DlZjJ%9S[@GZ3arN-TlFr5M
+dZE3B%&'EdcaMAl)*#FRiEfD,RKKHL#4He`8ABG""j#[Ce'Bp&YXZ+qaq2#Z2)JA
+TPEf9hk8q,-jViPXf6eD3!2S-U*AJl%5RDd`89Y6RVY2BArmMCC5,Y1qHSdlU,'0
+9RPk[(fr3D0DJ6*V5d[Ae2QmG`E!1DmPiS#)G"@Sq)4qGeMh$L'4hBD+YYF9GHMT
+kj(Jj4r0hqkSDVJRY4r[aKMmS*eVH0V%BTC[)%18N*CfG"@1S$#1j-`5r)#F5m!N
+`D843,#*X!eAr-6[T-H"YZPGpX'Z4p1h@%hDj('LKq(EQLKlPS%NrCZHa3D&9A[R
+Qlfj*D5T@mj!!I-!Y$I*0J[imMjHAL)fTDeI(bajqHEqmIRB'XehUP&iUp["qC#9
+T'#6L`mqI5I0X"+UQ#%++e)N+c1$"1,QS90F0VRSSTTRfkVQ2-YLcG+m&NP@dH!e
+)f*h&CGpaXfM2$T6K(V9XDm'&$&,HqFm#Yf*1&m2$5SHQ5pHZ5V(mi`NqHU3Selm
+lGcG23cD2X6`AU-UpXJ4*f%LMc!T2S)I%q!&qU9'"B$&K'FVq3i0-D"1H*UJf&[p
+3M"c)8*Lj1NNPNe4R[$@TRAMYj,+jbXM`+rTAfb4N!MR`CDhjNVf0dpU4JHj#aMX
+H'@VbQ*+9E)S'Yq3'4Q'(4YPN,68!R&@&@XEc`Mm-j0$`I[&F*Crr0K9fT,HHQdN
+,8HN1EUFN-f+UEHc,%I8dLCiC&3lJh"ZZXRb"@JNiBV`fZlr4mhYrhM5H9!0AV#S
+1`Q!Gi8Z$arT8fmL'BSm*#BY'8K+D499r*Y56d4L[G4`@5pJ+RQi-+1HRQJX[pTC
+8SI06Ijkmlech-,22NmSTY4UUJ(&*S+BZYm&pmh1NNl8&(2Sb5&4kiaf)EYI8RcM
+dK'Sk[@m([HFNmeP)[Kipfr'UmBV#[(+)383&J[J3dH&U'qdbfi1UV'qICjp22)#
+e6*!!)J&ADAJ)ip90EHK$I34+MhC"@$0CG#c4E-*k-B,1kkS+6BHYT2lRdhbj')P
+f1B)rm*HhI&SFeiY-1VMCH+(6cBf9`Npbh&G[c6ZZq0lC-I!@8)3$145X-0e)PP+
+IhQF3*Y33++#MC1ZkGlLmA!Qmq#GXMFd+5Ah[iH[9J9fNQ&MF9[M9CY(NLL'%JAm
+lN8hI-KGAZ#iSSCFGcJJ'U66!FmqMl"B%[AQV)Za0p19GGVEX4rVDmc4*(GhNA"6
+'"!G@Y("m*N&$48S5%`!cq32[!YHT[!R3Qq9k3i"jMVT'hbd-+15Q#()&$lq85IL
+k"i&d!5I!ETVcZ$J$C$HcN9F5l[K%!PMNFJdYK()r!9$bjp!$jN!,A"aH&"2E!p3
+1!0j%`)eK@VD(N9b!r'KZ#SaV"YJCc9h9`e(i9(G-K(SpfHA$1-fK)F9J8R&Li")
+eIIlTI2kUb6k)'@J'Z`@KP-#&5+Gh3&&&e8Ilr"3IAMmAc63+45S'h0"$Pd5YD2L
+pENQpBNe3k*1YT!reVNh3NVTUDF%*-$@"RCd[,UbG+4`J+"Sj2(2FCFj"6SN!ZdX
+-&*JFJm6"d,AmpFKTrfECc+$K*@blH20c5Bdd)XGZ)3@FkeX(8#b`4*'@c`T"P"i
+P,S!)q8ECZp+2ZQm#Rl3iUbG"(1L,UNJr`lbVeUUi#jc(kMf%8h'jJQr@$3,KLGZ
+iG#hXE@@D53(H$@I1rPF%pU0#q-J%1@LSZAdkjA5BIJQ-p2bl`)Hj6XE!,#YTf2S
+Sq%iaF-!-60h'EGM81j!!Q,&b1eCV+4i)Rb@#)3LMJ`Ep@9[,KmB$8BK1k*+##q0
+(6UCY(QH0j+j[@AmM9Sc'"eIS@Z6lqMdN9FV+HCk4)%8VRqf8J!L6+%fUACJ&8`(
+(5Vj%M,ZfA)kjX--VrZGE`$aXPQbV3+,'S9I&1e5L+dj%rS)AQQEr98D2#%k9%2"
+!@HH@EGkYN4Xki[GTq5q(`dG4@DY4)!1PMLc`N!#`pjpB8%UALif#5m2EY`YU6#I
+!%#HDQpNV$J6P!L`4-IUSM'r1BHE6E(+G&'2plj[L##YLN!$(cRUlSmE,B%2BT3V
+TFUq+d"FmKb8bCRA!Y*lap#HQcCa58RGMiCXR$&-!)EB3dDN9X9L1I,VGq4+BEEI
+IChH!LEGekK51&,BiZM(qeQl'2-Gl,!ckp+(dL3kah#F(jle[6!H5$6(Sb+0Xr2G
+UIrL@XF951d$8Q3#rS44*"85Pc4$iA2adEfLBfq(Yq4'6*-*dIL%`2M"&-V"Zq[h
+,Ur(1UF58K4*@RNh%AZi#mVC!@L&)Y%eDIa9fYl%1-"3U+C('JaBca)!Z,D44l-r
+Ij*X@iVf[qNM'UqEqFBLf4L0+*RQ(4HTMY*br"feAZPmf%,4K2G%be4ab[G0)3i[
+r5pU$$fpXj!+#&P0+5AR-h2YI3#HmE9pa6+`HH"c'AaFZ3bHI'eZ!2,YaiUGh*06
+XG*F+eb&ZLIK6)ARE"fcmdTAQRG(p!VKD*(EBLM(X3XGS)@8,B%q+*[&FfD2fU(2
+6HML@Y&p4HYc#aiE-4[RHTXRphf"F-pBGV))qBIm934)GD9PTiXAG%k@2GUPIUKc
+k41#R6+*XDMa')FTDYd3J%HaGdD+#k,+0GQ6(X0dMJ"laaQb[kki`!TSUF*LN`C[
+JZ!))EYC@BeI6RM-+j41Y1"9$i&SKA!%pUM@dUUIU[DH8bV9,FCANXF90Bj!!jIm
+d6Y+PIN@j2-I-mhHlP*J+!fX2&@XrGS,E%3SGe`FHA%KTU#fB$%mXYcCdIpiR#h$
+MQeUT%c[e,USp#R`Z&XNl&r,U$icd#S"T[NNGbB3L9$Fa*q4LLpJA2EdbD`aG*3!
+dR*RJE3qNQ5emFb0Z!+eqMX+r#!"%1Z0,P5US'BY8lp0DMXpj%Pa1f-r9eEcQ*eQ
+45kq`$bf'dj`Iq&!URS1L1$#N+#HJQqcKh'd@Y55Eed['FVU,jbTXYaT$HT-Z2Q*
+Ab5c'161RN!#2f5N3redBefAT9h(2jlqJ*'hS)0,8!1cEm[!&Nj2A,#JkpEF9`&(
+[T%L*FMRNkS*mG%Vr+j)XCM$$ihFj5!VfY)2#*(eV&j,!ZhM+4GJBeE96E-[m2M4
+m53*`PHakF[9Mf`2-`pR$k6ZQKX0VEZTTqRciY`a*mKJ++9&4jRHH!S6*iUZd-T!
+!!)!aCjIHM1+L(im(m8CfVbYVZMk2d8#%H5L1A3Y,GA'3!0!6GIBTY-LfE4MQR%F
+(X)Qh91iY50(,8aF!d+GYaNRRkTmTEeqDe!X4,ScNZ23BQ%6b-D%m$b8p$Bj)mH@
+1"d'6C52!0#VLF"NM9aH+5Mfp@hp54[JAlE*,H@Nl01)HJ0h[[@K9F248K8k4S!N
+VdPEje9@LeJlF9*C)UHZp)`*LMf6GEIIC"XkDBl&#a$lj#dNh[#llRia11fXi5Ad
+ilCbcADkp!14(-k[pGd,R66G$$A&"a)T-YRYITC)Pi(C`X%LSe"q98!a%Vd*41*C
+M[0FX0NJ!Pajm66)["8hNj`XP1p46Hj!!@HbYX2lQrbDe8Q%%ZTJTp,[c'a8FMBA
+E`pV5i`,,XR5#@rN*2(HrfBmF2@&lUje'KL+JprMBqI9l[kQqG!!jKp4aHp+Pl#L
+mZr,NHp*C*"&GUHb*&PUN*heR6S"fea`819(YLRRYl-r8$BI+"ak[Bm0ikl!!X!r
+1iE@NImVD0@UDPhCJE0LLrR9#14"X)Y+aZ@RA[TJ3(bRZB22KILI-$#0DI@&pI99
+I1MR2dS9Ad"2R,%QMIK$i,R9i#X()TJSMFe4JeRS%p)&V2SB@)GHTkiSbUj1#-bA
+6'c+T!P#Ff3("e0',HL$H$pkB9k(YYqHUh0X4`-ZL@[,dhKNMk5SFC&!J"LBM#Rm
+bZ@HjPAGj"F$EGFkV52fJ5ZV)3,'cb,MQafShZi9(`9mFPNbmL,rF0Sk2cPRUq"'
+M'BR'LF'eIiMP'V[L#M'rKK%!V1EDq+jbKraf[0m"4AE"*J'br)S1@F3qFZX+1!d
+YM()R0T)-JL1Tp5YiKGGfaa1aYLj+%I,F@FQT)Xm8DrYQ2V14UhiXY&p1NqS'D!V
+dE-VJ)*6Ij0Vq*HH3!$IR1'ZipV[$rIeBYdli[rK%L-Cpq0pD"#8a$F0Ghp0ZpiL
+@&P`#2N+faJHjepqcJKbZAD4e4cK)c9E"p*KU*kLYJ)hi@+))ij(e[jMJQE01lZ`
+(4AGfKlVh[c1jiTXhQD+(G5-!6,CT#d5N'`&jh5+c&1m06L,-8jeLmlMSRH[!eVV
+FaePmdRlQ(CXNaTTG&f&3-iaUJ3E,2-VR3)UekZkHe6RMlV''AbkZZ1aF!@l!-8c
+ER[c#AYje#CBYZL5rcjGpdhf893(`0dCVj+[L$*q-Y)A3VM9#lS#bCD&q*P6CYhU
+45(@A93CY%dq1B6MRVE$U"4JmNlUc&AV%1Gb(6f(LJ$69VdYQ0(NH@A0#qSlG86P
+Q[9LX0m,Vb#b06%(#kMhMXKI59d`#+a`U`8Yc)6p5IZ*#D&FCFjG,jrje(Jj"+UT
+$5[hX"(Y[34e%*Y"Yp!qH#MkIIQmmPpd@EmrLPQ%p5Ya(PkdKah*ciP8acqSK15p
+f9D4aaj5$XX0NT#U$rhV08Tl6k-eH69cadqJIFET31BAL-TJ$r,Z$q*IF*Y*SDQr
+BmDHZb2-X+l+&*ah,r*pMZVCi[4SC3E1#,6"qKi+,f"efBArZJ$`iAA*4,I)J0VK
+VHj%!bc1&,9-SPckqk[F!&Sd1qBBN2(f1c`G8h&QeVH[p3rEj'3d%@maAL,45RY1
+X1p2&$LDUi6pmJfMELS*aG%1aSj'C)ZQ3!"k*kqh[(T!!$VGFH1'[3cr2@aI,PY-
+B4kdMqc[R$Ui-c!!35+!k4'a#)cB9@l5r-#F6m&2HVM2)%X-,AXX$0Eb$+GqQC'm
+a1##*40P(AAS&d5"PGkpjI+0d)MUMFQZ(GS--aJ40EMp%0qZe0P,4m`De@VF3E+T
+$*"IDcded'V01QbNBAYrV!9pL8V)6TiH-,@UhDk"iYDXJHlI)+h[RBU5K!NS2dJ5
+&0F``q9(9'52AkPLh+r+BCGaV5XSeEreQCi8$i!V+8UmUHliT#$Jr5L&EC#39CNp
+kmlHqEZ1DVmT9lI1qh-"&[FrY0p9rQX-&5"5'Z%L)XE#ZCRJ@Cc+[&LNE"aXb1+2
+1elDjbClE,8Yl3#e)EGc3Uk%5FA(MQ0m6jaTGi,`N0-SZjSQ&8YUCppS-Y*&+qE3
+rDLN5[jH9p'2r*EhM2*Fk$TVl+'5)Z5Rr!jBN6"eV@-G,5q3L&fA6$5FcN5Ve@'b
+r-m3k2Fb3!1GA9&peR-6p%r@@L9R5iU+S(kTLTUU6-$#N#Z*ji#V+,F2MEP#GG,M
+%Z`HBUV[BLf(YIGIRFZ'KbB+K$4G+d%im5-eU"$&dj8&J!8$I56feUbI0),Bj6%j
+VE1K0DiI@1,@J'f2Y8@cP&IDHjDK2YSp'4-cBM#)Naq'FiTaL*h"e,+Ze&mSk*!R
+j5ZdP,0'14ISrIkq(2iJ!@C!!DKJl(S8dPY@GED![+XlE9Qch5SYA[N$ek2m0ph%
+PdZK#h@'$ZkXU@iq$[l)*AjG2@SirDaT@k5,jClIhd'C"GTJ3f(3Ufpdj39"S-l(
+[aGT`@j)p*JD'8iS+MiKDC0YB4j5m#0'rKD(U"f9h6Ei(D`rU4dZDD10GSpN@GCR
+hp'CVN!#62`1U@#'FKAH6p0VEEDZqS85XFqa(#+#3!"4%J(L&[mK+d921c,#d$8Z
+iVJ`$8e0K6(,3PRp+BD5P2qETXea5%N@Ia[p)V1pc)!0JU9q$PQ&JDK[A01cNIX@
+hS0B@'PHdiPfamELE(3@djU'-BUTaNQCl)D-KU!ZE6$3XQaaZ0(!ffer%68`[(Vh
+rH6cHfVeB-X*EKK!&,4Amii2c2'l4j2`CN!"a,0rae8,md`-SUUjbS(`&e4@lc4K
+%jHr(HNCdVDAXa-&a3%1UN@`#d8NI@L*LeG&EM31hd"`E+TeXK6EfTQa0kk(alc,
+#mliiDHTiC+hm2%@bqaqC`PBjrRMKi009QIYKNR@YK'#%Y#V%PR'fVd)K#Z09JpT
+jjQ`63-MEh8+&3f-'N!#A6[hNq6Za*ZfZ4AQhNcehm0B9[9+@J8dkYTeA3IFqA*c
+D&B$$GqReQ#kAFR#k0DH,RC&JFXejV`LfIZ+BA2VTLT(M#DmYP@eXABT[T8dFqZN
+-,VXX5J@G+JE6AbC8k6e)SLH,9k#`GUGJQcU2+&RiikjT&aTLHpTieb!6p"BLG8V
+L3%0T0T6)h#ZR8YhZ5V2fearLbA$5F$Q[!UUc0rFA26i5[biKZlfJhqLe1&ZIK4B
+0&&&G@(1BiJLKMVVUSSF4GrPpY'IPThpQ-+ECm[(SA!!E0iiA*U6-(A#22jD[jij
++p@4rqqU-24Uq@BBl#82#J'H-D8hh`pAjq*jf$k!e+c3)fqMj60S+ilj9ArrCD@-
+`13!"+R)!!!!-DP!J)!d+K`S!!!!8CR4jF'T`-L!!!!!!DR!b)!!!!%pUF$*S!!!
+!&QPSC()!!!)!!!!#!!!%"`F!!!!!!!pMEfab!3!!!!!!%!!!!#*MC'9Q!!3!!!!
+!!!%!!`!"!!!!!3!!!!)!!J!!!!-!!!!!DR!bBrp2re%!-J!!!!!#!!!!!J!!!!!
+!!!!!!!!!!J!!!!)!!!!!!!!!!!!!"!F"!3F"!3F"!3F"!IpN!#-!!80bC@&dEh)
+k)%TKFe"PFL"@CA*cD@pZ)$%Z16!`,M(r8J!-!!!!!3!&"!3!!IpF!"0!3%K)8%K
+)8%K)8%K)8%K)82pG!"3"3%")5&")5&")5&")5&")5&$rA3!8!N"!5%K35%K35%K
+35%K35%K3red!&!0!3%K)8%K)8%K)8%K)8%K)82q3!!!+!!!!!5Na!!(rNpq'L`!
+4(HqSj(pDEBFTqBEP(qkZI5jq158L5`m-(XKM*km34NY+iqjIBKRJA&qM'aK"JdX
+,Z"#GKD,!GbBUj9k@-1c1Gh5b8)Le%2XP',bH[(`0C-8kj9L+d"JSi-eXc#h0%Yb
+5rdqcAr2PLe&hr%S#Iqc[0#GU!fKP2"*a46YblD0cJfbb,UZmH@T%B8JXeKUHJ,q
+jQi4T#k9!B-!Qe1f2NUY*Va@EIC%alqm+d))E9`jmmGarHLD*eHXf(&bl(#P-iff
+m6RR2JZlE!E$)2ffQMS4hT#6*dV1B6aF*-hS3Qe1["hF81AP+a@0-Ye"X+!)P4Zh
+0#6,$[N0$3lTbAZ2)!c9i&M6aAk4Pqc4H+RLPq@2"-!-c'X9G[pq&lK&2!G,P[Np
+k`1Y"q3BD")IR[FSC)r$-qG("PK)!S50JB@%5N!!R2J0(9YETF`JiZehPa5c3&5V
+"VkFK1U1YYaV`-`e@%)XE'`Yk+U%AY'2q8l#&[-GqSR[aCE6`d`2QMi9lZG3D21r
+dfdEj-d4Ef4Bc-RBeG!iCfD"ckT8,fJCCaAHPq,CHjPpV&p!BJKV-eRcFbrB-&U-
+3h&J,k6qVCZ#P!$2CI-$0'c9MhT-BlNEYB5$Gr)'JE$$QZp&Pcmk+8qL-Aj,2))&
+fSX6Z@&aH`Ai!pKMX'TEpDVY5$F0lDNVi3V0c1L1VPe-+*cKf$GL)QJb'MKh6K[f
+ehi!i%9"8Vr6)Ipq'Li!4(HqSiE*EdNXhPTUSAGk96eF1c+hqr10aX@PVrF"`$TI
+Dj%'YVQjQee93Z[kbdi(k[ZMDbRM!G"C8h"Cp--RPC$6%LI'&)I)A8IVp&NDj@L#
++NQADd"0BaV8k@C!!Ejb9b--5+Fd6@HYbXbDVAbQ*AMEXljL),"Y8E[k#mL2FL*R
+eIQNr25*4(%X3JGd,RIpR(@+CCQ`"`[Z)Gp5[M1FRjQAr6B*S"%r1da8e@%e39SZ
+-$AFI*Xf(HRMU'HD#'JPK$T%3JT6LB2-V2`'fBNLccJqQmSfG[GJTlVPm8[bSTCi
+`Vi5TUV1)lrFehc8409kU-C*-U([VJ8P#,6B+fNp@SK,IV3'%dh'j%lhK,8H`RR@
+)6H8pXK)4cm,`[cZ#IRFSCAJRGRS`M+*fcj[(8G85'2pId'Qc95UL"F)5`de$F'"
+I9+-fB*KpJ9+)9di+EJfp9(r+S)D54'Qi)L-lDfN(h[pm+d[UqL+Y@MI9Bj!!kZ0
+DXmk+,1R!Vr@%',E)HK(RakKCd)lK"&qPm8J1GKICf&a3Jld-(4QTHLfU'J93308
+LSmclPq2aiI&J[JAQ&0#h0ba04dD&iZX)@YU+LFbrc(ZaCj[dBPN5+,+jJ#4hef9
+fe3BMD,mbRIQBG+[3Mb-UI56[dhXkG!qr*c6aV,`"ITq6Kqpk2G1-$jD'(&"&%'[
+FVJT0Rh+XXfP&--km0(99(dBr9rld!R#Qm!Dp'%68F'qiNX&3M&IDm5DDh!R"@J1
+@V("G`R!M)#eINLVGQmYeRRjQjR-+b3L-*1UIJ,p5%db,d"4k$D1%3D2%5rVD,&3
+r*9(9CR[jYK`-JL6GjCbVIe8eZ%Sr[mkUQqaP%'e)6,)8Eh3,f3GULSb,$,e&-j(
+"9Il(2XUk6A13!&B+6j2i"c3jSKC@-VVEXqT6YX0[hXiPGem*&5FaqNr(-Pq8Kq1
+1Fq-+,II+$VCYp+61dN#"aa@H8(ASFj!!J))JLmU%fq3I&#bc*&#+%KQ85G+*"Dl
+l6AmMdrmVH$B9[l5HT5BVSQN["&%,BrMiYC!!2rB$A3bAH*d@ED6V,Nk`C-fCD-X
+mrMr0$IU58V6DCc#h``mpD3*`3lrR")Ne1K@l(40hH(,P3fpS3!5r!MIS%Q9pS`m
+[6H6Zk3idcFj8Sbriia23*)ZQZfbZ3DSlMq3-q2XV5K1rJ$KSPdAqSqkQJQ3SIqd
+Xm5ZLCEP#TATKYdb'3Q'j3815CC4IXKM&+UV&D&q!iTiiE'33l0L%kVmh4qKV1X'
+if,0FEE@J`1#@,NiTG*Kp6jl8B,Z'E6Y+,HQ6hk6Z@2(V#E8F8XQ@AmIEBXr#Z)r
+#`@@U+rcrFC9aCk@GD2cFjV(leR%@Sj!!HR`BFJ444)11bTjQ6ij+Gjr(`ie!Y!!
+K4-6VNa&DM5TpG(LG1eFPDVh)NS`#S0UhG")3GYpK#,T2NU&)F,Q"KCNH9Rm@cfX
+*+iGMmPjmeHeV%NNm3Y8U6"i35jR+re*ETbd*!'Drlj'$qahI-"0+E9`bI6MQ23L
+efqTcEDJc%iC+RE'%U-Rj5kb+C#rSp#CAeR*Q8VEk36c$RVe6#FFKr!Pe8"Y#TKN
+fb[-JeB-2CjZhS89D%F5Xa04cVI-p,"A4!EU'h@V5-eN4#%'44NJX4`[N[0V(`DT
+8cK)0hBi`J2BqcQj@FcKfA3e03TT*GFpQ4Gm+RDRb`H@!jEFQZ3H0P)Q!h&XbHMY
+&Z*TQ8)&2j38eX%dDJiH2LM#-)JV1JT)V$kASASA`3DMmCQl'h)jK$$e+-1jbXA(
+Qlc*+d@N3bpSkikeljIdL`E1rClA`ajUcL*ShCD*DQKq4HjRPHbJ3S6U'ph@IqBZ
+FYNf3!1F*S$C@'E#m-PMe(MRZL#23C%ZdGm1l,1$Z5UYR-FFRFLajRi"jKhdJNRc
+[bJ#P%pjYR(3'Re)%5+15H1d9f,Ki-@%T2Y!4Nm(dj'LMAZda21`[c!pfGFecZ+2
+8D8Y`2K8EH%35GQP&jC8BCk66ErM-KB-`3PAM$SlRSVafBpG2kU[0STkX1(a)e'e
+RcCc3c1%pBN6i04$(hDTZ,SVePUH!Q"Yr!Z$@Cj(9!Ud2B1C8IT[+RNH6pp4)8Zm
+,FS$2`ZHr1fTqGaKPH#GfHMJlSXlJClj#"Jb!QP')3qe'Ym$EK9b(,fB#jV8XEY`
+fHfL"K0%(jHCDYR0AJc$Z905)BYEM9(,8mVjK'@q)D3B#YbAa1m`3lmq+$hfe&I2
+M[,hp,2$P1qpU'*kFcTkU%*'%i+Be5Nj18lmRC*+"HJhdZEV26TkM$KmBA!6(5c(
+AIdJ'Jkb"9YFSMC0fP)dRpfAY!LZT(RZRPLEKrLC4ej&1%H[3Xe+IJ)*q[Z1&k+4
+0YGBP5$G&3G!3#YaAQqjG@)Hm@M3-KKFd1UjV5D[*dbM+f9e-5lp[)+DXX*RKTPH
+hP3Y'2eIqp!*N[Ak@!ej1EB$)LXiplMke!@"BPeR1)$!4dfeShS+)EDS0cSqQRGT
+fqR)(Z0"pJV,I8!"Prb-Sh"Yb$[35(+F5rB5ql62fNC-fA9leIj+G0!HFkmmA,Y-
+K!f@[8'd(f1610!"2`R8Yr6!ReXLK-i"6RV!efk&i$('8BjjpXa#*lp%S'e4N3'I
+Yc$f*HKEPeB34Qb!F&R-G+PQCl34j0&bA9R)1T4#pmkN%Fm*9+Ydd`%HQlGVXHpG
+JSk*l23VDkFrQIE9'Z#4"LL@6M9bmb$$U&`Md0L3V5KhcPH56*A#D$YBLS)mj,M$
+Jfc6hr"+Y-i@%66b0Z`YNFT++HGa*S-+3!-a35fkK$5BkHUA18m9dlGTCL14cZIQ
+C0L5h9YllSBkr3"0I#430ZZ9bEMbcefepN!#FG*MMMTUb'`b6C#8Nic60`LmTTf3
+JYhrZ0b@+%qF#Gqb+CV`mBkr&eJiBe,#D8R-YIZj8iKdK'24@CmBrGGA$H@qrJNF
+2a'EYkQF@"(XNd5mPei"Q2FIfjJ(ID5hBNQlLEE&1CN$dN!"F+JVPeSTUQ9iFFh9
+0%jQ)6ccFS&Me'F'B*b-`kr6chjp2&qI662ckFGf3!$1T[)GNJ,992i$CMK')2Sk
+I-(r+dJ1ckDc65341+9"IM`SIeDe[S(826h8HCKBNakG9$JB,lG`TJh$mLcNF1"h
+L(0HX!r*GLDcFq8E-FQK#k9+rCNma3Ei3#`DH),3#%1`#&(iJV+F@9rbN(1bKPXC
+6XK!VT'%JK10h*C49)A662lf3!("HTbh'6&HR`%`K1&UqB9L0hK%fXRqNJ"`E1l@
++,PhNpdhjTG*+&fSIrA5f--%!qlSmEEh!baBLYScCcjFp&Yr99m28E-HX-L`%G42
+'"k3Z%+"AU12YQh++rLYBN8EQQ4M6U@MXD%SF2U(QK+-8q6i0MMX4Ra`lj*JiKXE
+Xa$mZeC@SelQUTNpp5-`PL`"Em$YTMG+c#DNeG`[Af"aYXh!THN"h9EA9,,&BR2,
+V8`LfZid12(2-C)kFRrbBmNKNEH[5@`5ZBGc&ib"+DV#$r9Za-`VG&@De4c#5!*4
+`!-Bdcq9pimL"5c1(Dm$e$%i("$6icPZ``X*[m'i-+9h%RH4$TMLIUUI0,FAJ6Mr
+DPe(BlmYH%UU-JY%G+Q!J6dl@04HS,,EB,,IMR9[EZ*BpIijX6*R$Tj(9C@M+a-Z
+kmiSLE(b%4A@bT3-16X4&2`M)&YQG&DjhrBMTC&cqX"ZrNcl@`9321C4cQ(eES65
+Qk(6q80c+NMZI05F[)m)lE*pXVBq1rLjacDV@R*N,D$!l5LaA@-1k[j0pB*Ua5`h
+Ym(E'R`0`3f#Z%DiLmD1Dq!NekNe1*#Kb@B0@$`cCfb2%M4UHYAam[HiUE5d1*Z#
+qKZ)G*&1(Lq5MG*0)VP`*j@I5#aqU9-UTPSA65F5fH@RZXJEJcif#MmQ9EjRH$p2
+#'NLiDPIMS9Le#6AMJb``J2+6*i$p)PJP-R6NAB!5FBZ(4pL#J+E(-RTbF[VZIM@
+Jq(q$DcJ()KU#q8"*!V9Y8XPXc9[69eMcB95@3mSB2H@8p43SH2#p4PB0'Emf!De
+3+$8P0$mFMXNpj!F%f!+"q,j-N!$L6L84#iY9GVVrBL"G"5p6qGL!+4lN-V'I434
+%bDdp"klU3'NBHrm(raSIcjB*L%l&3TM1U1UM5Tk[*8-Z-Re62L@ma6b"m3$MKfq
+%M5RPJSKJJS6d9M1SZjF%Z'E@VVRq`T`Z(Ee4Smr"0`l3H1iV%)@j+i6@2aLZ-f)
+d10[F`f'b[*AMNrGrSjqVkkHbKY`'#Y,2)+@Vq1Gp%"Zf[apU@4*CfKrCcpNYfST
+NI#$ek*3-D38VJ2"(`BM9'+PPj,qNpLa,aj!!XPh5!S@DG*[mBmKX0q-J(2"(Shp
+6@eYY#1C+d!T*RqZTGIG*[PSR*('@%lT--Id'S#%+ZUecHjmY"541Gd@SLqi6f3I
+)2S35L932TjpmDk)8V#C5,$PiUBQ#c"iQeBjKrI0%M62@%SaSPrE82B-PrH!fZar
+rJfH(,IPqaKCJ&HCae)rJIYJRmU'LbYiRYX8RNM"@j&d+BDVZ9-AIA9P6Zr*CXj4
+A`DrRK,5eA)MQ"m&@4RE4@Li)rJTHpVU6D$l*M$Cf&8m$K*H"JB&XFAX8"Ad'a,r
+X-I&!f'U`!GVHS6&IT-d-mBH0CDTaJilmVq6LkmLljihUhhh3@-#UiY%V5@E9YPM
+G)Y!Bl4XL01['#pM0C'BBT5il6k*4NA'*%KG+4SrKbVjIKNC[E$RlRCAGYq,F5QC
+&r&5LDj5AI%!8!BAHpQU+Gkb"lPql[Afa*f"UKeEEZ9(&ff14GLChq6cM2ja'GQR
+rFpZTIEp#KGf8q5Q(NSC62qfhX@hVi'40kTaI%6[LBCm&"TESb06dT'4XT-N-Yhh
+iL(jmEFlBiK4b+,cG)f+",E0U2Y(*%0`UeVplj+E`ee,2"4$#r8'3!1qHCGBL(#3
+q+H,`f-f#$rX`Sb9[R+Rm9,YX$S6A1FqBmIJ1rfZqra)b(Sb4KaF-*pePDj!!)8&
+d[%'N0GYB!2N59Y*j5q%b2YUcr`rkZ"5,MDKLYlSaLK`&qe`YDfUkXm6dSJY@#46
+c&l9qGj!!CJ(9PI(9eT&VK"J)UqmdqbfA!bUrbhALJ$jLG'0pJN%&E@CB2[T2Q8%
+EHrM%EXiq28*%80NALZk5IKFI#)kNB)eXhr!jZ(1*2X4U3bK+&rVF#13lL&q9TbI
+[43kG3I'1L1%aYPFSX,b5qdqp22e4Hl+V`PelA)(53SDblDCA'IfU*J'HlITb'mK
+kSB![I0KB'AZrZemG5mIIYHRkN!"!JMfRXeaRPD(DRh55m9BfK,bNNF))%e4"5@e
+TLNV3EkqZ$AlkE&,"P&km,P%Rm(0T`N$p0%Er)cleBfLdh3"T"NeI"0flj)hqZiT
+iXA(!cZ5&(ZMp#f3BJHFU9H+mYrPU6Y,Le%*%DeD3!)4EBrSXH&Ak&*HGH&3D-lB
+!rGaP(hDVAVVjSGFkcpbp`K@r1ClAU655hGHUH)L&qU@labE&Be64i$3L8UYh9YY
+TrVARmrM9H8(jecZ&rVCI-%qQ+F9qe9XUPm"'Abad##T6"RfT13"rcm1J+IK[0$l
+GrGf5R4EZJBMmeeCM'`HBqUKcj6'#ZL5fkZLV`G$q)TSAQF3V6E$Nc1J!+`UT@%d
+jA*E`a!p`+Gb4maJm8+,rCLYLf"2`3KjPFc!@IfTb2m%6K)'k)J`+@h3M54&j&r8
+-lS"qQ6j5+0LRG"ZFk@Y[fe$r6)*[apBKc&BeSNTiNK0D`%A-d45@e4`QGV$r*",
+IBimE3eXM*c2N!A3Lb%GLL1%4fXe$4IYAVSqKj,"jhr,CNfh[),r9Hh[ZM28Ki`)
+LfFrk[1Kj1m4AY!#P)GG3k0ZTCI@QR0aah)#!X4)i-T!!5Z)UHlhTC'H-Arp"UkL
+hpM2[YkGm4JFH9!M5kG'`5b@+T)34S#QfG9XFe"Q9q2kprefBG#AR,XJ!Cp,rG4q
+aj,kB(p3cqk[A*A@"A(CZ&9e4!Af5F%ecr9dhM"R6JMk*5UD!dLX``HP#mRYBYkF
+2lfQ4UZGDF3Maqj46NKhfL63YA5l&FPf%2DN%#*Kc(#SR3hFqK8IlJ[YQBENd6%&
+Tk8UiQiICNHf)mLFEr'HNrdEbUGh[KbKU3fI!DpRh$`X@dQ#l'P5CK+%@JZbB1G"
+Kl"Q98A48H8H9LdG'!`4bSZ4pFaMiR'jaf86eJ-*Bq@(3rEGdjQ`hkZ2UM&H%$P!
+SV@C,,`d)`iS336AGET9KKK2hp%F-B-,$6Ljp9q91'LbPkpmSK@!h1Qek*djNfSe
+JLG[0)brj5ae[IE8MjJ3bdfY+8r%9d,8NVQ[B198%'1FTVlrcq9LUTh+SEql(Yri
+1*hRX0alXHJN`A,(-r,HHHp)mPhQ-0q%0[KSM%1!5pC+6FCTl0BMJ#RDB006002&
+CYbf1D8T,pBIHqSNZc+)-'$l0ZKB*d`iFMA4[,UXc8ia)p)9Ub4TQKJc@f`48ei6
+XY6Qhi'HN`jjCmB#(R,AL8F[%2P!B&K(AIfZXkp*B%XijKYHe*kS03Rl'#00%Gkk
+l+Yefk#LfJjifM(R22Ml9D25rJR`9Lahmp4ZmJV[0YaPGJ"L#Lap3!Z"1b$UVkPM
+IRe'G3Df001,a10+pNLDCf@1@KdC!a(GA'2!ld`)RHa96[jSX!,UUI%"Zbj@Tid+
+`TGKe3%H'e2VUmq5kF"rjNE918rSbr90*TfI3AdFDQK@eci@8U"IVLjGRmSDd`$U
+#k#Y-qr)9hUmJPCk+Jq#@S)+-)l0(RL'-b0JfPRrF(T'0IXU`E9#h+,fhfF6#iKY
+YZ$`r,(3XkriJ&*G5FqJcNHaJE%d(9(j*+A)5D#+ih#'BdI9YQ'ZbQeYpbpr4ZHd
+"ehk`0PSY9RH[*`NJ2B$e#hSJqhR'!c45AST%6Ec6cBP'qlL,m'-@44$62*8Y#ac
+#1e2XDXKCTkVX$e%+TVQ&S`MUGB+Ec"CZeK1be4Bf3(D,682ihZZDB)UEph$M&X+
+@e$qR2$LrFbI-N@eDQi'Rr"JeE5QR-d8kmZIJFc6K!%'EFZ!f"Z-N6QN'(Tk8J24
+*f0dTSqJjXai69d(Ber,`db(9"jQCZ[CH@&ZBqUMD9l$hcEm#9#8NBa(UfX%X13J
+2fr*&U9LF6b@PimR8BQPESjEeh-0qR-mlhZ@0X!B3GD5refDPNirbXpZ@jm"+ha9
+SSjERYcBe[eLJ-ph`C,GeAC5BciMMjC3Eb5+fI$TFJKS%,TQSMSNlC0&,IpI5i2Z
+'%%&U+HEk0,,!E0eEBm+L5Am6VR`X`I,#UZL"L[d'kK`+A&SJ59[PT*SK`KYMUV&
+l[X1G[RQ"fk2P@9$C"LfHGd9lek*Sj2NJ"C!!UTVi2`%&-[*98-9RMC1G5NKl!ar
+3icpd%@Q1(VlMXI#$H0&%0VCl0'&!FqV')q*3TB&p(ZC$mdhdMPf%)NLkMBjcBP4
++@XFA$$)@d8e28fNZ$+a4qLEhYBQ8HZLaE!iZfr'IpC!!9%AhDFqP-bELc*AUK4h
+CkH$48rpp4b,`"k4VT6&qh8J+V4c4D3(Z[#ZEGZ`JSKkrA@Lh[DmD+EDmka6dC%)
+0XrF5RC[&$qkU@Kc60MrJ%hM#!80AV,0k`S$IRdfAjp(Xr2T6hBrlHY@rl+e@*bS
+d4K@qcMrCNNN6!@424,G8A0Hl0MbYpAA`CE#5kXXa1ZlHPrU8fR'DcRVFN59Xl2`
+9(GcLMR16*5-0XTKV%3('"RdAPpB(+`DSf$S#9,k'X35-UdGQJdY0UIae)D2#c@6
+fQe6aEE`ph1[@j)GG)iA9"5'95`mc*0Zp5d*h`XLHe+9iGB(aSlTI%lK*34b+IpC
+%SP$&KSM*TTV#bN(JpRPVl#ICH,GEb#Tdf(3`r(SSVL&$kb%QSE`p0+bk%KpT`kM
+6qBZ3!-M#F#2Bf5[`Yh91K*ihF5")G!2K!(U`ZJ3U8D!VZmBQI!#D#qf((JH1fee
+1SLHc'G--Jfj2%%J)KN()V#6#lR9CVlhf0iF3m$lc#f"!$-U-A1')Yk5f,PB00Fd
++4Qpl6biB5H5rlS+frYF6QkXDQ`GbE`b)(FFI3p#N"HI,8ZbR#H,!+CldNBU*fZG
+kP9r'Y5X2FkBBQQ%pfrpJ[&rq8(XQ4Xp`e81UHpN0&,"3lF3N94T&"fqEXSaA&'V
+S),S(`0mf(ldr&XVLK1rYe(EACH6*4E*J"#N`ILE,TkTLHcBfA,Z@VCR84ejRLZB
+,4bCIX)Kpa@*36C9rVAEXDHi&DPRA2Y#)(PBAk3,FJ1$A2EedIHN(8jQZ`$a+DqU
+&AAVA&BdU+8F6$8")AQrQL4N$NBCmhrd#GEbR*9`TZ%l#'c9AQ*2!aHBP+el2XcN
+UDd@4DdI+5)YLQ`iJ0VBV,"PBN!$j9!cF)RND`@SM)Gh80Gq#IV,ff9TQb"af"DB
+-5@EJBD*),qlTRA*4#2j9-e-3,(URp52DSYk*,SP52Q1&DB+2bC9[QGl+FS8bFJ-
+k$I"j,bMDSC+%h'Na([&HBKpKAYQjZCk"I3-8#RF$,PBQC2Q3!*@peq(a500Up+S
+3$LI$qh8)Ym$YjI(GSlJAKQJLabLV8KK8h&dJMlX'+kS$5Idc)k@0*Qd(Z15*6Dr
+HN[FGb#Cc1a41"(DKXp(2"T`Vm%#VhL#hkH+k-lbKLbNGYrUr&bm8kC9C5p[jeZ'
+X9d[QL@PS!kc8P@aJ*II*D*GYVcJVGJ!J2VF2SBY,"1AJV6NL#@66X6C3LCVY1f(
+4mGa!V*0[M8j&jlD5hSQahNABfH*N%[lD'Ke4jZ2%U&0QGmbF#C!!DKZ"l$4IFSZ
+!2(pS8`PJ'D3U,@Z!f1AqM!(`GNe(P-I%*XPCBC!!1PGQiae0Q@RJpQpMa,mc``T
+%f%Da'b#9XZ+@-(,YD"iipT+XU0MAXaLIQ$bI80!fB"Zr35qQ%dV-@qhYIR0Kr&i
+r$QmK)Jma"&Klm%)H8Ii++PLT6I8imT[rFChrB)C[V3"28`lU*h(&0C&mZ0P,a8H
+dkjqBKG'l-#qmhR[j2*fGYK!iDkcV&RCqZaK308TKPY0ZAa+#'UidadIGAh#il6(
+ALm`0Z9rr22SAppcSImN6TTYEpU5@VI3qaDE[4r,`61f!,R6G4"G"`d6U%'C$dqL
+-651Vm4LQBI8&3%cKB@"YP$ACA@Q(4+L'ST0FHYmbZq*K3)R1+mlGcarM@-G(5U+
+hjP(EM+1@m++8efeNX`0Yk40Bc+V`l9*DfMEAm160qMMQhj4+DkV$hBimB'%!qSV
+kjejljQp+!Tc3,S6eaqTbGD#rLfd33E-[Y12rJC(kTVN)CNS+UF3R,L,djiY2&*N
+QMXBU!Z[[f#(UmSf[JkkC9HD0dMVc*([('APSjXc)D3&l'i'N'j+DCqr,XhmE$[,
+JeJ`c9D3qP"m!Sdi(ijf3!!$'P@Y&EMF6IbMUT)K'E9%*+Yb9BkkKY[Sb8%)U-&8
+KhpAP%%A2"p5++TbRi6"Xb5C0"CmcT,JX&ra$rh&1Rlp)Adf)KI*NFBTMNeYZeNI
+f6jrV34658[ACm),bZ(Tkjq)J0YfUp)lqilqp+))49LV@,KAcCqPlN8RGi-U`#,j
+B09ERe&[NaA['FeDiD-&FHbA5)$4l'9G"[LdH#VU,P&4rF&0[2%mRQAHXNk'R"R%
+[fpAkec4AYJ06&K"0pf,cq32)FNaFRd+KhVqKVU3GYEq%EK%b6c"D@6&NRQ&k-aP
+6QcqTaTV)e3(GKr6LYD)0alME4)TQBj@U'#X6,KpbM'ei)$dec"kIl2RHY-YVD"8
+AICJ6j6&G!,@9)QF&mD'U*cb!9LDrIdA)$43@$pC(ma*Z38[,JQA@I"CGHp8CCLX
+fYlflI00*0j(('p-!@rA'['Bcir5+F5HbaUT4NA-NEBG1EFlCFA(+80RPMlaT(6T
+l3(@K14LeG!e,Q@GipNfXp5++Rr'HjF3I6F*9M`VC3#HRZi+cJ2[qAAVNMrQ#83'
+Q`bKPmF`0+@Z`abRq(ea$#J8[+2L%5(Z'3L14f&%V9eC!Ai5irIj,pURU+*SX9[l
+3X[*FXk*Icm293[cpB+IRkU6E'E"4hKJD!YJ1eH"I&CaILFC[F+2Z$q(X1aII"(l
+@ANj(YfY%&kNH4K`Ip0Rhf8[6f@Y4mMZq1MD@C)jBVYRNGL-'VHUS*,%F6icGD3"
+N)+MiadHRbTm#4@54hDEhJAc%cYTYXll*N!$TGMGRI[UV2E%Di*ZU6r64hf1`qM)
+`Y,#HJGh)f(9GMHIZlp"dc2*BQ&ENZ0JhIkr45$4R1)c%q+%9%6KBPHFIeaT5fc$
+cX[51L4,2Xf8M!aje8f6ChQDNe!04Ji)!BH,5dp@DL2!I268q(bG)h(+"&p@-r%b
+p8,*QZFpJ!KmX`XUS2iS@(hjXrdk8Y068*'2a1!83Y+Ihja9lSd'q+M*V1@Fq3Ec
+B1)jNJ513!*'N!6j`U+(Ke(JCa5TFE4@bIqD@1b"M01&AlZpGf4@J809'&(d(591
+RLX$p2m,8BmXlLa0)X-c+AZ&%[YICFVDQhe,A1k1kAQPV5aV@rLLTY6McJEFV*k!
+pBbX"LA(-RLhUfB()pY'+1Ci%h*`[+c%Dh$IbYKZ1K%CG)$`KT$j`!EM+@AIJ(hf
+QA"*R!ApY@'1'Aa)aN!"N3US-!Br8UXPd&3(KH)r!&L%T*9UXZVirem!PIK-Z(mT
+!jJe(`#YQQpGk4Vr9S(Df1BVBYEG[DY5*(LleSq@pC[Uhk,kK4ek&q0&'*%X`9r!
+Z@AFR+*[[,EBh)4@%qPc%CR0!G[N8chjFL(U"+T+"ZRGGHLDb)Vm!Gk9jmbiGBRc
+,R!X0U6MNNDk(LMJA+CUN(K*c-pY8XJYh56PqCrZI`mJXpL5@Iq2S"S@T8b&(mdC
+TGV[B*q2rGd5Ri[Ec)Sc$jkpi5eQDh!E$S5H1Vb(&LAPK4pPRKi24,IlQ@l*FE(b
+VeX,KFJ*hZrpb[5B(HcZ8lcc$(%V(eJ`kVJh5Ej94Ch&+XUA0%Y%%TX24p+-Bq%'
+R3UAY@HM!6,-pa5c%$HAEa3iaR#A")c8UiqBZrH[jc3Ja%alK6HZ$1c!%,FbM)1H
+X[IJ'r3Z1,XKcaA`GCcK`I+2dl*08K0maMKdJc1)$db)k2GQ"MbdJkhcGkSL%&TY
+LKDT8Yf0FLX%AkBD5i8jK!B%r(c[`aN4'KU-FJGIP9MP4MkMLq4RlkHP!@3rRf*3
+q-IdiFJ@emrjNI5Nd*,T[([)lpLCR)'h(daXHK*+YmTZY!ZMdLhpZ&0hdb6HR8a&
+F$GNUbRPADrIS'iCdLUJ$DT+5RJDY6&TKNCQaC@Dj%1"1)D6EpL0E5`)#5b-mbiY
+YZSXQ0e!bAZGpPbj6[&NY&(hUKfr,ajTc`faa*Y!cTJ3SpQ"C-qPV"IN(D2Kr1qf
++ISaqII29-GAkC($H1&lUb6,(l&V4T*ZXa'LAq3Q#$*['EaQC"T!!N!"'0BELLl1
+liH28'8`J,0-8H@Q(jQ0&*RB%C[GXe962+''BblM"`-,8%Sl+b!cLLC[f&FpbfZ6
+1dG1kXIPGK4j+E*T8T9dT0Ch9LLN![p`2A!kS6NJpjTXS@-cR44(@23f5c(SC+)Z
+a$Kh0rPBE2NYTE$&bdUfMJbd#'DA#BHAG-V0B$NP)6l*P0GU2Mch`XHMG0+eNUAp
+hkT5"mVDJ,mdqPj`0JKTl!eIGNA*N014!MKC+#Z90E-bUppGci8GFkRBl*eQLrcD
+"20M[X1BXCm293YC63jAhZ,(JfPi9*Eb[HDfKl%jeVFDVPTBfj)cq"ZMr(%S4aUN
+S6N5QNhqp[*[1`FU6(9XS%hA5#4%$YMeF3cMj)m9j`pRSi[a,i*qChjX0%RC[-Hf
+Ce*I6[Z+[&MCQH%kDi)MmE-JFJ"c2BaN4SbMK*m(hEhrG[BHP4AIiEf,E2Hk,Gr!
+8%U9'C6M#q(-%RA!'e'cbbe#AeCK*98`fM&bK(pI2$NhrAeXkqF*Y(&2RGi3eP)M
+0BTaarYE(YJ`lQS'rjN$mG4"4'C688b#5Y*FBUaH@`+8Z[AqPfUe0A%U+Q62I%@f
+lbcB24@q"!q"JK)HLXcK6fAJF&hd0p%Gd%h%h[3!d0ffa%l2[*X%`H(q$TT,[S9#
+EYkfJMhm-,CbNa)M%Y),k9'XpQc0Yr,*8i%`#LQ0L9IPJ2KY"(ANr$B@afhGQP80
+%20m@K8eV&"FIZF5I3PjB%kPM4(d5+DPMLr0McaEb$GVLZ"0CN!!B9)%r4RM@eS*
+c)"4%X$-hBfNR(CT88AX34Rj`e3r2GZf"hRZANFTXi80E4!E9FrX`3MG,f$KUd+U
+HehDE&Z0'(qaF6R0fq2p8CUH*05NG)T4kXX(SKr-GM-cl4-XY*UJI3iTZ5iS8AA%
+HHdqPIFaPLL5BKbH5TXPr#b2f8"EhNNAPrM"h#0!%[#aMA61*im,f%cDh%BYbPa+
+"%5J'[(3#`"Q@(+h[Cp6!&e,R"J&pj`GMc`i49)3iN!!"qMIff[I2h)I5%E0!DlM
+Ei@9"QNha%-Edh!M+kd3F!$[XL),$@h'Bb2#-Mc*p(G%!BYrXB+Cmd!$!EGSr-IB
+C)(%834b!Ba3+)f#G%#d&m1crBj0fMmf3!-*EI"FmGXkX,DpiVkpjTL[IULHZhLc
+hTDq8L,3r@SjRqbiKX%TV2rU-3qF4LLPbC)D`d92FL5,Vf'SQPJ&qc4J"BlGCGel
+"N!")%pPj4GK($p4"-c`p$T[chB1Qcrp5YZYST-*&(D3T"U0$keFk'HlENq$CU,+
+05&d'1VNP"NVr#feC!MVTA%Xh1R+J@X5A3cA6Vi[$j9(aK$X2Qm#+FTJhQDM`3Cl
+'j!iR-F,RrYR3P[YFLV-9-Y2@J)MAVjYQ2Ldpr+(Ii9jf)0TYJKVl,eFXhN5[U8$
+Z209"DL(LZFf0XLF*!9jKk-2"A)M(AL29l,XEY0J&(N`kX%!LKPEMpH*pE+9RKm"
+A5rL(%#AH'PkYVkdTB*%ZjX8p0815#RC&B5JfET6&FlVNk#EEjLq-AeL4MXqR)L&
+hX18ZH$9"4[+P!TF@ajH$UlklLB+q&3I'@i8"H54FfUr6iVD%k$*Sm+)P"B2-j*d
+#(DdeT6Ekk0))XBTEi,!KC$$Jf8cMMRDJSHi'#Jrp4GS6C8+Q,PF-"da$BkKLl*!
+!T3T#1'1V9cVZEMBJ3TiQ9L6##0YUUmCE9b,fHdjcN!"YELPlVLRV&J)899mG91'
+Ca%E`'d*Bq#VM[A9D%#UZlX*8ZGF@*6I"d&HS*C!!j&Ur!E'SId#4aFSLE)8Z-R*
+JFQD"Xk*GcRSR2$P0I8JPe#D5iUeI*HeFCi01pY5-IHD)SIZ3!%i[ChF)qb,%i'"
+I59*+bP-qSVLeQE*VEU[E0l2fbac9%3V#&XfKVXmbP1$G'RV'KA8Ee&@HLGVjrK*
+NXTpBr#0rX$!P0*5eDHBEkDVrH'fBU@@hDf12ZebT4JJ!+V6*K)jhrM85T`hc)ac
+D')!V-BJ'1$GGIdjpACcXqB1@*@iE`ad0%LK@XJU2CX9Q(2mMEh(`f%[hA)cI*`3
+pL$aU4N8Ffem*X!3qaUA$["k(q`%Y#Mc8Z&)f1)AP#A&NTL'aK8lf`$dY`(cND[,
+`q!mmfA!RAp4MVqBL(#mchBhEEr3H6JH-fpphY(r592+X%U9i0&XB1T9h'EI1$'4
+hIpUXNdef3CEeHSEK"fl`bdQ0ld1cj6Y$I[UZq*Q5a[VU%S)X,5A!MVm1[#eq6+)
+9GEb22R!$65d(GHFDhEBeBcDa!hjNAbjm$NY,!@8D-20aK1!F6DKK'QPL6mheaRE
+5kXG0SXrF2bPYh"cDAHJZAll+0SD!9KQ6Q'YlfQfMMik&`hLLXj6[A`,arel3iPJ
+)j,JQT#lFhTU9pD*BTZS-EEcV8ZfpdkDPAVbNr&TBl4"@h*p(&9!Q!V)18S+9Yf3
+U5pDZYihqY3jMjj`M-I@@B-J4B8h)CDc!XKCf*RGPSd(Z*l[ZVi)0%M0!LFm&'M5
+$bX$SMV([Ee,r4f8-B196[HBC8[p*#`%ei@1paG0iRe!@5@&ipTk!SKBA2'8!GH%
+89LX`+Leb5a-GBB29G4PUUaibMlHi*N+'2`$j6rdC%S-!S[S,jChYk'$#%eiAfYU
+jNUr,"2*bDaVM$D2b%BCTeDLNA0VGh'8GX%Q@K`PU'pJcLhRB5AFHDKAPBGEGq+i
+hQH&lQ0&T9@+eMU`3U4F4`-LlN!#EYbSb,rS$q9T`6q95jb3[brd[L*r+HYGr55B
+r[[%HAihN(E9)SQeGKadDF`lH+1Sk'-bd(6MKY++1@6RP[Zr@8qK+a$P6fS1bj@+
+9-qeJ'NY+e5NN3ci*UVK09pad!PjZbDVj2E&qipjHE)#pVK#0AclR2Pj'0JQKmfh
+lUU5h(k(hL5$SHG`ZGP1P%T`24b%G#!!CSha9S0QK1X*6e!qQeGGacS@'-+,I(`0
+JJ3JE$%Hji+h9qm4qEk@kk[4SUCbF-eiXN!#[AM#f8Yb"f`(h-&Z#T%Br*QS@b3L
+H,V'*JZ)pJjj%fp-GU8XkL`qUYRbf&r+ZSmE#PXQUhJ0ZHG)SQ5QP-6Pcm'&+&mP
+BHIk0lLQr2D*dCVYHh+jR++c`qJT`E-pbTHCXU6lBHNK0#"1C"F0'6[,F"m34bUD
+K(JCXUMHf[@3mX"!6dRE@-RFLQ@r[1Q@XP(Q[0#F$@ebmKUjMeaj[F[1kqk[F1I1
+A#b%JYFNE)N'@,4Qkb,-8`BkLaU,0l"ld-P[8++iMi`&#Bm6-aeVr"L0qe**@Y+L
+2!*JB@CZ",m[`mGbeaNV*YERCQ+HR,9dfA)b"ppZ*$JJUbD01A"%P1,&Z'cHdNa`
+8jl+`Y(T59eYPUD6AmL&%GMdfPirr$Plkm'Q#QLjqVjBA%`p)LFiQADSCDjAL55&
+M)`"A4EXJ%jJ@1@r`&Ha0mapH'JN+0$dP1-[(F2pPj0ZPJ'3@q3-M3P%N$LUXB6P
+hNk6XRPVi9Q'ja1CFLJPPIUbF'ZHYK@+E*JRH-*l(EdLha3q[kBqP-I-QLL*e52B
+A`hpmTkA`HqN+riN3P+&r#D4AqbEhA,+DiEc5LUB0C%Qf!A@4dLIimq4L`PmeSG8
+D9'!f@0h!(fDZ#f&mh,K&00*jS9S9M!!k)f`,3L9f,VBlm,Ef53i8`-%0+RS$f'U
+9m+r&dC[H0Ui[Qa,q$@IY+VMLa&MQTrf!!1LM98"*NTDCh3E85)df"N1E*c`R"E4
+f0HcS%kpJ(2KXHb-,Z&eUI9L8RZ3FR*j#p@c*hm"8If@I*BTeKRdh'4Q3!)hp80j
+e*(9TPkF"qZ$e(RPIT('"hhffcY`eh#)iKKJQ9l[JGCEY9ULcY!`)2ca45-AI&#i
+SlXfS9i08@lM`%+'ID%YK@FfaNlm'Np8#pVidE%S9*3HNQJ3F5k"fqbDE4VUd&(6
+j*'2`hhr,8QkemrZmrMq1NA4I2&-L)M-8Ib%hCcM")NG3S&BpU,N(h(QD*TBVAML
+U2EX&EM-JE$65,+@QHJh!Se8`H+Z"5L#AUM2iE@Gf*qNE8NTL`qK9AMq1Qf,q$Fa
+4+)B,"M6`!Yk!9`AXpC&Ye'2TjX+4d1GUeTF+FGbHpq[UpI&P!RSmAm`0PSP+G$8
+Er*!!2&YYE,FM+,#1UahpM9ESm$@Kfah4J0'IJjKH-%+f3MTlQRr(fqLE(fqM$$l
+I4B$MpDD6'[Q96L5S!UJcGi@X*2j,a1XP,ZV56aL)Je$&54(,0FY!Q$5S(1)TmCT
+("-A*Z4TNAq$hHRViEb%N%,eBrTCTdDmep`6m0"L0HiIPD!Jm1P@Y8Z3DiS@9GDC
+CKb9S8%U`p*hjiMBrUhU,40*S6qD9eVaiV[%G!RJm`S#D(Z@H3V'fm1ff$#Zc99!
+IEmqD*Ra(ebNj9`Nj610JT"i8#-+5'VZQIIJ1kP3Y@#G6%d1DE"Acj1GfqT!!,b)
+ijK$*`GG@-RA0md&YpRIe80%bN!#mLbmBmce&(qC!&bCbZCM6$Hk521T312ZC"lI
+,Jb6CGNCdX`$"KNN5XSb#%-#8VV$V3`eXqc9AeT4e2fIK$M,"ia&'D%rLj0i60RG
+DBTVr-Ec+(jh"S3`iYZHp2i4'Uh2Th2-H$*-K+!hlNAI[Dm@XAbhkRcK5E8@QTBF
+!E*54KS*MpS,icL(S5f54`Sf*G`"b1LEAB9-895*MbLZr1+*fd(Hj*[fT2l1I$I"
+E2K&d,5#(1dbJ0Ai6iT69qIK'"T'pF4SDjcML8@p,G'@LSbUC%H-Bk9+h9'U8j0K
+%cA`CK[24h0qmHlrB1GkL&0@MhMj)Ja'i*T(r)(QXq#9YR"hNZUcYDq,DQT6e8h@
+hi#YNDVap-r[9C9'"#FV(aS*bR5f6jM-`ef-@%hN(KZ"8K#h0ArGmI6l4h#%L[+A
+8Y+Upe(qrIp%+N!#qFlA&4RI-USkIC"(26XkrENaaEaeV6R%hV6PbrI62D#F[AC5
+L1e1`pmc(&(ITVbmmY9pYB@TM@lq5i-*Ap`qG+lLB!D9pB"U+"c&eP!I`(QAYd3@
+Z&fZ0H*p(*9mddhdAHq0N#jBkR0%SG3m[0j1K"PG6Jq$*Pq"k[P6YpC-fNCmL19,
+V$I[kR$@4+Rmbm00"T4Ij6+Z$a@YDa*)hLI+4aGfIa&%[JNZ2b-qFHHBck`53!,%
+hY'"3c@8jQLXqE4mdJ#h'A6!4+Klbi)A0EIpQTCX9S5l)ha+p'!&8I6%aA`aD'QU
+!J2Ie(cP4#qZCNHLUVkp5p8EjN!"KZU(VUJRhh0jbHpXrrbDdS"'hiVTCa6Bp)a1
+qdV"JJ[p([DQhjq(#GGhc#G@SH"85D-dlD"!VUF3aF"HRXXT50UhKIkaD,I'CH"#
+qZmFXkGXI+#Q5rc04e&X#I@m"bEkq`"C&B*A41-HM%a+L3IcPNV+&k$Ama&!MS5-
+je(mG+aTaq05Y(@'XP*!!D#LK(M0P4+UpDpfT((RaY8dlUQYm1VlCEEEEmLUI4fq
++Jap@)erbZNRc-A$DMQd0cFhem@*@Q"H+"MH)CM5b-SclHXpQi"XEkDM0Ql3m%Q+
+e#1!8eRf@2AcpHXdG2+[R2)J$0+Mi"VdDI'r('`AYLYA@Z(fF#46S0MIi0R#[FYq
+SZ(2PSG@"Q)jE*Am3@NRLX!hTT`)RJi%S-B,-R[&$hm+Q!BJ-UGY[fp9#arLN+T&
+UP23a-!+!9c`!kF%,3$&d)-+FKbd%cB0Im`HH-SBM+lJBh&q'`K-aJ[6bFD6EFjb
+fC1pr3SpXp8dAXCjN!e*04S$6f6P'6j9qHqpaU"&Q[FVY%Her@UXAGcbe0lTcP)D
+%k&NJ130+N9amUC6AE%hQ*Prb'qCHlk[rCC'CG$EY&TTi[36D!Ad%&fPFiL8Yd"T
+eDVef(0UZXXXM#@kB+2ZYX9mV!"dYcP+eP,pHh%(YBI6-5BYXS&LFc,Eicha(A"1
+K@5e)JNd+I)FQ,%*qkDB`UQ'[2r*db30HGmac&cXZ!PH6ENHCqkNre*6CVHbV`"i
+YD&T33%-@!SI+M-)'YG'-#R$4kc%jiHX)q2m1YGYdhA',2IN8KFfBCZ+@Z4@cC%H
+)EUR`ZD+0SpV4CiQVTB&ZQlrBhQNZ+-%YMjXS'HYfXrMAl&UQP+XHQSkBL)Z6%(e
+pi5T,d1C@VZP'NNEa@kF%jml'[lB!JDi8`lLJJ59`UUdUSX-G&2SrV63F2![p2BR
+Yr*)V(5Z)dD"iAl,R'q)!P8,a`NbJ&[9IKdUKRJ4IC)R)Y9@*CBX!Qp5-[KY)I(Y
+klBP"Um`@kS-"6rL@a9fYLa2m#bEZ5[`B)`SkD3H5h`hBl2Fm$Y#)YaCMS2C8$`S
+"$I#G`Y,c1PimKq@X2H09akLqBYI)!q[0B'SkaA-*lkqPV!e&5'C-*1pmPN)k!+V
+!!l9%!6FVmSAXD6qkU8hpADjI9MSq9455r0M(cYA,5bjmY#*TGf"4TK$Y(bmpZDR
+KVL!V4BLLT`b`hhH!`@ZPAd@%6$#)PTM3qlLrS2$5M6m-6kjKKP&hC9hpL`P,kI6
+2FdSklq"V&9BB((!ClSGA8DYcSF5YFl2E8lrESpUE)@d5ljk91LVfQrTKDMX6Y-)
+mM4-6(PG!!HANJ%#ZFI0``2cYI-R+X(Xl&6NH(I[hbY6S*Z96bIcBjaZci#PQd!d
+iHYKf)R1MjfX'('bMiUQK9Sc4a'j*M)KUDm&pdK)+S8"'m8!HH9$k4PXpISMHHIe
+F8&%K-AP+'+8CPFV3p36E*@h9adN$ff6d%&YB8!bP2"4``N2kII,LrApaUI(qaZh
+U%rU86Ip(X`rqVHrTq5N4mFVbi[E0"hYp&*jAH-hHh3P1'lpphAb*kN%Li,DA#Hi
+fUAVrDeBD`1[Y3CRF[p99!`"2pm+#0iSTYbL'lUfJ(CC0bapEF&!5b,FMT$&EqMQ
+UX-1MNjVj!lhGblFa9EG`J5K)4i+'@DXNMDmPErLSql#E&h*BHLE%AeC6*&BJf`I
+5%$K6IT5kXN!2iKUrNC5iFKq&84Hae6Y%8IK2Q+BPG0f0,F)d#QNbk@&A)c#1P`U
+HDf2D)8D!dif,YQX4JGD@'VpJ8NCPrbL$U&0TU0$d)K-6UjGI&0LrhGdklUTKL+4
+V[hH6rfH)R&[N3%Z)G#Ei5IhTp5EbbBM"%,dQc[ZcFL(8Rj8F-+0bCh&9[R4cKG'
+S9d@aF42jP)+Y`j%@V#`dDCQ"p3[#,ll)"L`[3@U,S*@djQ,lK`AZ4R5@#)&VJ(2
+3lN0E'6J-LQS!EN)p%366k2dMLF3$8lcifYThmZ1Zqm-HSk$3Cf*d-eLX$$mT,pX
+AiA(AJ"(98jjAG49Sm"BI,c9XbNj1"LAaapSJ!qrm+V&,6pm@TbE@N!$aXQ)TJLA
+VE,3f"66qlGk(-9PLha!90SN#`3#I8qdH3B5-&C36H@,K$F,f1F0E8S%"cC,IjcX
+P&8DD`0JD0kXfVFk9d)&Hp#$R)BGbV!Z(J$*"VdGe@8crJ,!UJ2Q$qR$QK$UkE)E
+0)$ZVREe+43i@p*hZTiip&S"1T+YXM43CdE#erLf(@E5dbjH$H"k9Y&bBjCqX@AP
+'dZhIU#1mjLb[#4cT&BSHUHXH69FfZc9LL9V#LbC`%9hRLC40SXV)!&mYH$dJL(e
+-M'GZ!Ylqep*HYCPdFPDlc'8N(VTa&fXAG53!Nkjcl#-qp`L929qFFKcH!X$iXYC
+CZ(Mj3Uk2Z1!*6QS4'9bRMH*I!8X0IjlYG"lK'FT'%2KJf-kCcP$&d32('p2YVN3
+f1+HYGGE2B!@(6%5VEG9JKIC(X9`C#EB[-D0M5AQbNRd-bccc18amp-[K'ND+"8T
+pil4!daG2C64,UTr9k3KRC`Sc*mTQb0h1!c4[Zm'$A,Jp%#rXKfNB&%5P+hBPXF5
+%1V-RFmFeU65E[81Zp`ZbVbCUJ6CkIJ0,1LTi@XZ)e9p6`FDphQp0Y+Q*4qFEK,L
+pbcabXG"P%3bD3*+!)ZS`9&L%-S#G!)2`j#!I6fUJ449dbHYQDTQ%AGD@h90e%[M
+ZNN9hjZ2Up4JMhCKf9ZpGMi9d85G@)G1+&aS99[pNq,d0U!1J"N84HC1URRYA[R8
+M!CSA#"(5mR,%Jd+-Zd)fa,PHehAr1A*Z,MhR,MmSaXGPC@Bk$`JrNFkfqAQ,k+4
+dmJZj5rP*)C)J0%6F2jrSaq#Rpjm@IXqpiVrp9"N[*d,`MCT&#N+(MSH[$@(L)91
+$%T(mB,MGe(00,qe"M"RH)-5fhXaJi8`M4bYkD)mV$P["dD)$&UJIZ9@NbL$N[&r
+)aS`UND3lUk#ZbNkeTZXC`2Cb+U$YT"61+S`bJE#Xe'`JI,I0F-cfam,'8aIZXMf
+Y@%T$GQ)RKb5K3J)X+EAqqd9NZe&!E%,p4jCDq[e,cC1N+L3HM1MKhak"#C5EQ$)
+@NT)U`ZLVHLID$,@5J2CKD6QG-GV[p'9cM#ScjiB-0i0BRZihZle,1jM22PL$C1V
+LeR0TaLieX,E'raJj+&NDd[V'"(bf6*b"!h+Q&c-laZ*BRkS@3ZMI+[PHG!Fl4aA
+A@``6FMAVSckjL$Xf#&ApBfAQe!UVhepGID6dJEAQ#(bk`5eS$%XqV"eLT+)-HGA
+b3PfMU9Q-L`Na-*1Z1DiZBa3m*V"ITS0XNRDFZ$#G3)Uk,'%AA$f)"KdYCNjj4YJ
+4hK8pKP(+40GZ$fM1)hm!K'2hm3MFZA&Nl0H4K1M2!i$2`p51r2e#jqITfYqQ[RD
+j)`X5(E0QE2!mBm!(XMmTUX0jKSF@-aA-V3@S%dGBSKMYERA`#6I[F'e$Y8'k*S*
+M2c8E)D)KhDPbS1'k4,pQfpT@Sp-RA5mVIc&l5+!('[!CK$6@VM3YKI2!ReJaiPN
+C**m(JT3faCl'DZVDH+#5QC4*6Ej2pkbpYjF'HL,CGfq(G*Iip&C&8&I-5AR1j,M
+,1iYT5-dN"V&Fmp@UK(lB40k!MT9lrM'D-!8PFIeLd-QGFKe*6kFAQj!!4i3eV'@
+[*DFk654HZXY$32&B,)FhljXBchmKkX3YP5G@Um(r'br"'a3VDLFYPaNK*A(@H(I
++4N*$M''A!RPbM%4-GE2@c46F)FA0PQNT+9BpT(aJ-2k(hfYR*Ee8!GUK0h5GrJ1
+Y##'6dQ*GdQG*h[[G1cJ@Ea'HX!+be1$T0HUhXlUU682Da5%r@*)1D-#%4`%CbTq
+HE'EGEY,4c-DD*mF#hCUZjk(Y'9QqIiRMTTBaC!V'$E8NbNR&Nh0C[UhNIGr%N4+
+SF1CVG[PZb6IVjJdbD9a`*dK0B@YjXq1Q34hU2rEhRqALT4X[QQ`Mk$QKlfd25*,
+-h``PYimfq6fYC8D[-)JeZCB5@(4%e'HS"NUH4HYeMLEYX0MmHf6a&9A1#I-BNd&
+404'VpEl2%(T,hY##pN@S($5SVPH!6DY%-X1DYc3h*ekmaRV6'Gf6(D'""C2'a-p
+B(LDE&jFVZqjXkb1AXX$f4QDQGP6X3h#,018[r+!je4P1Jqq'h,-HL'J%aC95aVA
+AIQM6b'UfH(`mcaCY!04eFh)fDDHTe#Kqk+L+kiI"3-$iS2jYFP'1T[[9Uiib*$'
++TZ0Hie(@aQ6kU2[B5IepQlrdC28b(`&Sm&8qf6eB@NUEN!#'fpkSG,T0c,m6Q3a
+rZ,G)r`TB@)PVl#J2a&h&3BeK[fIYbda-U*J2HZTlR,E%dBVITD3B13jC9fR%'r$
+$aHjf"ihX%N5T$FZ%"+a#KaL`$h'bm(!423Qpp&XB1AYHA,!430arYDBjP[RSS63
+UQkX$IHp3RI`5cABQ@+B6['jkYUm9epfArX)410a@)GXBlUK#6dpJBH1SrJPe6YK
+iD,cfA-j[YlSSLZl0",iZcGdVQi+EiD0LpT*PJ+a92Yq%*!TP9G$ed'*L5P6RH!T
+A!dXKUj)#pK!X!P3T@*2rHJ&2JSGfKd0GqAl1qI(FUDRN(hI%V63rRk9dd@))N!!
+S8N[,@aaaY$+c'dH,M&k#-F[YDX%,33ILkRBTq))2AQ20!1bId3mfcjXCI"4DXq$
+,T8ReZC@R,#XG@%#3!"-GN!$@*LPq9$1d$#BjSlBb50VNd-"#)-LrD5XrGk5QT+,
+FjqRjA#(M(A+)Q,FlfCTJfai[$)lU(+B1a2F)K+V#6Y,DCBaGHcU)mjEF1d`c%K[
+I"1eb'S@E'PZDkkN9Xm*C,BkH&j-+k'm+Eph&CQUfdl*eLfB4R5bBQIT@6C3DEmc
+4ebXCMa4Y3S[kY$VlZ9`A*SLX)SMcFl@3!&ZfDbNMr`k15#M`6VE"@Q1Yk+KF%IH
+p*rMJIl%3m,P0r`IA0*BUX%T9lI4D0#j&Z3Pf5X+4pJS2K5fhj`m$$ATD'DKZlL'
+5j'EDdHC)j(j5QdAP)BBkqVZm'P$'433UXMLfRD[qlU$LABJZ$29NlDK4lDd+L$+
+`*-k-aa5bD`d1a6lm4[bP((ib22Yc"56&-D%-(r,QFD6PZ9b-M'4GRUXN!+iUSK0
+&0kU(ABGN,a%SiM3'FY"BTQmpXJ$**qqKjZ-L+)IF2NEf@rdAp*UAPr`T$$A`cFR
+EIl'F6c06jMMFb&pS6VRT`AHG9DfRijCQYek$0T350mh!H29PZ&qN2Y&Y,bYeQ`Z
+IR'Rdphc5j8q!rEK+cr,)0+2Y39!qbZd!JFSG3)DR9L*NGe%4-9q#S4Y8R2mb,0S
+RJ8(cmq'Q%[9XSmZ8bLKS'0"TdpQF2#(N0*j$acZHk!98AG#BdFjr#ahj*(jG$RU
+@%5HB%8l"p#d,VV([jb6D8X'p@IRaD+*XL(IFkFYJ9K[dAFRKqEfAGhmKd4CPQ%,
+p(Tdeb$0!Emr"hY3LRiljLb`b*&6&kdI#rQ+Ak,m+1Y$LS5YmDS'FS@R&ed(&#(3
+i5lmdN!"T83)a,Q-m'G53!(qK%(P(aej1lcdXl&ZSkp!YPmRi@YD50$N4T53(Qcq
+2-IA`*2'lfIMShIp0H"C(,a0mi#GqG[*KHY!S,mbkJ83Vb-KbK`UI$VB*KYRk*m`
+TVC0bcI0hBUi&3$`,+*43R&*B%Cml`1+Fe95,Dhb6j6mA8(iZp6A'Y#AE`!9Q#%4
+VG)H5J+!m1P3U$XJBh"-&$'h1@LJBBhRc0jp""[cq3))I1aF6[JNVp3J%&qmFI1Z
+aN!!+4LR*Ep+e95YY%q[Y81hdUbKf8-jV*m"bQ,+4MMUESkpJEp6CQEE,*0M%G"Y
+@0HB6D%RRe[&1$l3pc6pTE"#qIfUXcV#B$8TKR-`K0cN2Hr-E&UE01Ib'SU)C81L
+MHU#Y`dM"DLNJb&"*AkZk0JcYcL8#MI-bGjFmLEB%U$&Em0L9Z9ja!lZp8!I-%S4
+)(#2dD@-lcjY*4`HaFc)GrS4"Y)d-S5UD#0k)Q!h)N4#iL"FdQ&i6)1PA9Qi(iJB
+"'lIZ'V[d3i[@2lXb*dfVTbTXE,a*V`La$id)Viad)FSAjTP*j)V%aaa#HTM@5cr
+36"4+6+a3lJCHK&rfeb`iVj+A-1F2@9NZd45ZPF0Lf%TMU42Yc1FfdBH%eMSl#4"
+T[5+pfU"kEYFq3Fe1ABP,kQ%#@Y2&HNNiIh'A3Qr`lRS#5SSahCU%+DYU$1()1b#
+RZ+TF)hLmTBJ!PfD1lp+Mc)S84[8,FCDYY)fZ23fhiXZU-Z*2qq%PQJlRkhQ$j1p
+aA1hrCZNFBRH0RP8-T%Rp+HpcX@fr&%ChSlaKY3[Y1!kG#PR*S23Z'0#bf#qe3`f
+rMA[eRU5%Db9H`rmZ$YhTX+,'(5b(H96!A#!*)E2'Zrk)aaZb-4rSb(RpQ&ja@d$
+q%'-F98ImL,qKRDTPU"CN0cUA%m,'1l'Z5l8C9kaH0B''P3DE)dd+RR#Z-f8Pic&
+9*jqpT+jMFYQ6efC@)(j*&65Br2M@lC!!F[iZ5E0[m(dkXd[I8&NVh"jj)%0a4hQ
+h,SE$,64`*,2k[([Qb`*J$,R!YiV1V"djprHqDA4b2%F"ARm,M34K)(B+"A9)lEB
+ZmX&QieCk[-RTGZ"+(PZrVh%3&M&"*bdN$,m3mrFjAS*)T+VBdJ1d&A9&VREbV+3
+!+Bd@@6QMZ@MLP'22VJ%-4C3)ZB0V$25jLC%&Eb2bJ&'[&Qr(Qk@d#$eahVa9mK@
+[hj1DfU)G#bk@XK#"[3H&49HH"eEVN!!e4fA0[1cL+!Vd(G"YemX0BA6G)(j29CQ
+qQm@'2E+NXV51`i4U8[`ii1&k$T2XMNJLiVHN,6rEPYXceL@EI(614*iU3h39Cp6
+S"$6ZB"!PJ%$B,c2ci[bb1ePamhr*e6l40@[2EBd)QeQYdqGV3)MKZTQ`G4iBeHC
+Tq(LbGLPd)8hq,#K3#!V&f0DQhpd$S45l!h6PNkZDre"#5h!5ApM9Z(6S`9qTM-f
+i1S#2RViJL[bY@"ai*r3*@HTA24Al(FG'+lFHNT3P0HF(IF$*"4k6&TSr9QE5&IQ
+V$hq-e"Zd"'L!Ub!a4PLLbeY*r5(NEDklCE2"lcf[H@c$#66#d&JM$)qPF1f9JG@
+182%dp,eQm*C5k`-$5Jc)#pmmA(X6RRlpK$Pm[XkUHpQcHF6KS1BFb"DMaKf60B2
+9RZY)MmjSQK*`DZ&&[NcA[lpEcmi0b%P3JYr213*%Xr3cBIM)k+KDERmiE"6DN!#
+1TMlZ,bYGdZ1eqSm,(XrJQ&$4C5TAE&2ld$SQc`fV8"cUVNDrDeL+QPG[d*DmDPE
+S6bYCiSi0iVNfTET0bq@&@$hC,%b8!T[Zc2ARcfbqPAKG#Lic4Im2k(L5,6E'h4Z
+4l8$i`L)qdhXC0"#9jX&dBkkU30flfG5`["ZHP)c5GK-MTm9)"B6R*T)P,4PlImZ
+3!)b+B8d+Q-b+`eB$1%e`ceD8%iSKGehMGSY!!3MGLVPj@r@I#dLJ,2mbf5-Rm*1
+QHMmq9Z9ZjmbXe+(KeN4HZ0N5CYf161K8aRCfcXZ@$PQ'-+U*jSD@@)A"aJXjr*'
+3!1'R[DM@JMC+kc'3!-XeJf3[FYLN504mEaVHmE10`KiI`peh'P0,hbEGPNf[BEf
+[CiKDDX1E)TfcJHPREBa5B@L-+[lYXB4F!@U1jMS,F`FHU)IA`U!S`D`b80r@8lT
+*-,fdDVYVc"$,I4jj#)X%+HSpZG6R'R-'-8DBEq#&I9PYGl@"b*hbcE+4",bBHII
+-5'F9L0bZ`h,ir2&6N!!5kDHLH)%)F1GR3QaL8"PHiaA2cBXMKhZ"HqGS2)SZDmJ
+"1afQc%6'`)Y#(-e$K6,qLVhmf0)SC,#&p-X34pB01UT&dYh9jBMZ4%&@`$k2qEc
+DPEempdbF(l$%@`5Ym$,Jm1h')K$cIq%LJI)V*`(Tf)%XfLXR3U1@&G($BEYPZ$G
+VQ)61'*QXjU$*dKm`P5T[V%2)dm*!e8KRDCqkFUK'CMFBc$@26[VQ3j1TfJ3iKjJ
+,LU652*!!IALXCVJYUX$f["!eX'Rar'c#J@)C2SdembJfRV3%hMbGK-XcQhime9$
+Y%mljq&IF4MFX3D8K-+Mkl4klDfS55iZG"5kMdGp35*-b48GL#mL&U0RCRQc#D`h
+&0rGjQj8d@2cQ1B5$`pYmY$Zb0B)KID,h0''El1EpFeTi6T9j%aK!R1IU0'Kc#df
+c0)JQre!25MZ64GJ!XFN!(T2br9*0-$iV6hI1[S*V52UX&'"fDZ9M++["mNT1X#"
+1S*91eUVI-P+44Z0ma@bD0)"PI4GICZ0KS63GAMA%DZQ4eGq*9d9Xl6P8D66eZpQ
+a[NJL5dhKPE4kad""bmKGJQKI3FJ"`leM+HT(DUE,-MhD&bLI3"i(J0Y"i,F9$4r
+C5'%U@q0VKPSCT,r1P5LL"qal4+5FM)H#A4(5i`-)NC*fXlHG8aPRUkEPQpiN0BA
+pccV$q1U@Z4RAY'51[9V9J*Q+hC%fe$2bU'%#Jq%AlTL%!@B%XrZU[cSiF+BjApG
+dMPj5JJbU5"MpqD1JHhVrAS-1CMM%j"0**HlhAL$'BfIFR3fr3IPrjr$VfrKd'I`
+ke2iGRf[`l!lm1K$qI@Mr(fUjIKeRhiEqhiG52mq`d1d0f9qXrZJ(9akFZP'V5fC
+@@66Y'fr9IqAjJH%+Te!LIXdGdJY%"8DQC2mSCi"P9rp,SZilkANfVfK9P+PM#2N
+#*[md-R1%rHVkA9)#cKEC&EhR)Y@5V@AK@XA9l9'(,UN02P`"QMKS[C*eA"Z6FHf
+M81,-5r#!NMQhUd*,85hAiF'cBqESe4N9Pfjm)Jf"9pZ8fhcfA9PcXbmRi[dkKhD
+c%qB,cPmj)dK8LVIq4U1*cMf1XlMDeHDphA,-5b-EZZBe4%TiMT-NH9&r1rE-I,3
+"bp5XQeG)l%ZD#LAprU3k(6DH!-lf3bfN0r9"(V#89M"-3K@ci+kVT)GchZ+i`AI
+$l"hR&(k`h'I4bUpi4NSMXaQP#m,mIHai59q2Lj+`m+GcCbZMlq%A)9i"#S9m##j
+j'bRdfYi%d6qE,`a%CI1A**aS1-P%qkFQMJ*dD8cX@$pYVGQIN!$YN!"2,0#bX-M
+%-`l)ZYY,'N'd-+0I"NE'J(TC!3h+MMf+!-PY8!K6rEkc5Ri%QLXRVjTLZ"Bld`C
+@Trk9YB9B8b44)MF#bYDdk(C&X1V@eT!!i(P44QeRX+,fEb"3H4M&4rm[DZ2lmQG
+K6ZAFFMPhlaQ0d)%dCak'lRXY)[5XU&X*G914F6Zjr`YmAj&ji3FFRm0G@3CSL,G
+!R"+r5HD++[MNR55cBhFLENmL&T-mIQ&VTHfQ$#*km48"[3KB`D[HEB1DEpaC-C9
+B$F)P$2-9kQa)cm"qP[(0d+f+XlF-YcDbJ6E5Ec@T+l3305FJ9aaIDKiD*0`UF!m
+)c[-r$fdEkpmrZD2B[GI@'Xf!kr&Ah2cQ['%##LC+38hli0aS*L)d1Ge$C#G8*F@
+VfllkTX1l8SP1kMCjD8)-H22@NbRK-PLJX`&!M"!@j[j#fqR!i@%MhfLf)+RqN!"
+1SfqqPi`F(b69V1pP[0h+"r)DZ(m"(*C$S"*dDND[JPqYaZ$&E"dcBNGm06G0fcB
+dJC0FJ&1J*d9q9"FVHHa4J6cDZC!!k(k@hFAQPPB1GLMjF!MmV,L2&@NhNEerlL!
+Cpm@A('J&)ZQb+"8#r%$lc0Lc-Y0iJp6Yq3,XF!(q#2D!liA4J,1Hc#l,+Qd5CPX
+P*PHP2#"&Ne-e8jVlYSQ%!!H'r&*aVI%J@hm3iimUiKAeh!kMd'd%pp4qlDY-+%F
+lEm*T&3#6ec-'[pZ#r!*kmra8#C&S2fcqT8!9+%3Kc,`X&PDTRjR&aVGdpa9Cmd$
+DIk[(LiZL@akrUdS4Tl(QSj!!c`A*1aVAYTcl3A,!TAVG25irf9#k%E!KL5%ieBL
+RV05dY@K*jdRj62XNd"E3baZ9imL2f#9)-2R%XI@+"P!Dp[m(JMDb`X,SlV@BP)Q
+#5EH)I)2!($,h$dchU*HR'(M)6U3L$"'08j-f53GpH"dPlHLLSN`YSAXC5aI-0Sr
+25Y[NcG#!p@D4'-GD%#J@H!C3J5dS`EVE-hp-YUI9%rC$R6D#a%KRHajAXmML*fq
+V!"9"RaJScL`jc3IE"C!!MKL+k9ckJ@HiYUq+Z90Jk8GfTDid-Rc(hh%k8L'!8-l
+"BX89TVK)Ba-ckki,5j!!EJEH,$pVkLe+P6N$dmj%BKHC&[$6Z#hk@kcRRaL(X*C
+K'&edEbaEq@(N11)146C#$*G9PVh5`0KF@,8,S[*rTh0ZV&4#2k9U2'NkkG'Y0U)
+F*ANqA5'aeZU1m&MqYEB)5&G&T2*'m4"!ViFeN!#a!BB,$cc`Y2#5NP8SFkbjaFa
+`@bCYHX#Shdh`2iB#Y@cedVF1N!$[4P%HrNY&pK*YD!#mL$)LIJGTe[dNZ'UH`PB
+8r,mN,L+5ZBEZk`C!Vp0F8J9p+0)(CZc6rL@fa8G8Rb8EU,j,IPB99HV1%3T"jT&
+)0"`Yqjrr1iUa[NU`128i9[1YeT(PeB,JHLI)pUV!!,(Q,aD+II3MQmFLk%PJ9mQ
+4XCU'Zc(a-l0,a0C6FJkJC&f$!)$4r[k5Xa5-V,-99(ipe6PB%mfb2"L`cl0)MEP
+j2k`2fEKlj1b)F'qK`***e083kf(J4CIfVh+%2@Xc&)MP1Za@THd@)a3rq6Jl#Tf
+E-!Y6rE((0CEjd+X%5aUIV`-'YF8+$Ri,EhrJ9-pP`Fkk21jQBY`4H3!fq+Z#2rY
+%K@dT3,JfeJ!R&3!L,5i`06FlUT1R`BB4"TIQ,TGdRab[FRfqVN,AQPaSHCIXljm
+,J,*hqRUkq#%"HDj!p*R4aE![MZcBqb)U"!6iC94+$(61Mr+"&-1-``"5+K&Vl-r
+2l93Cm$PbNN(%ZJ@TESMBJK3Bk#TZKlU9Y6pidM(6K*p)!AF2@#D!P(V8"H%$EAr
+lHPArD5k)qKIRk8'8#,VS2`Fi9T!!E6)d9"kBhpJfGfa1lQBVbNr(BChVhP&cU*N
+rNMNECbQEFAJpQU,0K*`Dd*B4kZlYCH3CK1$@Em,C'Qfi@&pp`eAXKp(%FG)U+H!
+4$E%,FSeBP`[GT1V"%jT-aD[CN!!EA'6pV+XSH&N1$+&,cGL[D6+qS[IGM8dP86b
+Z&ITlDX[!%,TALJ9B-UA$RkDiV&S3%Ec1F42`aaa8dCr#-@Q2)VCjJ(2'ci)XE-E
+XYCB3#P(9U6)P'q'akXVIF*bk5!)B4[1b5V6lMVYG@92&1`[UF-I1VF#pU@&P5)M
+ai#Bf[j*U9Shkai!`P)I*!BlCJ!9IE6D0)ZqLK#+q%d(24lPkBpi3RKJ$qMV#HD8
+E6hYqV49maLMSN`f3!-lq`4H,0fHB+rQEdlfG&%A1!)MN*%Pk'X"Rdb#d$!raUm@
+-'5kcQ9ANmpQXjS%Dh1k,$BYY,01Cl40DL%`f#6`3X!m83kM4[GKYhJ,@6MRUJab
+Hj@F9R5)DJ00LDc224q0S,48%pXPm`HT0NmDrH&+DIY8`k4)#J!!&SA$j@%ah24k
+*`SBp,jP'JfM+DQ@ff+mJp[[d0PV#bj(N[Qq3!,1-JGda+-#d6@m3mb'H,)r#cC!
+!NZ'A+MAKmJ''9U#baM6K)JPcZ6%1%`"ChL*PN!$F$GUT!e34@''BTN`RPp98FG!
+1ES-k@QVVM9,PMjJ28iBZVh+`Tr5M-`&G38bm15#6+i%(BE!,bkI(j*6SM5c+JkJ
+GpSk28FkR)f)M[5*C,NKZB(CILpU3!!2eI16F$&AHFTNP&P0elAD%&q*Gl6pHjN'
+h2hGdeFj2hiYJQL1SfZ5M[EPr3+Sq01YrQ&iT3VJLa1ecK9l8%'P84EGGH3KmJ14
+ieeBk#XL`6mP'9&AL+TXmZlMZBeI``hRM[B$%k%GFV1`@5HHa+li5J*S)M3eh-Dm
+$)VK`*#hY3Um$'LNP-#B4(bi"BejPh,X,D&%l[21Fp*YVGmb'Rp#Y@`#H,UK)m)G
+I@leTNkV!1pdj@-9kZ&"jVU0)[e('lU6cFE998P&)"2*caIE(hkA%5dDqK96%GNG
+@FDF8PYPqhARNK%-3Z(PPcp`MFl5ZCXTBmap#"bpI,T)jbJhRfQ'Y$kXXc,NjkJ4
+3hRPM$!8PB#Eb"`relTZhLLUST,"5`6D$#j!!H-MQI@1KVe,%j*ECLND"JUa2QBV
+8MRP@i,Y"AF$AN!"DT(2iDQcIl1h(#K'FNMA2[AJHC*k0S5!ZN[p%iElc6f#DDFI
+5`!APUpU0MVM["&lH'!'0lI'X-BMBAIbq)AS($B'%@@S(iT+--%@9,5FcPVdmT-$
+dVLp2"qVddrjTL5q$YSS1Ur2GYlaASA)pheKSi%!JY",KcB%5XpVckQ(%kRiYM44
+YR!mN6e$8q3HF+)GV$J%0ZC9(9Bc5Z)Yqm'*BGL-RSH%4X"PlFApR3AS'c6%c@B(
+Zi!Kb(X@3!*l$Q*LjTHbAeDI1+&cRkC4[p6NMlqp,Ua5&HQ1%$0Z4cQrlV6S4"5R
+HGbQa"%+$,b@(RUSQM[4KT0AUI!(#6JAibElp6"THK`9-kST#0A*dRDl2ZfqYU6i
+Q+fE+@4#K3!'V601e[Y`dZNcc04q2-V)(SY*#d-0Q[@#ibU%%(lpAKTkU)"m#16F
+*BPZGpq"2f`k4-L8!-jUqj'"h"ap!RSk2ZKKaiDH1+&k`NFbCTmr'icq&h,`ApRi
+@Q$ZiqccE5,!bR!Z[a"#$%UI*fY&D6D2cpXa&Bp[-TciUD[KGGYAXmd#V%4PdaCH
+-&e*55p6cM!&i'2QYMIQ*F$hY,1a'*qIXE*,m%),CJDbj)fj65DircQX-%$*K[CM
+rHURCbQ45BLA&aAX0d+!DR*3mBcTpcREI1)aHN!#2i,E!96Ml!`*HTT+`m-,,IR1
+!P+QrP6JeMJ*@bE!LNijc1MU5heSXVSj80F%Y[Q'+2RUr+DAe'FT!HRT4a38Trh'
+N+1VaY+98Vr4[)hVHT[)@`A"M+`ShX#9CfZfDT[NGJXSf"FVN(JA)`#GhBqaHbV2
+*hiZ-XpTdI#hN!ehE&5E5JHV3,-@V4[6Zj@db3*3A-e`kid$FC64#INrFh5#D@@Q
+Gh!h5Pe5'(Q1TJ@RC&`@rQ0Yh#A2aa4!h*dJ'r@k2MQA0`dDhE6Bi$MVEXPbiCF-
+c0UIF6!0D2[HEYqi+crb)QBh4kQrKlk6J-TK,cpD&cJ1iSZECaPQ23L*PbpH6"Xd
+4lZHMdm)RVHL-%d2#GDMA$FAb404Y9kVP*0leYjA9$pA[H9BJ5cED[SML[h5N103
++f!PJ#jQcN!"Al2)MI53Uf"b`%e(ci(iNmlMr0NNE3%2AC#URbDpRLEP$Y(%U,2Y
+46fmXCF![Zme1GlHeE%'IT2i16j[Ll[phf,TQlh1q+#)Ni$p9(FMRH#PmR+Ua!CT
+INYdkV)$)1BM2&+bSjRiXP3HjUCC9JV61Y+9QCXmU5JifrLUe0DR!UPS4&)[*jUd
+C93ck'!`VC[iibhi,8(r'LDS-X"j8YG0R9mp8EM(fU*dh-Y%J1C!!646Il@NfXMi
+rN!#M,YeqKmmhLkaEZNkX&YALBapfL`2YmDMFBjQqV`eJY2*-eB'B[G6Rqhl[k[#
+GaXe$+TYfp$EFXKcl0`LNU8@qICd2[E9XlNH1)SHH6CpBlia+@QJp@hHfc!`4'I+
+qT3'3!0U*$R1Q!Uf--M9$)cLe-+e3q[`DhTI!LM`KeZC%YZ@hc2HG`'ik9EHXcVP
+i)9G#HR63GEhE@0JQlRqdQhIr,MXX!YbkUIpF*9H0hir-)UpaRcBec1%GlYQaLEd
+DdU4*FbR(Q4jCQ#*Xj3`3!p0lA6N#`+Y6ES*kr4EVNDAc'GjTr`[22VIYM)+Rrc#
+MH[-%6)f#,(i"@(1h1N!%HRG$H$ZpapbS`e1q&bY2F1BGG%0`!F5di4+(*Jb3!#(
+MI,k@MXi6%a+!CP0aB-rKV)6f0YIif94*l0b(U2[BFT8il8S%(CmT56!+,aZh-Al
+3*c1*S(qh3h2NaV9H(AlXB-*FVX!18-'QB(V6,l0H26U)JQ,m6MaG5P@D6S#a55(
+5R(XRmmDb0GL8`*QLbHLP+!1'0S#+5kPa-6E(5hjhh6e2P1ZZ(GDAC8k@@A94DTT
+j-`Ti[LDiV8LB8jqbCKqb+3P(p)L"dU*M`9-@N5"%*G0`dAVMf-j#[kjBY&8b+%h
+3*VGJXVDmrVck9VU[c8AK$rL625TB,LBA+%DU0XcM[EG*GIB9GjIRP$ZQ5JPLbUD
+Yf,MN8YK4XfmYQPaA%L-cj4U[KJjdp"Z-8YSCLQ)J#DXEGrcR&!&!GXI6U*kF&Sa
+ZDVR`QJ!DlNX!6Cl"E'0dKLkJKkrIeElc+m)P!$Yl+`0&Lh2rG2KV(c0I*JITM-B
+&+18F4I1E[pk5`e!P-S*bcAe&eK(lS0R!2Kd)*U(1cCdM'1q&5#Lr6(4&%,*JJj5
+HYR$,14U#!qSJpFPla!AZPaQ41E3drC9YHMC&1Qir6MP&4NCJ8q,K+A8)Q!!qR$,
+NYY8df!0A!A"D3F`M5eII4PEr"6AQe4l2N8$[aTq&+cc*rP`ba#hXUC2q[cAe4fK
+f)Vd89F5Fq*Pbf,K#c)lJ19Z`f,jC+,f68aeUqZ0@+C9C0"rqYXrN(cC(9Y!2cip
+eA3*fLEpA8DKRUT!!Q--(Cf[`lHPC40`FQjBjSbP$ZT9MBKe@Bq--j2m-qphF`lP
+pa2FDRd8BQe3jIr`IkaI@d4lpl-'8H`'eci$-LQV62GA9jf+G)*&S439XP#[S!6N
+)%*!!Xmj[9$XP6%!5V3jQ9`3jDLm$A1MM16A)2)i$(SA[PH#hD51E'Y0rCBl@Vb8
+Y@3+"YS%dpGSF`ih'eJj!1Vef,EKa11DGIcifeQeQY16'rDZ*+f#[XkLT,BJBmC3
+5")RPIaHK&mS3'pT#G#2DacN)*VL2E&X@[XrdeAVDma0@"#-1iahbqi@G-cNmeEa
+irXTiVMAK`IJc9elF58e`1G0ZLdGm!6i!i9GliNpk-5d50XVe%AKT+,6j&[KH0mb
+eD2HLXFIRrX2F%LG9T#2mT,J(JRD#KE21d[$D0jf"VFHZY8*,Sk5#@ETB@IkE0U9
+#mNe(!NUKD4R!8Ddh6k"+"ELF%RdA!EPQ)NTTF'@D3!KE'[KTINd5aAXecUM#l*P
+G)H!iBC+@SmChUqr(1Z-[hq"KCIKDNV(*VJPl65!YEf8&qGpJ!RGI'4Kc'(2G%f+
+N*[VK,CFhTNdVQ-d6,qMa0[#qj`e%"-a6%aE!S*d"lP66)p%D+QFcSjZ3!2pq9V4
+S-'X$*[CL[TE3DeFDqTSXBV!Z!j!!,$EMfPPkkhk6HahTX2PK+"E1[T*kfR1'2S'
+`ei[5"AEqqNpjU,#f'1JqMh2h@&T!L$Ak2KdGmJk2f!%`KINRa-0!@ck!Q!"qM#&
+i*raiHcA$TUmM06FCYaT[@Y"X*T0Fk53GBJHN2e6L8c-LDUUr)rT"k5XX8&PQ-b#
+4(Rf2kjQ-#M$pCCKbIV%k92F28)(YKaX,E,SKAGqPh`Lh%qdDX8q(8&HYdk!LXl8
+FrC6FFZUBlEbKkC+m(GI2h5@dHYdAb@mhD)j#L1NT8i&c$8VY,lC3UD!0pPDlK5c
+l$jqU[XcTmGM!KINJB@KLbmffMcJQFhBU3%kYQbHQRZ+e%6*-V"kj8l#RFm&!'VI
+ePqcb5J,Ce9EkKiR[1bX4Z@0+&b3*CkC"QY@K[3NXEmGUM,'F58jb--`9Z@0VeZh
+l`4qS!H#TIbQEFVV1Y&CiXMV1mRh#kPH!@cB,l4mKZ#A-BQZkdKQKMM@0AZmXraC
+ipEl5lfI$-ULcam`)`ACaq6biAXdM+qBl`HY4EH(Ka0L6*`Upb!D-QaPjJ[eN+(K
+iTmM*jl%HMIDUip!ZkFXf(p3-kE'k6bafrMlKKT!!%jRA'd!k2N0rUUE``lH5h2,
+&*Y%q!c12JqQ)9l0$SRj1F)%#8!6DA!GEJ[-S5+MZ6(,NhG42dDabGbSa9U)%5Bk
+HPjXPl@rFACa'irP1Y0hh1AmF-KflXIGC@$!`1fja*8[MCf%bc-a*fJEfA3BY9hl
+r1#@r*eKk"PkRk96e)M)cf2VUN!#QGB&A3(,QT85Ad6UiKb`b)m8Fh1dVd4NX"&K
+-RAb`j+6%Vdc6QZ&UMpTlY)I0piGCS6GUPaUkSlJL,C`a4CEfkj@&[hkKJ"$6U5D
+GdQRJeEA9jSTc9)Gc+)"#iI8SidELGDJerA@eMVP+9IMpXJpNfL+De#E9E[+'J*-
+`e6+X"VNhk6`3!lYCX!Se*XYH*KBrQQj6N!!*mBEKILjf5UI1!%XSAEe(Lj6[AHH
+r[EhdDF"NPEjK@PNL8GA9jNHbXl+'JB9l1!9'Bj1rEr1"PARkC5Zp#TV[SUBbGK9
+d85dh&VBY(ZI(Q#-,![B'@I(A(I4Li'Ql*FH&ai@3!"p5-fZ(%24K6$TXpq$1M+S
+CdA$dCb@[8[KXd`q*+)'(mrlSF$iM#U2JJcb*5Ki&!Y`irMf5(19C6X,HFUXeZP+
+miJc%+"XBlKc-DEGLp4VA35&6PQ+UGY[[JDfm(*q0-%XD4B5Nh2-h4iVmNp"Fb#S
+%AfGLi&pHq3aqc*L5@C,r+8m)KX2X5$dP@AYrPk$@kM02LSHC$8qR,DFV3T384T6
+6)jZ%Er*8'(fl$G$[TmkPqL6YQqY!aTk-54$hFPGq1Xd$`X!FCbDH8FS@m"p(DiX
+&mlU82A$%N!#CGjBJGXjC,U#U[i&LkSLR`DUkdXmJ1RMq!%!1-U48%ZYB[[,5KDm
++q1dY%VaGp8")Z*`3-pXN`cJDASb&3ANB6I*iNFDJ'Y)c2RmFTdE6Id2*#TBY*K2
+0kY,E51MSj`$r$-E2`f551PZ3!&43dLle)m[G1lAEN!!P4EILaV[-B0@a,0HSp#E
++"%+YIlQ+FTdL&qH#&GUQE%Xe(r,X,I#[FHHK0%#DD$%Tif[6,!Y$8'3kh0bG#%5
+B)`MJ@12R2,,Sp,*3X%0'E6Pr8#(lekNN+U[GCb3R8&BJ8hhMNJbZ5r##emq&Se)
+0a[QIZZa"qJBZLcR(c5JVjS`Ej[2iR*M#@Z$MBCJ9,,J(V1!iIC8a4XXGRJe4c9j
+85bK@U1fkUQ+Ycdb5I)',e,4J6@D`X+fXl0bUA+lHbVpLE42T@qS%89I'AYdR+mH
+jh6SrC`jKJi83NB3E6bDfLL96rGBH9*E2+Nk0pm-9LZYh04e[HbL'keM#Z2DNN!$
+b-R8i%p6rGU66e&"TjA*Di'K1I00JUT@DjLBX6&I05-1#E(8[U&30a1KlCa)eFCI
+GfB6Jd8i3R"eli`S-Fl2L8(pD-Jjr2D!BRYk+9kK@[VfA'bE!c)ieG+JB*'h3!pA
+#kSE&"P1HQCVUpNQBbNmRl8KSpD('9Jf5bUJlV@d'H2p4l@*iRANJG-)a2B%R'-1
+,dP5Vm%alE44hiDIR88!V,$picVZ6!jAlUrGi'qjrG5!3R`1qp-qj9Ca5&M3j[AH
+Ifbi%rhd+raQm#![DE"IF,RL&1F8!#m%CJk&IMm`lq#Hi+FVpY!&Ml5$iZY85cpC
+$I2iFVBVB8&()R+PSGTcUGGr6!(NBrDUeFESFdD*&`I$&V'SCTN-Z%`D86""i$S3
+P01V)iHfLDYPa#G01fGpEPa@R"Rb4RXfCH4UJLXX&jHDS&Ul0Z*Ye"eJ-ESDG98T
+F9V-Y!9)5Y-)&9A(m+BS8YKeLZZAI1MRCC(&4JC2%)jaY12D8i'aXe'lK+f"-T5p
+m0[MJ"[Cp"'XXjX#V@KT-MKGLqA"NQiBSKJ1,kEGLZELCG"&hh$!be2#$9DmdA)(
+DlcBXF%%K"81[(f%0G1"*Y@JRYGah35G4R1,DS!fe9RjA&@rRRfj5B8"#JaIY3rp
+S8-arG(BG[11@6@p+jIS4l%M2Mc#$5mUEC(aad0kbHf#kCVmUG,mp)+1UHFSer%f
+kT$#q[ECAATmBpqdSI,LFmZZTRbG5c-2@m-,$HQ8F2Qe1Lr$V+j'ebR*"R22Hlqj
+hQM4L[MNH`U"Y0%J[D)9TdQ,XiPp3fjDE[[m*MNj(P&$p$X!VkafS9T+Fr$V'$L#
+MPKGYP8Rf*E[JEI%@CD@'RJ+@X,[hDU!JCPB[+Ej!A4G-XUX3(p#&C))MR2Va'#'
+"Eq+KAf40!"iRI,eQcEN@jM0N+'UB0M-(pRqDbBl"f6M!094!h[LSF++&`iibYX(
+R8h,'I+2hl3JE#HYR[G9%2@65PYCcPJ-1F3EC@[l99jL3!%1d&pU%kBEAhlB[S)b
+id2UDc)aV(,!PfP4iqac9R!`Eh0ha2(0pVR*3`AY3Ir[Uq`@14`r2+M!Zf'p+Y3m
+k0Pf6Zk@e'5M(Aa[&#UMcHe!SaR@2%i0qZVSGV$[FFh"Uc+D",K5YRBK)-Tm,i#S
+8ccV9D*'I9[QL#NkXq$T")`Y1[9IZ)M+eDQp[SRm#`!+4B!dkFNI*MKdJD3KFd["
+Hp3V1%%F5RMS3XV"-H[Pi%M@d2,)aR1%L-@rAUZePFG+DU#JJ)bdqL&lH"6bNfF'
+8P3LdFEcGG61I#e%+V!`MS)h-%0FBaNkIJ5#6B!YQ(K,f'bA!NiR"jQ6r+QQfcm(
+E&C-6d[p`Bl[#3rBA2*9Q#+Ki(!%pb$j1VHk3!'!X9##[dSqVcD"6'KiRr'(#6Rr
+IPk+b1"h3'(T)'fa)iAMc&T0&d@r0QhUL(P4Daf-VC*&LUG8r`DiD@J+mRIaV*K9
+SYpSLfR0)6&1LVeTi6$HmV#lP5%3-+UB#S8A$(lA-q#SUk3GKIQE)e2CbGQF0JK0
+&jmAP(+S2c*K2`mZ"Q$$X9-iL&dCT`XULC(aH3'[4@A2b%,pkUY9`i$JI3HbZFpG
+R%&@eFR2V,rEbDj`50h8LH+qB$JV4(%m"H$$eZ[NTdiBIkN-9QLpFLJ([GfR$E2&
+G3F0bQ+h+$2j22FAk0'iJA4hBmdL'PqLQa"%mdE+hEDC6iHjDQE&JhMEk@pfXJQ3
+NA586ac$r"p-*D4Gm@Xm*9RUhbL4[8jdl!eUR2fN8cM"KEf8FAYiXB5F-kD@5446
+`#eN-'%YrD@FP"#-R*AGd09Ghj8p[S8VfEreM'`kC"Pi+q#N#QB*9T#42G&k6&9!
+MImr9p[`!6eAJ9SfMBDV0LHT$i45mh6Z3!%*b%088qY)q@A,DM2PY)D4&$KK@F)i
+P-*%ZSp81+qJTEPPa9f12$XlPVq1q%EY-Qh-m0Q0UkGIb`ENJL3+f3fKCT40fp''
+,!`eY9,0Zl89Qh!Bq8ZqP&HLj[IJUF,a#mQcr&J,,R-i(I+f62eZr%35Q[e[bcA%
+C8E[K-&6,C)jA!5'fe+,`MFMpG4Hj,AVcA)Z*mV4pQI2F!J#UQFJMbY`)L*Pc5$@
+3!-*C94[U4UfH1EUTi"Q(3bjE@1al,9,VRp"6M-6fk!$r-8(30&pI(pR%rhB-k&k
+Qe,EZLZJ6pJ!YJVJH44q[fle2"mdpB3pSCV((Z2mfpEXjklIL4P6d3*,)q'(IdSf
+KUcFQ+r8,1qi8jD5Y"G-%,%GlP$U-G9JSrIS-5"#XACpZRm3%iFAahi,542*&e+A
+`@,CKB2Aj[YA3ZZ8eq,AM`a"4i'Q%""bp9[#$39G3+ImRSRALB$3lU5Ghhcc,ffN
+QV'`$E#Z(T`BIj-eEl&9&%&K&0@fmX%lJrfcVGr(35)9LC2F,9E2#MF13!%6h5k#
+1r6p!Ci+$`hi0+iCMNS9Y2iX*T,*#E++%edYCieR)ip`8LG@BD&iBbq"ZfL#UJ'(
+5Hr$8Z@p+dE")bA'qdB#HMlc&8pH'b#PXlV2-3%3qiqk6RD1Gp1%JV0KVPVlk5mM
+5[0-,rPjD#dP3fadFdrREPR'G)*BlDm+$SYSm2CJpK&)D`TI2@*3jQZI@m4h"SHP
+'`pNXUCMRCG"BKD[[23k!hAX5'*fa&bFk$UNhI+3Y[@5*JV#UhC!!c6jD5d+4-P"
+11R(Mp[6CqhEEp[5YqhUPaqhTerEYVqhT1rEeCiIYkErflDIYk0[fp86b[""l4!"
+2,P@L[DH8S9AbDpTSM5QBErKdRM*b&U!iLDTRcU'Y[6'*P"pcNpl&1q@%qQ%FSl!
+QXJGmQK-)J+d*m!Z25-ZVq1I1%iBEk!@bK((jS#4k8RVkDr`Y-,MCXmN!0*,leZa
+$9c%J2Nk@E%fk"(4JGd0l&BG[bH#AeM884'cKcY8,rd"dRZEG`PF8ZejMeKZZPj0
+YE+U(-9VIS!*N+PVkdP!%"C6KbQca6iK-&&R#jBD3!)AFT-*HImJ(DI(ChQEePZS
+b)q!ZSjqaFAPE'-5K#-'58HEJNZJKV%BS)KEKpl#dVRFT@lE#2G&fbF%Xh`"'2E9
+f58`(1lV+PLrZiZbYa#VMm`)XL1pbElS)cYdcDGI10DF!,*I*A[4**p*EYP6cf*p
+M[55HHH"pr""&lc@Kcj0%HHr8h[lKMF,hX9%E68UI(FH(c)a3BTK[[%kCrAL+AhA
+SGHM)3GX",TF)Np6FrI9hJe%Mdp%T(l`'LE#'UfTc-59F[fYPf`ZV+eZXTj2,S+A
+YL$qk(28V)$F*J(NGQ)m1+V-h8l6qAP2U$2&*KUG`a0pmi*L1I-lB,QAXc$L4GVJ
+BLkjkSiM(%9iZmPB)l%U"SR%k@G*qL(9,29L@Vm)4BKETYCPJf9haIhe#Vj*q4aI
+2"%T@C6'aa-A1m)ClP%Vr'%Bb45UD9mF0UBi3h5Nj[ZpKX*[Bb40BFD"hb[SmU1V
+rEidf##TER*m"deH%`dB!fe%e'KLLACV9G`4aXTe[PJ`9p2A1lUq&0$SLFYU(&ip
+"l0PEf[DP&`Q(qDjKZGRVEU@i@rpZhkeNlA'a2&NK6kcUlUUp$(re9)#NVY+X5SU
+Yk361M0@l6q"'iVC+2Xb"Iqk1UF,`X(R6bVV"M3Sj%TcmCMMH#pelXfCDNB)4NI1
+TSK,4HrPl5klNIS9Aq024hJhf+3G`#Tep18Br05"ISdPpf5,Cj92Xi+!RBC-X,"V
+jjA0ZL'K9CM,8lD1PF"NB9d'lbZ0kU*-D6(4TU6LVUkHKldAkfX+ENYCipBbiY+C
+,`dI&S6@LQP2pD29IYmIY(C,q$,dU&rUMb6[8Y#SE@q"0@jGMB'BkpA6()eC2e-A
++)Cb8I8q6GUUFHD&$682aD254+XX4LX3C4A!Z5[[XabP)40F&k8RV(LLQbBN`*#2
+T%DiTRNYpHRBq#iLKR9mNXldL#,Q6+QGk09bVbmVideE"R@VF!e3[%Xf$@SKCq*Y
+!ki(6#Eb6+`$`C*-hACKa#IS-L8UBbmV2&3M+C$FPYl'UVi32Rj2Bq)-+F"iTC%3
+3+(XL"ZD`IXdYa'5ZG(Vk[MZT84jRm5@1R-`JdI[r4QE0Kc#*68rfe-T3%#q0pD!
+Y+KY,N!"I'!,M)kH`F[UXL#Ja1!!RNC,HZlNY`X[6DH'ibckk#Jhd5,9DSDZJL*&
+8qSjJ-&0bUYeYaaP9PIpY#dPb-KIZCBa92i`MNrMfbUcVV50JRAccS2h6[&p[a1-
+*RS@-*YX-QF3@crJdFXUfK+F%%%MU26NkDIacK1kda4GG3S"!JpJ$Ah8G$cd*QVA
+&@"0'G80&R*(GGd9H@TQ&)G#L@!'c(S80m@J!10PefJVTPXV5IVD@T+&%lJUcp[5
+"L*aQAM+ara[Em-IlI[-9L6`'bRRf$#R*KCk)4f&3qa2iYCh(l)Z"l4"*eAcX(QT
+QK4[qi",$B+c$3[S5L54i+6d*rH[Vb-#,jG`DpYaA9ra5U"VAhM6DhG$cH(4L+&)
+59qPH*FRpHPS(9C*J%bfR1m*@a`@FSS[a@5cm#bUaiYF,C9Ckam"4k#iLN61mDrC
+aVGRm!AD@%NMCrG5q+5cRIJRdlF(%6a@Yh0JefpkCH)4Nrd,Dj2h+iT-T+jFD$'M
+%q#3'F5L0)G5G`VepRP3*kh33m6b#JPe!9BY)K'IEj#&*%(l&G9*12H`+ljFBV[!
+baI@-D3%$LmbA6ZlAZl196Vd'Xe&de)S$G+i!,CMe*T+mM)A0TZ3a-X3aIKQaTb9
+Rcq%YMV2(V%D%R'pU1VA-q(d[i4&kCSJ(#Z$!9JM5NN8Gb*TekE9e)lS&fb`2N!#
+"hJ-N)2JSB&%8A"$G5NkGUXRl#Y-H6Fc&c&-KeX%kh(m$3q#Ij'hGlpDNqKlP)pS
+qH4lX`0,Y[H)lNDd9r-BLB%ib*bdE%HU)1Q*`%e&1MUTMb4I13q'M$`pPMF@3!-+
+JjEkbrdPAq6c,cA*+RE2Jm0$%e`8I58eV`AD5Y05m8#)l*`6JA#RKi3k!4qm"SZf
+#T!ZL)%*!JQ!Rim&)SEfakYRd,S!R$J&[f&CQq%4-!M3qaB5VX1YVP2djH@('B[b
+#qS&&Pc51#MKIZ!*)41&(VG(M4lfINN"p,%$%d#mHY"r)(8BaQ#",)VEGi[UeMLP
+BCZ)GPYbXEQ6B0R91E"RAP4hK9UFq$Thir'!jXN-'M4Bm"m"mdeN3CIabF(MZMDH
+i5R*h66[K*N-09,!X3l"dLe4HVkM8Nq-#@-iXL1EZ3GZmRCE'6Q)Ei%'0dSU&FfI
+6`($,LekCP@E5*q"C#d4e9AXYc,[%kTZ-k`mH,k3Nh9(SCc#`e8B93&TP3!b&'0Y
+NXHZ9R41@Zmqb#%*4,"fjVfPE&39KcHfMK[N0#,1r1qT%%J"`cB8d!d`Z!liZQ+b
++Y5hABFlKHVc805AqI!NjaI6lf!XhKIXq*erEF0T!4%AXR#bVIl4Bl#Y6b"bIVNE
+pqiVYIdU#9k9'(,J11LNCISY%e!C0Zkqm00HKY!ZZqr1`"&Y,Sb5+jM3'6iFJpDA
+DmXK!K%H'`kb[N!"PT)Z`Uae$M9eMHh8&LAp+CAY),3R-%[)pK$JUPN1JA@p"68C
+Q8`[U*Y!X!'+F0P3DBM,*N[h!!GdDA-A6E,TJ9kir@@(`*)emr,)Q2$4*[",3GA6
+fUd#X"J[l(Q&!&Qb++P5hPqfEY!RXAQmm"J'`BaIhc&Uq-3(CFM4eZL9k1aPN9Mk
+AZarLjUa5P$p`9,$Hk%-NZB2Kkai2i(C@66pVJ$lHTqI#&EP`PPf%`29R*'6UANM
+U&rjD!X&&rfLAUflI@8E[LQ-T,YUk['Uak-5-c)8YJm10r(CjK9hG!Fk%HBB*rL,
+p8,1C&ApbM$YCBDkUZ)T#CT@hahl8'EQ0B!8$RVcrBa8N1-fr&,hXm"j2*XpK4eY
+FdVV'ET254C!!GNL@G'5bEeKKYBfJj#G''BA,PbDVVeGEhb5)0CDM50AqY1D*XZK
+3L+'$F45rk8rj1JmNT#-ap#rpQ2eTP0XS0Z@D9YZ$SL5Y(b*&M'*I`AJel36i$-r
+QLciEa2P[S83I+4U%E)UHe[3*dc(1DK&mZ[N-NajhmMTa0M-A9mN[Xb$e)`U%6ie
+L$`#0,e$[-+&L55rJeecqJF)MeeaGfL3SGF&9epUUK',epfY-U)'$PYB)if$ELqb
++LJ65rL4q6@Y9K+Gd)6",()-a&RiRZ2*%)QVjfTE@PP6P6DULD+5IB1%NYU4(LjA
+dF`4kNqBRj`L%JjMqcbV$c%PQ"9qD(T9-AU5NHA[h948rYj@#*4p9MZ8pYPh*aP1
+'Fa03Y%AG)U#VMT'ZEpiBGm-[b)!4N!"BihKr&A1L'[D!)ddTCkLIK'$Dqj[#LV9
+"#+EMF4'DJNerqETr$1p!$QqD`Bl`-[eUFR8C94F2)Q6`F32&Z3YKq[2i%8fQdac
+J!1a#h'&A(lFVXjl$P"4@jme"$*fPMLHA69j&I"ff('iqI2cP(RF4JrG1`&#X-6a
+'dSb@hK(mbh'@C5EiN8kdAPPmH-"iQ-5a"'R`IBl),@UZ3&QMR*kL#EEa$q3dYTj
+94S6#F2IUGdrr+Xf`mXe#"c4AKXK4e),QqJI@I$hP!XX((5JrjNrm-`bemjrp,4I
+8Mda1iV,dadAEim)I3fZq#ad'DGIGf!B$5'DZk$GfUQM[6Jf2!mq`$Am1!abmhmJ
+l'Mc,UdNJZ2lN(MmZah9R(EVTM6L'eG%YkdRp$#2bUlX58fLi"@CN$REe%RLiR&R
+df@IM8cNF8")fle$P#S1CSPYZ*&T0D6paN!!&pb6pp#J29B)k6m#3!!&BEA-#RM4
+%Pe[1fV2cd"3Tc209C*4iaR*CHpi[d@JL4B6ClD&qLD$PAa%F4TN51*YM8Q,41jL
+(9aVc@`UZrJ*!rN`&`"RM$&5*T3JJUMU45pNG,E)p32`9%5c&,)Qfc&54e`8pkSB
+QDh(9(Y8V3B-HR4iJ-0"r9EKP2p&m("6r6!84*9d-f1B!'B"-IXF"dF,UlU8"he*
+I15PhhI1f"0(BC8RVmqCC0HCFRe%@[6pdAFX5ed0+J9`H3I9HU5RC35DNi@DkLK"
+N(TMY(EKl'CA61--m-DZeAcF'a82,+4,iSlMZd@Er6Rc!MkalNlG6qk@PalK9ZEY
+GKqDD3JBh-lA"F"Um[+9b$G!G#$GNX9IIl@"PiH51TFKr''SmmI")YSkC993PPl+
+M$kC%qkf#1!4)0#bD#RH$8dFUeL4$b2fR"YAG$5Gh$rMb0h6G((3dh"b(d$`6"Cd
+`Pd"B)&A#j%3Ml"&hmZXkrcN-eD$eK$#pEl@-Jd+)#bc,-2([lL1l6`Icj%qa%C!
+!Xf$ifBM!PUp3E0$K%H%Xb8,"+aZ#Y-*)pUI#DA&2IS2F(e)qZB!'+-*A(NR6YaN
+q&U-kTYV9VJ+*E+VEZei0iaZZ5ECKSGK%8qZQhPZQ@%2!FqV'raJiiL#LU&ekC'F
+-!iKBN!"NBGC*h,Bf#K!CJX)$e$DGk1HC9@rE@F@!f*a!01-Bj%DaXaDmDqRS`m#
+*+e8frF!G6cAf65Yl6!l3SEmI#[hl[QA2%)%fi*k%R"-iR(25BX+IcI$)"83`F!a
+r1&QU0Qc&*l-dkebMJrkal9-pZrCL(,8V-r9,&hS128R))rU23!VUZ*NIE[Z4pfr
+mYT!!A-%iX`rpj%$!K&CSC@"&@cf`@IS&RK9L)5AKfC!!``Hj)8,X+lM+NAPp5#S
+4em$5-ZG+[2X-i(kK&1hM&KJYD)HF2b229!a![A6r0#Fdd5fhiC9$@&5"(3#8j8!
+"%Sc!LIp,Gm"#m`lZi$E`1"656Y`5UXBZk1r&[+DRV8R-H1CC(X`fir3ji3$d"X2
+UeHDbF6-*Xpp8[bKdXA'YEi&`GLAJ*'V3,j3eG8ri`ThkJdb3!*6VmTUP(K!mFCV
+0HB94FIbMBmNlCj,bY#a4qQUC,5+T3`U56DkQD*UlAFbGa6QSb-GbfVa0Vp)I19[
+,)*1Hi6JV"kp4XEM[6+Fielm@Y+lfrE$5mR(@H[d`'US3l1aNZ%92lEF0&p%aV9b
+%C($RYRA[rhRI1iX9RhfM-aE9pBhcVeeR1!IQ)AMUmP8Y+GTZfiS8Aiqj5#10LHf
+*2[*1,k143#382-c0jQVal#J+lAjGp&ERqjekph#Ib$@,,G[LKZNccNZfAfAJMR)
+e5UL6#LpmaYDhNMD,'S,m$*R6IH$1-Rjk-l'GMd9f#[Sb$2dCT!-(UF5qB2Gq5&k
+RY'F@ImjNm-[0@``+r(KP593I9EE!fEk8"L@Cm`f3!"c1YP)83R1+Y00MIr93e8G
+MY*%fPc*,Sc+L,qRiSphbq3"PmXpLiCq,HfNjmcShS"59d0CU($G3"A8GJP,lC29
+@f1rS0TL#-RkZq1FI3M3RHIULqNYXFIaEN!$*6)IRJeqdI@5HN!"4B&@l08+jTi$
+[e,m,R-#,#6*-RR!'E11UqB[EXb*mfJaNhU4J6D`J+348qIjR$*5-Zm+PGLRf[#,
+-2Zd[[B-[RY&1EL%qIepl5(h-G"48XFHZQ(Nl"e-C2e3pAp8UGb2qclQNKjd'Jp9
+53$,iT0EB6F6ENrCL5,j(4bF8&2#ICKK`RDMj0d`9CUb-2(pc9qISV+)39L!Ek@h
+&4[EG-ZV)2JmQJDJVX*`RTH6-1b3K)PZ,-,P3FRXemLbUAE3Kfr23mb80Mkb2Tj3
+0XlIi[c65UJYFU[fQNNhl+GD5elTAI2jC'dAGkGb@krAjiSReTi&XI6A0h`FBYK#
++ILEP!Hp`%"#%Z@*Mp,*KAIe&FUASSF03NHj5KP"d'#X8h'40jBIIMMQeL3lR-ID
+Q(lFQP)!aNYIeEU-*rIBCrDbe&McDlhHj!1IYBaiMie[*I$Y10Q3-pP56@rA$fkm
+h5QE#C$RVpD["8)a'!q+R&hS@,T%MQaChX59MfKm+96'%Y!bkhAN`&ki%m"BBa()
+"NhQ(ikTRZ$jN)FX@P@HkhZZSlI`i1pF3Bf*!*%@@6XfXLB!MMBpNF1*0)'TRL6!
+I[lpG89UN'rl+k'H"Z$`RLG`KEH%FZ[T%%p1e)(+UG6&'BpA9jNHbXl+'JB@6NKL
+L)#Y6N63VQS&N#IE(I[fmEAkKFb5D)m#KH([CDZ5R6&A+C$T%"CELqLqK`L*U'GI
+fNdba6FdIdY'i!Kj*-rk#@T6'#-0#CrAbN8HMrai#%C'T'aKE'M-Jj"SQib[HcCD
+'rfj"Tm2GcpJ`QQBDIl*-"N-f#m0[&1)9jIpNkAmddUL)24)&l4Z%QLY6l51S`(V
+cNh!GX`jaXc9p#`YJ*q,MHhB%"XLaja!Jb%J2FURKU*p0B,'%+ZE9kHa$FqPRqN-
+6Ah9US(Gip6"$6Kj%Ya+G0#Krl*FGGiaIf(B690GPZXKI$a1@RQPhf#8YSjY*55G
+*HGcJ0SDim6eEkMG,`jr-e4Tka8BB+NAel560*'aKQCL[3ijfh1`0KlI%LNP@*AH
+ia[CMJIJkq$SIlTHM4#NY'1i[dJ(jP)G6m#PeFBUf(KEE()Y6$1UBD-d$(l-@&Xh
+m,+6pTCFS0jUEF$!EmCrc-XCPUYbiU)Q-eil&PpFhXH#L"Fi!["$Yj#dD!k6eM`,
+kAc(&CRB#HqBphZHk!0`PJIm98CDJAqbiaT-X,MLL#AUE-P`VJLpe2E%5$lRaabm
+Y`VHGZK`P3%`K[Jl05iG,XViGBaHA*)2&VF,2EU4R94!4VCDZFI$5rDd+K"BYm4*
+)3fa1FUN#ekZk"-p$!4H(24P$1#faQ*1YbeSL2CUG@L`SpC!!5rX&G,GU(F*%K80
+0UBPdl(i1kcdJ9(ba-X["XYaX!K@3!2U)NAPIE[)!&&i4#ePL1F24BfGQ3S`"`K%
+dlBM@XI%N"#d)il#`*qNZ$j2D1FCiT*bR5cJB)k2%iH`M[&qb"(bSL$Rr-3&j(Yl
+ki-ZQ3EMk25MbSfDHB"LI(AYVdJ[hU[SFB@+!ad20Q2,%%N4A&#`jrR-V`(0l`!*
+FCZAI!,(p"e$'Z6e21Lc8rhR`TI@qh-r,V`0X["0'T%LK+H!2$SU+8k1(``!JDp0
+`[c0@jDRp@MRN,eYN-mH!'BRHd[$B$`*2R(0KR(jC[&MlIaY2J'YUMTr5*ff8*KU
+`i*cp"(pCEBSl1!fXcI,8PPb[)-%GMiNl24)eP)86Fbf51[Q3!*Q3!(meH2A[6'e
+b`kh@U[h6-k1N4diCqCNE4RfF6j!!8)I))N2#[6!)Am@FAB@dNHUiRF+P"!0QNk2
+k[B!hXl0EQU'TDiV`D80BD9Si9@C!L88"fjXfRp-[*aGqbiQpH4GZUK-dLm-pA+6
+L!YKH"lLmQkYp%-5&-ANLM+YVbZL5&Fc6hqXppBApV9#V#r9pV&59jCB)#b&!jS,
+8SR!e39pKH-NY6QjLGRN5RKZ1eh(a,IA5m"360&Tm4-,'+(iIRAhNj6`"%95(4d[
+)YhHVXFS&3kIf8RjD)L-Mb8L0M%CK4X,[r&FQbdq''h`K,*QK+[`$%+brlRHD0'+
+q14l#S'dceC8Mr12[6cD0q(mCVN3TCN[Tr'Qf3FBMYTrA+1iE9MDb*66Z9!SNm$*
+91iZ9-EfdeVf26d#"8Ebe0[[8XrCLCS89R2&DYVqES1k6I0G6(%XK1m25'@brme%
+8e#R!&M'#)H&C#@3SKM,Qa[dUZSYB*[k4XLFmM)!8)5dS4C!!p2-,)5rKCL',Nr*
+YcE6mESUMSBIQ,LjIT0aH#qa5*pGXN!!f-MdL#(qkF!`c9LU"fh"jCkjrG()`E-i
+MlIpHD"MbjD)SbbVfKcF169RBUkkb+jF%`KC-XqaK&F5Ii8YY`e'2miNQ&RJ5%Te
+C[Gd,3BXarI-blTJkSD--3MLbPa4c("U2pVq8%(9'Hi6bE-Yb6m5))lmlbiaL!f'
+C)K4"m*D@Fk(SpT-qX(",rP3HQT3IJadVYm2XYHf6rL6*(%L%!ieA4AeCpB0)ZL$
+[KT*68[A1aGd-3aN6l)N$CqpN,maVaJf+V,k3!%V,8TFcdZ6EfUFI8b%2ajKb#Xk
+B5GIHG0"i'N88'2(aPklHV&&914%!2U"GH2(E11$I-r'!$NZ!B'5M[%4PAT1d[KC
+@3X1qI[!dY*-'C*DeT+r!)*GS$R1pYA6Ulhm*jJXV!b3-A%FHj%(D$HN(IC9eUp[
+58iYbAXa!Z&5Er)kA2JQf)mZ4YEh&A2-"a3bjkb4NU`KNEH)jdCbV!hrQMh@R`Dh
+9K*Z"m-TRZaGK&0mI8qAP$FU`4S4PHK3%L`@5m6mKZEDEpCIR93UVdTYM-6&MGbb
+$(I+CB`@0ACDr2XYrB3Qe5Z%0QF'"3DF6S*2I1frRj"bCSil(CI$&ab0kAETU9-P
+f9,@rHSrm*0h%9X4S!%*+L,aYiM`fiD5cLmN34J5N#h`%$9aA'krkhl$KNcS$3XY
+!(%-hh9-q4L*eX08mbiFMrJqEcNShR#9*,dc,fZV%(hr&$Y$Y@2A$-6r@ibKTbRj
+*h'PM22HjG-lN"8dQLUij%0SpP1k9fErV(IGL-dG18"2,*[DFTbdfrJK9a0GYaY@
+9fJ+pbe`XqKX6SPQb,GF9hNIIkGBce1M4KXF!f[85"PDkhN[q$e5RGiQh1M9R@XS
+Af3Njf`,e45dX6R%T,86'-@3``UrY9V$bif[YVmTGr'lZ45*,,a[JSp)jB11rAV)
+N**qqGcCDD(G&IbAl2Srlh+fCFKY@qrMA2MJ8@i6YcT-UU*bc$!QaX)'XcGUel`l
+r,BZ61l5Bp%`13d!1r)$DNc`UZjGR1kZ`@j46q(b[UGLl,mIl0%aN+i!hDSGL[8r
+'`VKXY[!(12kCQi6EaX&9cYD41DhQ'c-'Z34m3%b5,*LVA9-Q)YM825B@[Jm'G%Y
+m&-Am[D,0389&U"Ga4-FBd2VDMCR',GNL,DRT5mad5LbTEi5UUhSqhIVpHA#%jN6
+mh9md)r3e#D8mK2(JKpFAZNMhU)NVjl@%fA1EpK!IrH0ja-1%Zldd[+%%(Nr&Gpq
+S`[,dSrA3Nm5KaJ4"bN(3TLbGHPkrKCj&-m[(#T,fl&G([Rm@f`TL$kalLh@`hDK
+2$A1rGieRFl4+52-fQ5p+"qBQk&"@a5[ZfTfR1Y2)X10X*@-jGH)CXHI8NMlkBN2
+GB2&p*qDE#9X5&SrL(HL4&43[9XCIF"234Er,Z!A&S+$*Fm1JIi$Rm1YRq'j(m1U
+Eq(CCRm1V2q'rIm1R(q(BYMq(8[pKYYr$T(rKe[MbYpD%#k#L3cJl@@HER%4,9V#
+q0(A&i+,V"%Zm!cjV4RTYrdd%Y-fAfTbL%IX)LlV$!c9Ap-(E`q0&(-E0916YRH(
+ae'Z(d-G)582V,M,D8@MDTbh8Gf0!AaKY%BV!4cA#rCF!S@d"[Al[$&1BPT!!2GT
+I9NLZEl2N4%MbLBf4a)EQ5PUQ0E2iA[%2AImY64D*f0c&(0MU,8BGhd-6)2S$*XY
+ckATKK`p8&KINTAG1N!"R0,EcqLV`MC!!R'&#&rpI`FhmHjJYRCQ90T)QcB,(h*'
+B9@E(bfSAY3ML"@Sb$K3mPhE'*,9`pXFUJB-',4G+8i%@&m'0@SeBGT[(L$%4%L%
+T8LP%JYjc(9(88!h&$X4`[@pZ)kN8FJUS)-5[bp!jGAY99ekhbdk9h*!!0Dk`N!"
+5G4Y5KkNSU[LE@U!*dQJ8PD9V2KKR%BY5Q4d(jp'rhrkUl3EkI,qm&dj(X51#Rli
+Im+lqPG%-I%8#"Scer&5'B!5,p&LcPAVN*9F4kQCYl-pc311I,**G8"Q*SY3eKa'
+%dk28!(F8I5J#8SE)CY,`h'"Jr&@brD-qSqc4iN`hecF'XrSi-ccr!QB+5kfhBAl
+B#k)Ve'B-"FZ3!2+!F$J4Td,i&Y+#,9)E`Bm8RTQE5)TNf$bRah%j5a[Z#&-6*UN
+JqG8T'5Xj"K6NR)K,[15`3SF+)3HC'BllmFBM@(QXP)0r)fcIfCAR&!p6h*lSe!H
+k#-$A"MALG9KFp+JBj0Fp0$#k5[pYrGGD8CbSmAA8Qbl!`aJU6khl,9cfYEYB%Ta
+*,M+!dqq)YqIH2TqC-JCef"(dI2ZB*pLH@ejmdqTQSYG%q-9$d,bXP8bG4-mb$E"
+I--LBkiAQ@k0M+brkkE`H(hTS5Hr8+0TQ+SGB%S6[MDlZFPE$4&*hRqQLBGq),@!
+ISL8rd!$d[&L0[miF#058*R8)ihN3*dSbq%`'2MrFe6&,,mhplJfkUG4baRre8pG
+3Up3MAH&bPTl'fq3dRHJ)&HUF,r6X3E(alEqXT(frGK8p9DU51D3AfPDE0Q*UHN'
+a2P#XR1#I[N1k9B5Gb45XiZ1iI9@eQ+)%jj68r*-pK#'Y+khD[ai,&Q)A$Uqk`L&
+"4aHHF+Ij)!bdqBJr#82,&c)N`aBm)VM65UCbNM0-(bk!BMqAp$dCU)"1%d"jp"3
+%1)YJ'924pbpVKKi&+[,HP`SIeZ3lI+-*+1eqkdpXi-GI!4@jT1a33!qUTaMY3Lc
+pA4q["!-9NYUC`mEBjCKD5cA6,[R6'`82r,m)RXcLCNYb'lP($%)Fh4,dXUPRSqM
+Bb`*`BKBL-Dp9[!Za1k,r3efpr6JbL[9&3l@KGRd"46H5d2L9e#f&qPd,Mpm@5c*
+D1Ybf225MLbFD2k"!I`lF1,#dTV34$&,"2CG(dH9`a'XdD)$$DFif%++lRY-IaPr
+[j'H'%eN6pKEd[K3*m),T1SI[AV0KDU3A-K4(pL10[YiCHk,XU$m1G@T66D2ATQm
+Nr#L(6V*@D'eP6(2"MUFlA4k`QkdGSYYDMf+M#QMF*m6j`RRiV%EER)$6X*`$%U@
+2AE3a)fU@UP5CFNLDRCXeY6T4E[@)Br*C*Z6R2kc8@[fKjCEGCCEZAc"A&6qQBh#
+'LJKTGLj#@S01jUATm!S@&)GpiD,MfirNhq&JL0+%DZRNi4@NKh"eIU,,I2mq$MN
+83*9amTHSP&fC8qBKE*,R5f&4rU($&PJRH4T35,BNNqDhGp0H1*AH+*&J!d3m09-
+IJ0Pp8B(K5pi5S(TIafNGRF43J4P9@f+`[0A8lQPFB&YP)b8M!5YF&F)irda-NCd
+MRhTVScS%1M+"%fC&ABp2VS-#kJ)Yjm66ZjZ")@l@SVG0JQDS&2dh66lQ8B"rbfD
+K&FN#RHZYbB+Rp0M'i8mbVc@HQZHEJr-LikDTVq)V5#qR#HfTDicM$hEj&(`YlGL
+Jq1BK9md#j-4SJi$IfP0h#CRNTQCqb1Am-9%@QR4KU"Bc*4'P"%2MQS5)5mdVf$1
+e0GCKG5lL%KK6!VTN'5fMMBjNl'Q+LTalT!31XbXc4jb`q-PE5,(4bXKD[r@+E6m
+6m0YA09!kR%"V3+f5$CG1eQ-IE&bSdk`DZ"'rjPE!B!MNX5P2+YE8H#kA4D%G(9X
+`ZDpm!Zc-l2Z@AaDGYUTG%9BD+,c`%RQj9I4#dea+"HqG($U)(5l-JGGL'6H)CYp
+6@i@RpN$*c+*L"(FUF9+ZHkk+@k*9)SQl!H98HUSHrh5MG3!jh+qMDU1P*"kXqRk
+cB8$@JVdH0XiU&@T)jl26,B#dPQ%Yi5JN&'9p8rN0"0lYEK`'H41VALMHH!l*'%U
+3!!`UJ0SbB3B0HUbbCiC63aSRq[@EUbU((FD`Z0&pC!AT&fIDmjj*kH6bPX!+N!#
+"FePGAC(bQd5fcm4NGP4E(Im9LeGPN69j3343V`U3!+k#!IiCYeTK22$N#e""&c%
+15PG`BG`&*hHm0l18A6pS&%#,i3D8'3d+NK*J`AH%h*p,4F"&YU!Rf@,ppXU5kEN
+-0`Haa!+VF"%Vb8)CKGh3L3fdKN9ThEXSEmPI(1Ti*HLG1PaB$6)Y`'a"Ap3"P[b
+jVQT@G'!*@PmGpVdLr'KXR5(4Skh"!QkViJ+),1`XE-)R!Pa+1`H-TZHZ#l,HJ3P
+@9Ai6fT60L8m8iU2'a8ET-aH`l*E(iHYZa`$J`cFqfSSRhGp(+`N4PJkml'Qb*8h
+5*@Z%3c,$rSC@iJkj2%Q2Y)+$U[SJaBMYQ1mMjP%hHK9FC*GaBN4aNYLU"$LZ4XX
+f[J@def6,K'Y5*aDdhBc+e@RUFHE4f4NAC+lVd9pE0X,Q4@qEjlj+2%IRE0ii`Q4
+6+BC`dcF%0fcC42VeFCfHGik&G%irCJNjkhqa@l[U*qrZ%l@PlH$jN64qC9YQ[H%
+eAA1RX+Vm'D3*H#4%1`U1MZ"ddG1L#*de3m`B38X$jl[HdhVY(HR6b%X5"#%VfcT
+XVb48M@Z58Y3YPdSYca#DXGX[!3dcr2Ah"MalJZCf2d4RSq!TkTZFR`M5'[P-1fH
+2BADKpDZe6SdFeeBPfpFA(h[2A$,A&#C*Ull+)("k,!eTdHA%2PY[3f-$q)!jCLR
+'@FprUjHRH@SXRX[$c[T[BCDU!5UkmM')Y`V1iDB[&cSiV%b1c*S2V-iMFMHUiY4
+8SS1N!c&pUdPH)`aIIG6ePr"I!qS!18XUf@!+e-+4V5kB60J%b+0[i%YHi3mGr1c
+b4M[2j["JPZTBZVcXim(Nl`-Gc%hFAf6K2S+0@%"`"A"$Ca!YAQ3`b02em,+Tbpd
+c"ZP`YEP2em@9J`DL9G$XJ+5fSSRe`e,h,jeNVMXlr4AR"K"@G&S3)Cm#F&4bH$K
+H6Up)c%afMQJl9BlfUIYf,1&2J8X10I6jF$LN8)cq0@[qZd2(F$+YI1[(LPQU1!L
+R6BBhri54-a(9`3h&F$#Xcmf22MB3ImfVk"Yle91ame`qAmNh)UN6$ZPISf$Rb44
+YbN9L#8&'S&k3!$ac[pi$8KD8UjXDFrV+Q9KX3%9kJ+qMZ18i@fLpdfD0JdEBc[8
+ihjUUe,"Sjf%kP2M@l`Q**U1EC8`dhKbJm-ZGPk1MiS#Kc-Y[%eNchF6r0Th2a2K
+P2`8`PH`l2+*9HkHN"cjaL[Bic50XBTRSL%R[XRq@39C)C$Ye1*+cG#m)TG)(8X[
+NRQ@ih'R@i6@"SIej&h'42BJAjh6p3S9Tr911Al2eYclRFTIPUZq`,IB`)566iY0
+XGAlZP#')*Xf"`b4d2(#EKk%Fk(5Y@5Q'XQ&h-r3[b59e1-Q@'5(&-VZBVejDpaP
+@Jfk3!1!KEI!!LL9S2(TS(bCmNeA!BeTilVb,"`8j#XElUMVA5%!8VFYC0,hhLDL
+chrM+k`2$`H5PdK&B9$5$)JD'-TJKp(kb!V"`@0p#99pD[ifm!N5erK4qK4)B4`2
+4he!R`E'fp4!&!,1UTGBiT!4G-!RI3-6#mU9EQZPrlF@NNal3+"c"1$T3kGM#IR+
+3!-i+De*iqjmZ&T(JFp3[DPdbieKLRZ&R%+1mY5b0EKa[HF[$pjESdN`DAa[r)Pm
+m)A%FpQKX+rp,hm'AT3L0Z[aUN!#[KJQMY%[dL!iG6Xakk-e)qjd`Tldl4#A6HXP
+-3fZRY44`9i%rf(eQ4m2Ye%@LCTZ+3$6@rXl3RTI-,KC6VDS3F5BhP*AEE"b(&UH
+QSY9c5(0rG5TA5lqh"Ye0lK8IH+D(9%UeRBC,Tc40k(&5Sh@F9fdkf1&9YJphjh6
+`(c-dc3F3F%2h`Xd4"H3e)F8+%"I5HN#+kqS1rN'UhpEX"!*KamQ)%F)`JA[ZKQ6
+44aVA'JFTG26C2"E4GraK8-9I1V%KG"NR(-i$KNhfH'DNT0KQKD2Mi66iLCS5Y%C
+KZ5#6jD93,'V'$lZC0HJa!1qf@-d5f!U6p8#L(ZUadY"*,4S,B%-+CUk[j+dQq[N
+p$3SEbr%hhJla3E9rS$'SVBY8b+"6me&,5e")$L5Zi#0F8Se)(Y("fjMbG`rbZ1X
+r@IN@jC'q9Q6e61")YbeV-%,'Nj!![[RY-S0,N!#!jPaYjR,&U6[ijZV)6ie1T,#
+KP25HX!`F"Xe5"E%RMTNh,DQMTr1$$(Mba)I3Hm$Vl0H--MfCN!#-reS#6V[iU)9
+$Q+"lT2)aDL@b@r&NXfb5DbilmLpq`!1"32AlD3GMd2G6)(4a%k2ZK8IFaB`B3(G
+Fa'C5,P(*Q-`0YAf!G)pN0$3'fJ[%qPY5ImCUNadlPVp6%3CASDHL`IE[42TUrSb
+Nq49E5LB)&SELVKr2XKM1J%5%3@NqqXGH8%`e'R!iY%U&fDQ+d$CQULP@b!"iq5&
+ZqLXY(T%,6mi(XViTRLS+T@[VIf-#5YHPVM@&+hSVJIi!3DQ!#alVp$%QJ%,d6eD
+E6BEddMDESlA5qAJIp'cZm3#,F,lJFhPYT)QISpQ-#[16`F#h&)#b4['6ehkU`QJ
+JlbdRLc5a`FM#)9K"BDrV0%)aRl4YdPkpfHN-,([`iaiUq*b*GCL$[IJ%S%2Xa"0
+Jid)HFRSYU6IK@26!HXbQ'@kpF+3INNU4d8C#ANL8N!!EddCkNfhhX--21Ud[j02
+&-@@K'kP'"PTGf&)XT4D8XdBFd(4$DZASq'!NL1Gk,m3#0[Bf,YI$jDAbjP&5pIX
+!HjM2PVAe$C`'B0)2frND)9%qlc0iddkTj414'QPd2rHEcZ,PF3,*P(R1%88Zp@&
+X2*eIaIS(5$rmplc80@m2ajKZZ5@iE(X8U9*6'NeMkicSr@Z#(KP6&HQY8[&HILJ
+IQMkjQ&bSaTR5pN`YFIcNb8BR#ZZ2aYkY[+a("iaKX4Cm"FqV$0RfYL(+4-B)Ve,
+"jf4'eRJ+1DKp9mR'Li6%iPBQFr[eKHLp!5bGrV!k#(m+BJ+!!!2Gmlf68)-6FX$
+ijVILTGRX-rNbd%LT,1+PR%hU#QmH"hN5FEThYU`UFMA@qN4bcSA'SbMJ`A0Dhjf
+f5J)*cph,qb$8%U%Pd",iUX#bT%bc#,UU&*ffJ!h*Lr9NHS9b#NVKjL"(,#YXH-9
+(F1&Z!4X%VV6SJqN@C$#YG-0V0f2(YAl1$h,Md'q62$6JKiH5i-4Lr+j"AG&KNpi
+#(DH0YTZeR)5EU38%D8Id$-m43PCI3ILGmV%1CQJ'[&GiMRHB92kcH65XFNaj@U4
+bA#U2reHhQ%jkBjRqI8YVJafK-K)-UPP4(i5)a&MV$5Fej9EIjRKBE1#"`H9KBdj
+K5E5N[L3dBNcMNmk`HDT5I0JE-0'2IIZRErPi!fN4r$b'JqDUdLl)SVr$MLl66lc
+F5id8YZe)Vp2FcUYAc6G`KrkdRX3ERAQINED(kD9[f,))bMR%EdC%*rb"A1KV06k
+kfY$p8hL%BKY8Aq'I(m"f'DlheFrGbaUZ)mCRF$92U6mNX3S25R!0e5$m2rFV(1k
+EEVr$PPG*Kf-ifqcGK($CN!$QDBRq0qef9+Df5VG`e8P0)'5jC,PLA8H2'3kbLX@
+d[P4Se'(*M-"4H0f2'69XrBmJd0('QbD6K(PrGc%iIEYrj`I6[p'1`&Y`SC&pKbK
+HR1[9jdR#!1$!5I,PB#@NeC+QeaR9))D3!!-Z3e)U&43`)@,qK6m!)rp!(k%RIHX
+-,iYPJFfh3pjjF"M'I$Gl(1IfJ)!1*Q%KNarE0JekS4LJ*h)p4cL)T``5il`4[,I
+S&"C(5H5Y)rUb[9`'6pUq[&FFZZ,8&G@)E'8%F%3M"N31ePj3XNkAHP+ST"04I3T
+*-SDiJ"j)j4%h'0(FL%TH8DMKAjBZK5VlY(*%d&KiSUl-D,M)5c"Uk[aUrABSTM%
+b9f51Sif$NL)49#9a#c%VM&hDj[22`icU[[&c`9#f@-SM#bU0mc('cmaBK9JiCqd
+$iPMNI5qb@e'Mh&DhLE+!SQ!e4hPQ`E"*lB*hX@'Pj8V$6BM59"12qGccdK,klCl
+#"I#1[%*!RDTHJHbJ,9Y9UDeNG$NY[eiKlRqEJ2fkCSqSc#FMM!M($#LV5VcaKLN
+j!KaXMEDe'Ej#1ZL@TVdbK@[FS-L@'I$a+jLIepMAH(&KQjAE*2M@!NiYD*G!"l&
+KpX`3D+!UkrbI"da`Cdlq3@aDA8pj)meQ&LT1TXB4+fG"!C8p%Dm'PA63AH$*1B`
++U!l&GIh$kk$0-6a0diElFh5pFBLXMmj+[@Z6QT!!T[(6+A#9!15m$-a4(cL($4A
+#JqU,j#5(pf4DbREJ[i`X#5RhQ%`4Q6I-e9K!8)A+DA(L&0(0P8`!6epTP&m@R4a
+Q6KLF5%!r60!V3hK6hmKGSQ6qQ#%fjH6'Dh'U"cS3EF)TCXRYKA%efJ@er0,mJ2I
+UGXUj4PX1&$'U4l5*k@'A!L(DCIlDk5jS[K'hi+4Ffa%(pjpANq25i@c1K%CmIY!
+'KE(B#d2P"1Tk$LJa*&,q[d"Ra8[bAP9M+pEA*"bhdJB"G8EX8C6[Vh&R,6RAdG5
+)8)KV$I,Ve+#F(RK$IT1SfB"M$2DAC,N3P@6FkSE)i`UlTQ'8LD,l@rFBlb[EmH!
+l@J&01@HL+@6q&A@6kDa-@ZX!PpSKY(C4ZA()XSf*!&CUS-J+)l2mXr3T)IV!922
+j!IbeFpLZcrpreFp3qMFa&0LF)Tc2Z15G[m9d&#Ei',5VXMQh6T`F3X!aY-P3Bdr
+Lrb88`,1)8G34f'6F@6C+AKA)#De2iic)@ChrGVF1%GqQ2[8FGmLKXL5c@&($2!D
+@#8bADl*'XT32LBip,mj'3hdRp*!!d010rbfH%`[,j[QV"C9hTd,0Ni5j"KR1K$r
+82M6MSU-iE&rh)UKBD0U+XJAAja8#Z5kA$2T&ak6$c!&HrCbfkM%HFrT11*eqCI)
+%DdVh`+U2I@4&TaP0a6'E3[Dm1(P6e4pH[6&G00l-$BDiBac9kQ6KV+b#mVNCF3F
+[L@LkQPRB&*U#m"h$&CI5XC)GHicdMhHZSi9jN[mcDmKFEr4DZPR*,001!mT(&!(
+NdL"$!A$r,''rZ8[KhaE,8C+['TZ"$"93fePa,01RL*p1$L#`3Rbpf6QbCiA+D$%
+9%Q[hFCFC(C12Cr"RqXkU0j63MkAS9SIm-5&caLSZ4+&pKqB6l[@a,B"$R(RJ*mG
+(ATp@abSk[b3FF1U-lQY!acIP%TfEACrG1ZSA#kpa4G'q%kr61,8V1KNAb0+eN["
+d(X*N-)cdKHFZSiM&Vph"bFHQ)AX$!AhGcq#m(6c59l%RfXERG6ThKk@J9h&Pcq!
+VbUiJ9[%H[!MKQf4J)#+,@P+bdr#k2*2*CJDX"0#SVm)Y&VQjV2$F6@Q3!#0lFd8
+E2S$&Rk$Bp&Xp&`2,)Q0M%e*6ieCq[2d6RV4U9dA8*@U(r'K6hGPN6F@58U85[*L
+)"Ya3qB3A1XQcD1!f&&C(@k46[0)XbkKG$(1@P5!`QP8e9[Gj6Qhc8KHNXDa+3Hl
+YbQ3mfTeaXe(*)N1XZGkJ5L[UDjPM'-0U#h&#j@%iQ+UDpf3Q!Q%&%CjPKd1BN!!
+C1'*2eZVYbNp"mVYlKXeqGKcX&EDKfb'($Sei*252jJ!AY-!58h)*m#SV,YkB1[G
+!9FQ0TAh*pd+(EfVppU5m%'##$Z6jCC6EL+`(Y&cUM#Dl'DE[pJLI@m"4-'F3PK!
+$3#"8iD`q@@6pS@`*Fmc8kZ!@e#`fq88#[i+m28fIGid'Si9TN`dcL3pICTmC3BS
++A4p&I!5RU($TN!"[fS1)Tl!!d!G31A8`"0YBPAj(RbZU,GAV#aref[)dCiA$a`D
+$cmQdaB)VcQ'GE-Y$adiQF"%UIp'[+dh4X@reL2kUXJKr`q8l["dRHX6!p048biM
+3@AcNCm+h'Nhr@kI,Yf*TrB6$Z-MNp"#R#N8l%D0SJAm%24!$cSK`SP`)84IrD'b
+GYG`+FmfdfQjI$K+qJjPQTFh10LUr0j!!&3LbJQdP0,['GB6JjSRIRUjcNR9"cEH
+cN4T0JMrFGE581c(3,1d*21ZA+XRl%NpkQpFNk#!lhRdRKX&B"qh&kGPM(fD1A[H
+)Vid#'4dF'3M30"X+$pc(-FZ`c@m9@AZ%Z-rR+3iMkS#`NiH5r`24e-A5il3#JHK
+KYY&J&&TqHYA*4T,UCIXGXqMI64R@'d3dHJqSQfIYq0HRMD2#"F4BkC2XqPfX!KY
+H&1SqG6D05$NQP0&kdC@jXNRb)bd@N91N2QPDXTmV$!("'2$VG+*K#2fqq4pTMXi
+MBE-YjBhPMJcFiJ%)*'GVP(-%SXUNMPQjaYUq6k[r2bD+kR(HKMcRdkL"`iY5c8"
+Rf8E1p[(([rlZR@%TD8)C!3d0lh2mK`mrb8V4UG!cU6aMB#'3!)m5TC1c'5+fmlR
+&'3YFepfc*Rf5cMlE!3VqLQLj,ZF1kmDZIC!!)P#N@C6&1jk+B[0%m#lQK@JR"f#
+$k5mXcl43Y+CbL`51T#NbV+Ir+QM[8@JMB'#$4!D8U&m)hiGm8&AIZ5ccf`GKrb-
+$%J&e`G4Q!4[K8e6RFU#Nc))41-)Ve1lGGbDJem9*#YH"Jab0r'2Pmh805C&#rCR
+JV-&4#Kh3bCjH"NMDYI*Ak#YC)BKK2bcr'"6!S'5a!EANe@**JGa1+QmHI05YNED
+J$dACh1q+G@+'Ei45HfhUS61[F`VhT#hGKe4U`i%@5+!$PcD+a!-NM!`qD9M8[V9
+AZU[(1SUfZ`pG(mM`5qqM48mj6p&EhDFKl!4)@cl#U5BeK9'14#I+!X&iHJ54,P#
+'+H[S)f5$&d2k[jEHfZ0l[B"[P3bVF4`9C1`(GDDL'62Q5[I1Hm*LHEp(Z3"mMlm
+JBmpY+CS9m,C1EB2pU$SRL*q2G,&'bMKaYV3&Z)JqXKG1E%2#30RGpFKLPMckG$$
+R1TJ[YlQ%EcDBq6G9iPLcLR@`kArU,Z6X%Fi8###*rVC'[Z#mA+FZ[1)$c*%h[&8
+0'qI!bPJb8,#H5&fl19r4KJ6`e8h,H'TX!H,#8F,)P"p[Nmd"IPRi"&[#-XDCFcG
+S(1`Yb)+AYGIe682#pq9Bqkqk3`@Q%C4k+r)`#eb8qCjSM96IUpY"%bXMkHiXV#V
+fLm8G$H*fR'ZKZejG&3Z2i#GjrQl@cZ+`,`3V,CZUbRE6#6[,T"B*,`I1feCEISV
+ZK)ie!bp*SQ('q0FIiiePj`DkXUArE-19VhIJbDdVTl%RLEEBkJ+*XZfLU@YC-%Q
+$Ul)fUQD3!&Z'VReYdL9T5HQD,mIVrK[dSB@`!6pUdcD*l03#`Rm4PJm!D'JM"rP
+EAdC*+,$%86[,a4&"kci[I-P2-D4m@LJpa(p$TiGHR5R!r*m,'CKf3HicM*RE(3[
+`*Q'pJEfVjpfTf%jLN!"+LM!JYZV8'N``'$V%TjkbaC(X*f-Mj9EMYm4k3lC*d%%
+KBa053i+&eb86"PJFQUC`BC@rPI2K(19IMCH*b%d!DF9&2jNE-2I9T(ZBq+YZFdV
+S82kDdPl0S(XVQ[-LE*SfmVJ(RERKE&cQRXhUe@#'mlikpQiMY0QT46jq`05$+00
+GYNbae(2lSqKpB,J$@15&Xj)l#P1e9rC+p$8TCI%U`@q+Ql5CNh35#0V"PFrp'$M
+&0$&'p+Mk`%J-Ad'6KJ[+J`%ANGpQ0e2KYj1QJ04kMDMTAiFTZedN8+PE18TZjN#
+c##J$Yf[F(ar[S`paQY(da,q&lRGUTGp"e#3-Y`P&9MSF$d)!@qcX,Zr633VJam&
+6-5`*#5MNCR'hCM55Vh``8b6q9rQC,dMF-FISd@XD*rGXa'6fBUQ#iTYIfaS%Z2P
+b+i0G-hI3X2Z18Yk#``4KVBqG%S!Dh4Yk)mkj81lPBGq%IQZ#@D)Q362[66Y6+$L
+UeENdXG2!e)+)Q)5pYTCh3M%$80J"k5ihT,jh(!jPJX,'T$I)(r2m+E[Yd,llD$r
+K6rm'TAm,6rKI[m(rI`d@rKBRr#ariDNI`Zcq&HI`[Eq'NhAm+GrKSY[i9Yr#Tll
+G!IiA$r#q2i-@rKA(m+1lm+5[`dirKG(m,hrRT0IKT$brK4rm,chm([p#QIi@Tr#
+N2i@"r"+hm+(r3B1r"QrRHRm,*rK9eq&UAiAip%DVlS'kH6Ub)U6'%ZC-DP0d)#d
+50MU&@!J-Q%&#F-TC*I,82a$eP1)%IG3KbrAP-#Y8JY9'X)mjQeGUp$Vi*IG%1%A
+%Hj%MV@m08IR%l-GE+2kjIUCjc5-V$Q@qMMRPMiVA,0pqbE4UjH&Th-r[4`1m[5"
+q+mAVkS&pc68iX9EJT%0"H#8#qjTUF@+Y`8J8[-%S&pc68iX9EJQB@H[(#KIM9mF
+0@GEhLB$MeKlVTN$KQh86(JhELZEbRjLKCDRXQcDaCK5Vj)1kH3Z2&29I3[+FYR@
+2MCE#ma*fFa429[bkm&(H-4MF+5rG1CPJmKi1#dNG64c*9E8q'fY0,&rD0f%DB+J
+r,F6B@#@6[56+542S!UY!$2hm*U+85SEfD92F5Ij%Kb+,28HrXRkCc5!JS#"M4bF
+!TI6N*qY'Mh'XkMF-@3DplUTq5dQkU33DKk`(rhrrImeL6T4"[I03EI9[)4$MNiT
+mcHED@rTfbEPeib(hd`P%(R`fBc#K0p!SHp%a9-'f-Kpp-*4"jm0Q-`S6I3+(VL*
+UB0XC$lkB5L$ciE-CK3QqJ8&qNT8&0k(D3"rYhp0MCc6#P@SC88JREBHaB#S6Lcl
+pePj$XV%Iq@#mi(2*q$Jj@AJ%#$V)FYZBF"@%(j3e-XReYEUNc'qKaER*11RVq(2
+PTZ!Zck1"$k"5YmPbheDZilFl)(pXM3,rFY4VK%2YP-LbhV9El,MH)`A+Jl4@'i&
+"FU$Y%qKZKjl5FYA9#%mE*k%TA$X,,e*keDa--a3Q-HT'X@KL!Ml@QHV%*83G@iK
+fIb8*G224Pa2(J($C1CF0VqcK8l)D&MAY*MdMaXlcmqhXlG4j)Y5HL,$iUE&$@I)
+8a(`5#6G&kZQYPi*I58JLV5P)Zh(,!r$ZC33JD80ppXrKrV['F[C`3J(ae$aE'C*
+1FVC`3J(ae$[Q-NNjbYR"#!I(6iCZm,6cEdl68Ccfi+'RDffr$8'&hK-RbJJ60Ip
+(Y5S"0ZrQKeQLBB,5fHK1-(Sp-B8'p*&mmbeCdhh,Brq#Hf)ScB3XX*LYJ60`eG,
+6E16piqL@*h#Vb-IDi5f'9CceT@KDGj*BABY91jfA44PB[m&Vc`i*LP0pbH3Z+Mj
+L-4EP%Q(JX)TCBJ!`CC1mYeU(jjajSKBf+AbriAY[pTKl3FP4$ET"%HG,V@YRmrh
+I-rer"YY3IJdjILK+i&QLVK3cIj15Neh`J1Rqe`d6KE3Lm(ZRGr`M8FdDZ(`5mqJ
+&i@6jf#,aaqX-'ir$L-iI`"Cd6-8$G*YQN!"$rf'&*K0cZah1`*IXhUSRAc,&miF
+4R$q!,1LCLJET0XdJKrp$#N`QjhBlRB%[fEe86U%("miF4R$q!,1LCLJET0XdJKr
+q'&*K0cZah1`*IXhUSR2M[B')*paN))mZ@+pB+CaU)bU'@UZQ6NTTmLUi3i*@[Md
+0HM$F%j2ALYmPD&q-NNUYFG)Xff!Ue@SE'Y!E#pG1)+'9)M!"*2T*f#c265%cH##
+9)dX1N!!&(QeXLq16*4ehq[YI-A$-MqT11h+9'K4aq"3Gf5&m![I#V"FDdhQf3k%
++4`2mYN"1U(GNbrhi-%MSCmilNU16@X8"33$VB*2##8Z2G9mE-SGZL'N#&M1Z[+3
+CL4Q$KUk0Q81h4$5"#aRAAP(%)TGNZVSfC3lG%0)%,'GGH15U4mK-R[mGjL2Ce(,
+M,L)C6$VDTEV8qRlRIiU8#J0$(5HEGG2T9%"Uf!+`9(RRTbH64+[McSQKJNG99!!
+6p8PpM86Q1JMcAq*"19GJi,@E[T3H8r5FS5'cYJlT+6A6a0!2V[+"0ECTd*HD0d2
+j8YY8phM2JLZURHTqiiAVi3NPH-I*UCj*#l'0[DGB1MqV-"pJ$+4f)+[YGkrBb'`
+mZi#Fjck9R0&8jNDB"QRA'lY!0rprRIMdjDQ-b2*UBN1b[0@3!0A&A(aSNU$FkXY
+#L(1pSN%m)@d+DKA+F9E*a1NBk@EjhY%JRK#fK68+i3H$*a1NBk@EjhY%JRK#fK6
+6l2B$bYN'+HJHdF`6a1LF"dQ&+ADHi45`G'-H5DlU!+1CI-dpA,I3@6kJ*`b"fd#
+`HXMhHX`&hM*eI@C"#afrdr($h[NE5QDaaD@ciaML`FGf9+a'!HLDqdkdRc5ZHj+
+N180-XIALPRqfqb5K$P$6,(eiSI)fqb5K$P$6,(eiIbaF$(L9B""H#Yb6$Z28T4d
+CcR@YHRmbaXba(Vl`kd)RRBd96'+bYVi9`h`15G+G*@a$bee9H9[89(!E2E8@0Rm
+$L)N#NU(91VM0'$bL"6YldNQf[rpNQ!)-'9Ufk(`edEe%2ZKTb[B+fRZ'R*3K,8h
+2*-r8YeK0G&Md#Z,M3[NVl4+R65S5L#Zc!5%P"0Ic&F881`%lejL6[aMca99PHj!
+!Z[!-mYkb`pJX%4,1qSBUB1b4i*6Nh8@Z-Q3rfA`YVX`&5CQL"E[T[PPGNkRepVB
+mm'U$+EZI%UZ'A&S!$#`IXbEM!@lkEjCAC1TpIDf22"UJbQlRa+VKKE6U)XX(l-Q
+i`&ZqQq@9f6UIAfYMc`DS-TZjm5UiAi3Le$B[N!"q@d@CGR#(91NpYm,m!+0R@,E
+Fb$&!%3%A*eEUY1dE%N+IkQ-HAe[Ii@r3JZP61+daTYFpfYA!"DpS5r`jq"jSa9"
+p4IUl0G"Pm&UkMF"c$4A&U`RV!e[Z0U,Hfa0YKC!!UbNHa@%3m'Q82NA)ZAh(jhY
+K1P*ClM"Ui1+RK'M%(%Di31&F2Z%mAB&(J"NH5+k42"(EBp1iA!f2G@+a,3(J"NH
+5+k42"(EBp1h6iNpeBV%Y!H!'4j)VT%m%GYMdki&0!`@3!#H(T%'f9j[88YcJ!+R
+L&S&U6d)ip5TP&+[b&fel5Q*94fk5jj%Ti%5&"85Efj6#LF03e`R#aH@KS+M8DJ+
+6NJP8H'3%H6*kQ0lFD-9SiKCB-6VPCkXhl%YjFrJk+)a1!lDM*H-'8$ZT(3IJ[ke
+$BLK"b[B'e3f+rb@BbfacC+'RmH+I!)99!9EI%NrpXYQi10R`F,%NE![Qd`6#RC!
+!dmQRYPXh"aXq$KBNMB&mfQ#06iITj02E,CZ$MCm(#a*'`,jY,h32iZY[Xq-UjjK
+ar*[HYl3df[RBdXke#j5qMpf'c,`@[$a,UT9jQ%Q)MdT!IcR&F#NkaaiMRHH"466
+S#6509-[J80p8pkj[-h4GPRbV%Rp32P&*PaCI09q#R$ZX9mJ%&"a1Kq6lQacUQK!
+49[pVbLqV)H#!&'9T'E'6pe*'CTKNUfi4"NVF*2EXY50Kc8DrTdq&qq-BXI@4)A8
+kfFYe04I,Ck2%m8eRm@X2QB$[AB!9pAC-iXA64(KjeL'h3[1KhK0$U"p3%SKk3CP
+Rdf-UbTP5ll15qfDTfpErIqSJ(Jh5$Da2R-)eZe8k21eN(8kXDX%Ak[)(Ml"Y2Xj
+VIL@6r4$bR)8qf(fd(Jc9HXc,X&JpcT)&kYM-jik@6r4$bR)8qf(fd(Jc9HXc,X&
+JpcRqQ+f-cRMTC2mL(P13!+IE$lD$`CU[@CPf#`HiISYfd1c!-#9lV-@fhE-Y*[p
+V5'0LJ99el&D)ip@)+kjZYTamlBU6e4@-iUf$#0L#ArM)QfBDZflUbebelj9Rr%E
+c`SB3UJ(cf)@9Gpj*4ZGB5*3J$pjYI"UD*qH8jMLCNEPYS6)dLc#I,frp"D(@*eN
+BZjF[k2(e5M%",-,UA8Q0e#(2QNfI*DKb$B*m3,`bEp6Q,rJ*UErkbEaKm!#DM'`
+5E$YI#9lX$5YZ(iM#r"dcUr*eZ9hfLr*qr@kYYIpZ"eThS@kQCeINkh+ll4INrIV
+G@f[r@r&PAS@kQCeINkh+ll4INrIVG@f[rYrh6"j)IS(llf!,j,CUddIJ!eVIjG*
+XbNZ+Y9r*RAae+b'I2I9IKmp*LGYVJcYd3VVIL+%ZZ8ZQ`44f,ri!@kBG@3)Njc4
+QMT,1X0S'Kc2`pdq$6iKr&&cP&[""NQq3!&p$PC3G!d$f8AFU$ppF-rmk1*@QG-J
+KHTHI2+L`GISc9,Ar6rHrV#F#Grpp`X@S+00a&dQfX2$Xcf[%X[mqSJH@25%IS8"
+Tdm"r[U)(PMdK(jXT[iC,rI832,(T#1qTbIhSq)B)rDG)E$'0,He6q55UCep(SCU
+lQC`l,G`T*9,%e3B5!hML1$P3Rq`$PAXi3'$bZ$V)YF)fE,(ilYEV4%2F&5hJ%1"
+0YNSYIH!("SkTP0$Jm@Cdc*2fEY*TlEN!(!iL"+HT[DABS"5[McVYe2R`-`pI@!,
+,C8$YT[dp-BUJUNB@iV-[Qj[E1[Ae+E[A%[[r)ree(`pc9RTm3[4)a62Q,0T-V(p
+r8R1IrhrqA4IBJCK,83C9CjeSrLXRqL1&2J%ZSFii5VbQ+A8ZRd1abDJ5jFh$LEk
+Qc#9H8a5kPdqKf10'+hFh$LEkQc#9H8a5kPdqKf%pHR([PX9iIFcU!(ccCi+Lq8*
+cFSC,h4Dm2ipAdH`6mP2U`04R1"J6F0mC9fD+5#2$!Ip4N!$UJNYUJ4#pf(d3dT3
+c,TCVTqX*AMJl5Ae%E#+Y4$jeb$+p1MXY2S'TcAaiYjPrN4%Z5A8K,*jmBmVeF1%
+eHhFP60Ja0Zbk&5j$ABIHlbEP9ddkSfc)aKi!YMFfR"0LH!bB*jqSP`4!klLV6G9
+[14e%4q6rM(&Kfb#PMA&QmPh4qJe2)EULbX@bPGi&[jmSeJ$kND(NHrprrLXA%YT
+AVUM"H%F$&SM+3b0D1Nm-q*K6V`16AaY9B2J)BC0CDIX6A4eK5@Dd1a@(JFQ[MDU
+`I!3`bDbdrBQZMV#NXe9X8`m$NemE9@$i#''6@@Rl%edGB8PMlrS#E6Z)BUEfkA8
+QlZ9VAbB%dp2ET81&(j8MkV'qN!#dj6ppVLae9jcT6!MlCSGNVAAkBG0+3`KihfZ
+'N!#C([QPeADZ(P,8UCHG@@AB2B5NTKk-U,L#8@jDih2lFfT'HjT(#,!+Ei9h5c,
+qGb(NV%e'6lU!2PUpJipR#1e'G,N[2Ni'LSUMS2GdG0,N[2Ni'LSU6cRh4ddZ5mq
+6JD+KPL0ac+p6K2j6lbbZ4DGYaj'!%kf`hl82V[E(hB'KP+P'`[28cTPRTjYm!`k
+Q9SL6KV%A`1Q@kl'@!8Q0UdaKlI1hBCPK!iGB@UQYd[4@B9,A)SICeUh4EiA@5,A
+iJ!R2B@*C`Fpcb[L!SSdcJ2!pG#LNMfQ!`PIm5h+48+)GRAVZFSIeqC'LQN8"H85
+`E4!cJkqq4L@j!`m%[(390(j5M0aqTTa0Q2Yk68Z`LM5arL83K6-$XE8GehJEqcE
+J0Pf8,49$ABCGPm'pJdCMIr"Jh@jDVLBZ'J[RHMj#E)N2D&SGFClq8Ar1*9m*1X5
+eA%aF0"I1p(b%f4)Hd,3kif2S(086ZcU2@*DVLD-[$pq`FS[i`0S@KeZ#l#m1GEG
+!Gaq4L[M5&B+jeVfI8SNApl0JCQ1mB1(KR-aQDBG8Hf)N!9DJ-0SmXbUVkLQJ&$U
+94#YDi8r&qRU(l-Q(2S3JU)fiAMP'-ePmXZ(r6i6mmZF(B6+fm('ZU61(9rE"XVX
+G1DF,,%SiTGN1`@iI(PbiUZHL[Gp`J%M&C8h,%U8)$`2I`N-&$fE-491Jq158'dX
+qPJGr#3`82CXa&8k$ij*+a+2TB(P-BL+HcCL+Td(ab0hbN!"F)JjR%kb5fHN@cjU
+'hfi8M*!!6XZNFRf@IFLeKfJ#j`NE3)NBD%I9"eMUX0pm9H'qNNdbPL*r41%3bV-
+#4'[jU[f(P$P*SeAC*(0"66jjY$,QN!"@fYrG8Y"qB2ZCU&BQ&Hp`cYcR*XQ",NT
+TLhmH2r`fMrd5HGPbl'#+`-S4!QFA,0R#L!&Uc34XLX$+%3*R&bcC`SJ"KjRPQJP
+r&Q,G0FXfF-$dK5)KALEDl62*%i8,20lYFE1m$0PPUTk`)j16PITjR4('-q6Vdb1
+A,C22abSkH*l5JVk6hFMUYBAT&!'*h1DD#D$3F4Ch8cQM[fE4*1ep[BBYH'%6B50
+[d8TPD9R)-r#d2`TEp+3cI$qZTRF#e*qJ4Se'i6A8NVi&$Haad,NTT5(r(5q)1jm
+DFN($jb5bXKX9`-ZkUQi+m!+l5k*@dR&f6R1hJiG@Z+%,c[Ip2+(l5ZIrD-!CIrp
+rCG+DSUdm"cj*j[)qk6!XASIMUBTc%kpq+!E9Sm-U1h,eep8eY8#+Fa1[ILJ'eD2
+$+MYbpGI909Tc)-a1[ILJ'eD2$+MYbpGI9(r@8HeF6"1RHC9p2%DY`H*"KcPPrJY
+HJRQ#Sd`,!($$m$F3G,E!-+jLM5Lll26fZ'H*M9b&B&FCIFQd$*k"2+&#,fd5Ck-
+2qf$05d)%(+)bGX!1$ck9K3h-TelYJ#ZLQiX,LiV[h2ZQpF[a[V0'$DBpD+QDUjL
+L)KbGP-a"r(c)hMQQf+Ap4iG)%+'M+RY"bMF@F("NqhcrIB'YI%MNcN++855+k*l
+`hDBrjaJ[i)klFX9rpRX#CZMmBpq94EYa1B)klFX9rfcf"-h4q-Hr+SF++F`4efj
+BVrl2B%cG(ialmTr-Z9,dei*JBAGH@XFhQc9J,F&`Q"D-Vbj'U4LLVlJYFmNHS+A
+&*kSaGS`',qh"TmKK-dGHMFK"CY)PR'JKkTe2bArS5c&QdX4!3*)9iNHiZ![-3qh
+9SfiBDI6Q&hA&F4TBMPX'G%H`*Yr%L@hjNIBJ*b0r1Imr3@XVSQ-C(AYCCT@qZ@q
+T(I3Q2'"-iMP"'ql)9k+(Il!YLUd4Kk`+hM)@)A-S4MZLQhrr)K2M,cpG[MUH8K9
+@*2934&1Mq'm(9Uj,,BE0H5lY1NPc+T+,rhGBch$%MK)$60Bej,Zdk5A-UNS[ree
+556L4`P4,[fV6RKp*,Q958Arp[pifd&`N#i)+866P2U-"**Y%Hij)a%XjbXU9`Eq
+X3`H'e!"T1ha+TeJrHB@aN5b-I!9%3pQ4a3H4LXQJV-HH+k2mrh0`(LNN13hQHh@
+DXH3M$'c0CkaeQ!6$'c'fj1X`#BBepp![SKRUJe$0#6K)ISPEFMBpXMI)i%jkZca
+SpIdcXMF)0XdE(E!RSQefe$Y'364@,U(6Km4PA)J,(DK+N!$AMC`0RLQbc(KRd!A
+!pLSRG55DKH05pJ(!B61m2QBBPLhieKXL-Db,R8UAQMr2QTMp,kZ*Tl)"VI-pk,2
+!`+E!dhaj+l5!F&lPR`Q!#q8DKYRZ"p*P%Y%m19jqUm5NJ5Se@6UdFFUMT,mT)%U
+09NkS"Y9(5Aj53*8DV*Ieri(d4*X)JrL6LA9RX$URrbqlHm-*NrjD5e[HKh(#MCj
+QX`l`*)4"(L'mQ4b!T"VQ0'dXH0DIZ"McVSJ9,XX+5SXZ5GTk$h#[b)"hi&YF31L
+L5ZqkX66N#b%rf*me04#J,rprrbaQkAef8#Xa&KRaj+D81AFV)U5["#%XLSFZj@4
+8PGm1)X1a1lPC&59[pHd@SjI8CUriaL`r3Zld8e$f*5U@88c2U+lRZ01@I3kTl2P
+8LX#dR"FmVKUVA)T9LP524,C3,%G'6F[r2$![Vj0RYTd+*YU1,V"@SfAj[L94M8L
+pr&[XVBU'mH5Ebl(,)6*16XKFcRlm0R@FfBFHSZcE9*!!bqqK0LD4KPq%AjTY"pI
+GqX3IK&mBh!q[Zr@)2`KrmF%D[ilL0%d91`16U,[eDkeG(jreHq'))mLb&LRa(PR
+C$99m3k`4YD$$FH5M5&%e69D,QX2"23qhK9(kr`mQr1klJKNJ'%A!DjID5IAST!b
+8mqUhF`AP4QF5GMb5JYqCdU!%PVm6Q-Sj[X2$c(eViYp@FEfIcUX%d"GRfIfV*Sp
+h2mf&`8PMiELB5)2`9CHSG4PKNN6Q3*Rja@U$XTf)T-h5eEqj!9H8+ZX@pqTR"J0
+&IB514i*2e`R!UBAIdm,3crPr3p94f1Hh&CU#!FKBe&2'Q(LlT)'mLm`&(CBefaK
+V*0#-U(daj9I"JF48)V8`T*K6iE-9,J#0+Y@VJ!p&41h-RY!0ZPD0hfhVJQ&2KXa
+8Z!)dUeDZ!$d9%lFbHR5'*@MGpYmEpD04Ra8Z!)dUeDZ!$d9%lFbGlj-P2-(),V5
+N3@3(6Y[3TDe)Pkmf0e!XT668iF,F8P`k-+drJ"GB@3HP11V5*l,FS')D(R0!"Je
+GPM!85Xp93lRrA*5a6f(jqB&I*'Ce'c[PlDcYTm6bI5pLV+&XRPVEX#rIerLl"qp
+"IQCb5p+TAA4IBff@Up#dbCYRH+5IDi99i0%"r@mU,4`[mKK*M#3&(4Ga`RcMfB3
+iP62k$ECf"-GfKa6G3I3rT+KqKcM`CqA'kh*@hQdm0JFAB0j"A54dG!M`CqA'kh*
+@hQdm0JFAB0j"A4VTk"(JcmZ0eZ5Y[0TiE!iZ`Eb#Yr%jQ[X"&Y21j4V"m*qrFPi
++C)Q5`4bJ#$"b1Vb-cS9X)LBP4!6""2&%rD[1,A)&$m!RP"NI5h[j@0Kf$Qk*T9-
+DfQM[ZVUR'),@AjiN-'#J"rTc"J@eh&X[a05YV)rf%N5J1F+U!i$NpbCBpS$C,*I
+(Ip2D(K-C,,RIqV)lc,D-[1JI,d6Hmacr-1r5DrhhVq[McRJIaCBqlE%1a@3KbRX
+8f@HU)!LYUN*qPr"PcA*)5N1$6AVM8DEDd`T&D3pBQ02TTiP9jImZD`"*E300HZ0
+4TYV6#N9T$eLBdqQRL5,9r29e3#N1$6D&$h)E@Q)piiiHBdqQRKriBUfi[+lNX,-
+J8Ye@dK(jdLV9"G&k)JE2U51$UlfG&KZ`95Yce%bV%fRLKUa3m%%dbd4RAN,d+[B
+lB&e"CV(IN!#(6Z3!-%ZTK[4)j,UM5-#X5$!rAa"H!YHci`!!P#40i,EP&9MqVmQ
+lB'+*BK`a&MDN2CF(re$T2'Zr8*ap65$+C,`)j'838C8NrMkQif'8iX)k[4`P8M9
+H1e3l*4"ahGSFkAa2fmK-qKQRNQV$5cYS4S6A4%j)+GDM6Ceq%hme@IIiXMN&m$J
+PpSL,Tm@@X-JU@d*Z,2R-R$,5k0b4Hkj%MpqKp100&RSaY@PZHThja90N[Le5GG&
+elVN52hk(didd@HM'eD@jkRIR&6hETY8RA4GHkj%YdI-38+A0G4RDcfM&4M1+iGL
+8IMY[@XkZr9dBVKd*TBd$-8daCf[6D%!PAN2QSKK')UDT("-ZQfH0TamXSRF`5@d
+!X'rRhLp"Zl&ZF#bj6U(S&,hd"`c1Y)@V)kRH1L&r5dC&f!`6GaMp9QJhd('d5[N
+Y$U"j(qUeE%P*HZEV6+1V$,[li`JBPZd`PN,,810c[&GF0r8f)lZp,DYSqZKLrfD
+Pd'#SVjV&3bZ3!19b)$2D%dRjK'%8N!!aLAAHX2,!"irAFDVHTlX05%`9NGiB6hP
+"$h2qaLAJ$6q'+AU`M@T6%Z[mQ-RDKilh%,XMMc-BjFq*qhTZP48HQUh[hhffpp$
+IVTFNR1e8mi([YkET89(TUYlpppY[I3hkk@qXFe8mi([YkET8DLM,HrIIEEhd0qY
+rlqH#X6Z-cU(I4bqkH`[JBQ5%'ZaQAlURCJ#*'ae,-ej`Rq$N*XERH1fq,JkAPh5
+XNYHU4Qp-1`@)1YG11mUMR,q'Ad2CLl2hlkcCSaK@%j)mS'XMU$RA$!&B),dl`6(
+ES&*2*b"@##p1m%afj'!Q6N#X%&kGi*MYZ50j13+`3AThJQ1fPmr*b"@##p1m%ab
+DU*r3"NfiN!#a4Z0b+[Ar5hjJ,j2925R4bN*h3GRJ+eNTjKDc0b'Dp@mQT"$),[2
+E8BAAYe2jFRr"Cai"FPErEd8HY!BHlHYP62Gqh+Qde3U8FLDf"Gfa@@RjJe#,F6P
+q$aG[N!$d8G!()9LhQ`pFD*Idme+4BA'A$DbCUFkBKkPV%(r3Z,mjjq)8bT%Q[rm
+DHCA1*DL"5[$d"R$6MlY55PNLSNeLX[#Clp(FL)eL`Ld)"UZ5ZAc18#m*Fi62ISl
+N4'X@%@K!09b9bqCZfKNZF*R[dGb)M@,#,3J'Uj+jI-d*T%ZF*R[dGb)M@,#,3J'
+Uj+jI,j--%-%1F(f3!10Qf1YRd02G[maUJNZrm(b[fBlbZaQ4IafBAbK!!#Umr!k
+j1dHhIfSPFaPEaUeh086ERrlL2qpi6[Y%L)JlX(Lj&Ipql-S"&@GeB9+'#bD$*+F
+%F!3L&#J12YK1C`"#)8)h&EB6QF!3L&"`R&X*c1!)4#IGmJpke0aG6[1DM"%e%qM
+1q3FH)eS2bm-(2T6iGNZFH9-fIJ(M-mPcdTUe1JKH*hP&Fp4c-LYp$G(k#G52+k6
+!*$X!@eVS3re&R"5YMr!Bc&1[mXlMP$rm!-l(),(+bV5X[pDGF*(be4b-VdY#YhD
+-!#&[fENrh%9k@K@lY'!!IKih*rZ)VdY#YhD,rhNJ4Z6r1)VdY#YhD,q&8,Ud6+'
+l(8`[Lb@&a8fBN!"iMLP82&3BjPeUBPrP'NbLIc#UL`3(9QR[YU)RL@Ib0bpEp1c
+@k[XXJIkf(HbSd2TZr"Y&VlbQi2[hR!iRY@(PHZ2JE-jNdm3HB#pHHSHeH$60ba-
+LV%TTK4j5S8D3!%qCCKNEE$rrIrp&$N%9m@P,dI@Xda[`c)UIrhpBi5cUkiQmY9-
+E4i"22V!N3NK+rNFH@UQ0Sm!RRe9"C'2VVLEbe8aY(J%mqQCmM(eea0jDUBfM`#H
+I38@M(eea0jDUBfM`#HHreTZS6*flZ#J`eRKkE$RVBT,cj6@+PP)3K)r0%i#%-U2
+H4FQrT@4I@A,Q%UFEjD1K(iP2E%#6Vl-I+JmcZe$[N!"!hHdAJ`l&[!ckXTU2[%b
+!cbh89XE"FM$+h6Gk3rprNbd+b5[dr%@ile,lRlT,!lafLMh@FppdPJGil44kpVA
+h5@"hMY&(SYEIG*B(H1d8EpIlCq&5Gl%-8N[3M1KN-r`Gi-Nm9FhiN!$8'b'l"Z$
+`,qJG-CSCPdhA5dV4HQeTJf5(QA8VCCiPV,91PDPL10k8SX5Jh*9J(IkMpmiPTYp
+I8M2&6C!!H#Yl)RGG5klNlLR4-[TU1RA4[CK`TrT8Kq`Aa6A(KDd[cArrIr1BI)b
+a!l3pm(#`AbVb[U)bXr[Af8CHlka%X&APBi9-r[Af8CHlka%X&AP*S@cqpIC4Pl[
+V%5`9H5Y@fIhVl+-[GpBL@#V[hMC2HYN&#dA)kR[%Qf,&`pQ9C5[kh*6$ajPm015
+UC[8kN!"`NJP"8heP6VCP[m3R3mmHRrl#GFaNVYD!hlT'i4Yf)3JQhBCBCEpIfdK
+fp9C3dVH$1-dR*hc,YD@[BSJP5m5k&hl4,Yr%4-[QDqE'diJVA`mldLG*BRTCY`a
+dheT*LcG6%@8KA6cM@RfIHZR'419)3HhdfjrrIrprrh"P3Vj1ER0**0rpd(FiAmb
+43-BKiI86p!me&&"$c0%r320443)5hLIS(QSSRmjfLIS(QSSR`I5fp9C3dVHCr8(
+fRq2V@aM4bcM!M)GMNe@S,J$AdJ46FrJllldS92hiXKpkb@`XBAiY)85M0ZNArbm
+fdDlX9A#K0pc[(H%UP`[#!2mpi+@-e5L["5C1S%UPdG5f#95h`9,eiF$Zl'I`AUG
+2[jG*$[mVT!#R!c9G8dXAR103JiDH"10P$$e#c3X$,(a6$NVJVGc+N!#Zj&Cf!h(
+2`p3f3C2rIr!LEd'XfM$ErbfhP8%K-(X9STT)h+HAZk5-[6ZZk5,Hh2GdMr65d,1
+hqHZ&U54bS4""cRNM0*+86&8h#'Ib1AmaIc#Id@,HJZ5a)l#Cc0'FKjCUdjVFMNE
+IiN*i!K0iN!"DdmJS)DG@ACr)`TlMGqpff,)Q@E,S34+iZ#LL$V#Vim4McBVb%Jb
+[&I6F"41hJSedaSEii3+'R3@N4mM32-R6-JZebC!!l8TPN@!T)Q8!UUSr&&M&@'8
+BB@,6aji*+ZIrGTEdCH`3c4B'k&Kq@L$qUES+RKmA!j'fZjEC*TDFf+r'd2$@h@e
+(mCCYYf@b65djX9q0SH'YPH!rM,0YZbf5D@R0L[aY$`eTI'JFMEAFYXNdY1E&IMD
+(KAkSjaf3!-ej-"I8D3FMT3ICp5eMIi2BhYa(di4hc[ReREa&1LRC9VIm'pr'R!9
+J(q$,1,qT11k8*KL2S"JYm5BB#Re,+KdUC(jNXT!!B9hj4V'KZ2H0`KJUq3PR8T,
+Z1i92rh`&RX2)3kkc2C!!qA(!)VXH6&L!`32rH6pAXThklE!JCN#L((dF&LD`KeC
+ThklE"d*dp4c[mA,f0+U2C6[eff$S6TkMRIiZAX$3&l+GqZf`G#G28Flr#jH[VfR
+FThklE"d*dp4c[mA,[r%iS2ClUb*M3Y')+3f@PIIH,IG2-U[Y8a@!Uh@H4r+ThHE
+'G4i"['(,dS%c9"kLRS",,3b4qL5a5P("Aa-`)Q(pYZPJ@m#,SHTIU[-*L,&a[hP
+SXJPP)EEH'q4R"q*#GpD'i3UHIrprra`hY@4pUV)8p`SASP,qFcbDAjCV9ARf(Ia
+96rZfdq!VlXeUVcl$[iUTpm`jm"AhCV9ARf(Ia96i!9R`&IGQY9HIBGr&9+PK[l9
+RFmF6EHTh&(0lbN`G00U2mLT1hP5BMMLifq4929Sd$FjQciqQ(6Y&4LDUYBVC#X*
+-Ed!FkJ(i+l'VRSl(0Sr2H-AXdjar#1!qI@@2`IpP3kP4iER0AE&U#+d+i&(p$8,
+94$p,&XkKJkddSeeLeDYG[mL"p8Z5UCUVY(CH,PF9rhrrI[pTX@[T%Clik[c`")$
+GkGVYrT1TAMJbaakfeC)P#8@6YmA&89ii-XFHYY@5*3NE@pmA&89ii-XFHYY@5*3
+P$Z9SZ+SVa`CBipEDXN5I2ATb)!LI(3c)kY,#+lr+BUMN1EK8C3JS"%2hd+h`E+G
+q0"#AT"p[c3Ba-rjI(2$Gkl1m5L8bYhii+Q[0%eJHF(5qFEKM8K4i1Q[dM0H*dKN
+UdHa"LeqKX#rM*4`F`+c)NbJ@kT%BLiMNkhMKjB@pp(98P5UU5GGI%,C(r9j8mG$
+NNXVMZi!Z!Q%Zqa,EcpSYPKFE@dIrH92JJ8L$-B9rdij15qcIdZ@'*K'+c4#MKFl
+JEM-cQL`6B0P&4*BB65!%$L@**``0aQCc4B*X'bLSNX-*T!"j`%iA1i'ic-jSX%f
+$C485@'%dJ!e9TiA1i'ic-jSX%f$C485@'%dImckUHrKT([fe[qfT2iDChfflqh3
+lpVI[fhTqfVGqfV2fk[pfh,qfj2fk&IYddj[YU+qh42[YVQqfPriD@hfh0IEIrf$
+2[fhKqfU0qfVrEG52fhGqfjrfk,IYdUir`T5qh3$IYTcpY(Afk$Aff&qffrfV@rE
+BreY"EpY%rYdPrEDRlE)rEFrlG#ca$i$@+ee&+L+b0pTVk8GCQEYCRrc!Ee"NBZf
+G-HSB@h)*'b[@T0TSbSQSSa'HdMP9P#ki$#9chB4q5Mr9'Sc`9f'0`HNJ!iMhYXp
+lrG8eqH-'9eZ*N!$dqJ9KrKKKP5mT'(-8+(3Pl0$4C8q+%LEaNB+BIr5*YD4Um#f
+V"SSfF(PUrR2T0**XbD1rG(KQ2Tk$e62+"ACGCBYqdFB4AjrcVCSHGjZb2kb*1E5
+#RITF6&jP+"rDrN`%U8phiK1jG%(0EeMVVXPHBTEE85F,``Zi!a`XI0bMNP)0Xca
+'cB%Dr2#)&9SpDU51SS1i5('QNXcdRFr[YJ-)kCJKMrD-NTl&Lf&2Ee,'"`'p*22
+%R8NB+KNX6hiJTV4E'0TAlG6JIS3Nm)2RkIlCkpKi"r+e`DIHmpU&lNdD2pc3i$T
+2l!a'X-93+@(qmcG+,lr&,MM@`hLqYcYb%@JJU(b&&#IUlEGEml[*Jrm"55C%Z3d
+cU8T(LPdf"HjeUaBE*-(*rd*JKA`EFbQh+SLeTXMi,Gm#r4rFkZlU6QlfmJ25J%Y
+TkM1Ail[62Y-UECC('8Ci*LJNpk[%$NpjLRSr6a-Chm,L)TqmeV[I2I+k#eZDE*6
+)A)h*fJQdGCa)*c2%0p%E&[l,ImD0BQTcH&"CA!@$MN6q2#FreerE[(rAmI*ZC`N
+Um5ecVcSV"q+HIV1i*+pcpAF[4MZmMmrAN[MfVAQ'+'``,+i*b-C1fVM+1f!"BRk
+aiP@&U@b`'JA-+P(B!lQF*,kifj(ABJp@VQik'HCIbS',a(``ehe#4fZTeG+2d%,
+m1mhAC!I%b5mSTCl'Y"pNM@GpNEFM[2P4Bdm"*CrSESCd2A',(`S)JXrUY"5CT%r
+Ga,kKdfE"E$r'qN5T![&`amhGairc''1MF(2XrXZqZ[[L"mGa$-DJLCR9mm@Th(&
+[TNFLP0k0dZ[UhDPh1698ekH4e+Ck(cef[F'p5R'Y-T6!#451,&QdjiLIPDI)4&`
+rJ!*QCYiaNY#$iccS(#EQIpk'f,3[4#6I58+r8TVk(e0+$P@Aiq)1SXNII0PCVS*
+V2r"(IJMJ5PVS!YY%99McM)a6-P1i8G"6&-QAbX9dpQk`h1TL8@8aXlqL-K5GHSY
+[[`m*VhJ0D)V(r&+P2(V6&hLe0ajH-if@eBZHd!UH"%!EA%H&V!&bRc2r10*Hip0
+'JlFHcH*@N!"H`8$hjDi!9NC22$0Be(ici4TSS)Q04Pe60[M6A#S59P[Sr05Q*AP
+KJX*l,lpESZ%(qiS$KUc3cmmJXhi"YQD5"ae2aQ#'-5-if3X1fGL-UTZUIC!!GF,
+2@lEjX@8cYUfaZbPNXhEDPm5[kF,FNEm1Y3!ZDrmX[5p`&#Ej4NP0lE(dBUrJ'#0
+j[5Abb`M-d[23N!",6!kC5Dc&pKG0Z2T@QVdIH(-**ceL9hqjfjb,(-9*D0h8Jk0
+0VhLG)i)f'%`pC6r)[*!!"mqEpSB0(dQlmZ(RpT!!SF,l-'$H`YSp(MK045U1%#H
+J4LA+jbMPLVDl)"$EASPCa8kjkHN9D8BrKbJ146r+ciCNB0Sr5A+DbEq(qa-,2-#
+hJiIe-&E%i`"XVU`N$Q!#@JZrXBPAHK4e"-$H-XcGL+&R@q8bFkp-$k,Xre6A$Tr
+%49Vk9"L"[jef'2p8PJSJ%6R0(JAhKYVQcmmm'80,kr!()l4Me8DB4@%-$Ba[K4F
+,T#Z#I%Hh-deHq-[XX'&DP!FLK1)`5k8#IU3V*+PA0pP@P2jiRB`cNEM9Nm&,ajV
+,kGq%FjKKj)SM-#I!00X$0l'pip1FkZ00Y@YV9!1bh2&"6'Fc8Ud6F31jC9TiY",
+BFhRN6diS[E[*9q@)iA1IVE8d`K`DECA@XIGkX&h+PcEl-V$dJ3UBQfK*!ckLC3-
+qp!QL-"mkABDY&b*qb,RF[N)D0`XJb3fckq%pD(q8m"XI,#!IMTPSNZ-`T+QPTGp
+SD*E+L'JSL6B2J'NAM1V+D(c9'l*'qq3RS`CYkZRN1SNk-lGI@2(5aI3R00k42Jj
+rD&)Amd*S#A!r00*Se"82IAFQG$9'+Y0ka9k8+"P4hH64+Tm&#Z[YLmX@3&6852i
+6'8(Erd*0659EhlX"X)-+@GI2KkM&!Q)!59pSR0k3!&kK,F)k51d0ideqccZGm2Q
+`bC!!2cqYjbd!CF#0p6-1,)1$`h32R9ScpX#dP,Z)45d&iHb)-c0NZSZS`ATV(LS
+Uc%3#i0iBJ+N-rfEJJi6`Nk-C'h*54mlJLQrA4V5Y)YKeRmM5-jBL00RCU*YI0#[
+)bP1+&32EFpLVSaC"5@r#&mh3Yh[(k@6ak#Ydp-H6IMXPm1j(H1UA$338SGhZk+2
+@PKqHMmj$0+lh&e(XVUehrCNXL+LB4-3`-#5N-PbChJ#K#YkS6l0I'rpH"ZPl6'i
+&VGf3!&4AqajY0[aeU5j*lVI"a$XNfiVYSK4*CMMTG4H[FKhKUV+$q-b"!dMQaZ(
+PN!!CUl*`&&T)%MdXeZ(mCST6qca3"2+9ba!UELH$-Ac-pT+U"T)CA!RfP-)3d)B
+6@1&G438RBH$1j-#@6G9rbX-`+m`9jmmU5Cfj*V6a8LhVdACPLIN9`rB%FrpHHhY
+h&mL5+J5VrIlL&YrDPP0iAP@3!#$iP@Ik-N[N1rA*'pRI!Y+h'rNb(Z6--QeZXJH
+F!UdLp3QU'j!!`"kc#&*Hl,1"S6[-1e*kdc'BEGDKZFmYar9*N93ij,emKK%VbK4
+,`MMr9qTQ-#`5MVQKE&+be'apcba8X[8)*NPrpm%6#[e,3h@E3q!e0j*bfNj'K59
+c-,pL(j1b4"Xk14aJL@9+jpH-a1SBc4cXZ)J[J1K5l,E(cSQLJk+C2)#IJ9HZ0[N
+6-EUT*QHj1,eQEk5qDVV3qmS)))me)B)l4!8PTJ!-8@X*NXXQQc6QmYefbJ0ej`#
+Ljq2,#HIR0*ICF!9a-%+*k*R#'!GajP(D8+`Ibi'%@UA'8$#XbPU,V@+)9jK'jKj
+Ui#%jaBDPklSRZTHr[,LcdSPUe!Jj3T,rIC!!45Q)p#e3flQVB-j896M%N!#5EVL
+iQGphD!$`)')55C-)LAS"H3+ZXF%LUld)F`0Rre@@l`6dE(@U5Xm"A+KEY'i@-0G
+q'9p@(1XhMGl0AfKR"$L0Z,%Qbe(Q69H*6`iV@)[+D0[F'Bml4-`iSC[4fj-(r*r
+&8`qNrB53!!@rq##BCC1M0TXa0jAe5[[jrff3!)dTIlG(TB)!*f4ia#+&)8QHPjb
+(4l)2hdP0Y,cQPKQej9TG!Q"TA0FM(jrF1hT0*kDq-mSlIR%HD3cN[9a22-d1NK`
+)#6(#Gi9qG'pkq@PkM)Yfr5CG(JebdRbG"c&#C8aMkp3Jer[KiZmP+il)BK!RX%N
+qc$$mcTq*H$$FpESKGi6`lD8NK'ML*CZ-!e)M!F*2kiCb&)(Uq+#9a'12l@HK8+Q
+C&8cGU(e+e50f@2mi*'V(8,XTHjJp4f,h-UC'QZ%,34lp,!ikVTq%3Y9h#NH+I9q
+`YQGAjXUiMZ61Dk"cUXcZcqk&8Z`dNY[ZDAcE1r58&+)3E6EY9-arTk[QNkU$%6k
+HA,hDVPMSQXrV&-k8G"m3krkeQMcRXc1,T@2e3`PVMPAX`Qmq!p[lI-Nr0h*DGAT
+k'K1"rfh)EP#Y&H+R`eIfkDM4c-qN3*8UdY+AYMc#Mrpm88Ni0iaV8J21+jY9HLK
+kP,*p`&VEUGe5aq66d+'R(Yeb6T43h"'[Z5q"U[8jdU`+pc0S93SLFQrke9V`8M3
+3K0S34E9H''P"Je[4Pq@A&P`$Pq-K"2Z#`%Q+3*[&*cj4""!`,Dfp#AkC'$HbhF8
+R2T!!8lpG%qc,2MP)2&[PFcT-R,G3cV5SL,bEEi1MCI5LPG#XKRS!c55CY@J6h$I
+!6['("fKmM9hTBC,VcrF)'Z[S4KHKE-AJ9TH+1lFd[KmERV(r-)[5#!+F"JPe4X9
+m9E!N5ZAm")Ij4eqAA@@fHkbN$%[0!5jik"j[+p-CY@N2#pkLm'iHGFF4I"2$rZd
+#,hYPY2)dZURc1KH9!,RT5V[30LU[ANaV-d$(kPfkJb#Nj"Ea92HXQc$&KPB+!N3
+E#IbqJkmiC9'A,1U9R0H3!,ZLHY"G%M![dk$QkRlEbVKrCdpFYc26,"1,XR8diZ1
+p1lb#0bAFHFYUk0Q`923#(bFYDrIi18pBlkLXlCkrJVlhYmQUdcH#R#)1ED)8+XY
+cMI`[J'#B+CRX"YclCML1HGDqfjJMYhrf#B!@(lqMHHr+!UDREZa4bHark',9,-)
+0,c4)b(!ISCYI88A-LC!!*-)3E2La-X,3RT!!DpZB4UERipb"V*e$+'M3@$K!G2F
+5f1IpGmY(hEk!m'ZV4IU58i@p0b)INmhYMK85%(qB,&++qHPq-%`BJ+Pl*AYEeaF
+c-Pp9PXRRpa!YmkhB[B3TZ8Trr`#f"8,R*DUCqK`%MM[CaF!A)0CNY!#'HV3)1%%
+6AiR%UQPP)3i69Gl!@Jl10NJ(-dN(64ehVriGcJB'TqSCQRj9i&@H#55R59G8CH+
+2QRdQQ2hNA+8RbGf(SHXmpA"ailc"hi2h,d-2"4%rM+bJZ4li16''5DPa3,8!ikZ
+6R9eFIqUBTfTSi@0i"mYH2$dZq4AQ@prfXqSMYeTHGZk3!)Gp`0r+DU+5@$MlGBQ
+#6hLfF4mC2J9Ie`f9@33eVR)b0'KbC'FZNf&Uiebr9@m!ae[D5d`5!9a+pmYUbML
+qTXAX*ik!Kj!!@(4V0R&B!&`M"6AD0iTHVE(+S')+[(LPA9YC%1HRrGpM1%)G21k
+L[dbYb1mDNHPB!Vl!IT94+rCkZISRY`,dMa(U6IM&qV+B6pNIr[pV62I[DQB@H`&
+,&q@qN6Z$"bHl'4%kI'bphD@'H6'BcQU!M6b$(2ADFPFY#j`2URi"E@"N(5p,QE!
+Z8(!CR94hZZE2rI'2ebYV&TA+",pcRr)K936Q@G9(63dYi&MFA@C#d4-d`)epKf3
+a2SSVd&e`KCPL,cC*$D'+EmR)*pBhi1Pllc+@a1eAMDU`-rG-i&p%U6V%+T!!Tk8
+e3A[-Ud*'h%QLX`*V32G1i"J8EfjH4A&@kKF%Q'cekpPbAM8!3[8S+!6c&)h+rda
+6pY!&[,RLa6lQ65!m+r'TUZ!mdCDQ80r*Gc9qj3B`!H9%m3$&-lVJakZ@)lf`KDR
+2b*(&bchZaJ1X2kGFdhHT*Vc!UC+'d)%cV8SF!FKA4B+CNdXpT6[JHZ,`A8U`"iZ
+"E!3cP)$eGpSM+&PJDfJI04Ui`(pi+JCY2J[qeSa0b@G+5+#,33P"P-l[Qc)@f4e
+ZFa83BI-Y4$[Z)QL'$1e)3[$0T-H,LVCej0YPYU+['6F'q(H+,9PHiqemraYYTF&
+!kTpYc46@0XRem#*j6Q'ZmCNDJeaPB#5$6VHdX)fr5@"Mbl6QS2QNlF'G&3%ce@h
+m3ef%,A[9m,,jRme)ReaMmB-J$S*miEdedTBDH"Z(XV42*T@BC21BJ+4U$rdkFpU
+qPimK8T&aQJJGhr8eHm"L)+)1kAF@$GlSXEjhqiVT"6diMAIef@E*#M**ri%(b&h
+8Ae4k)FBUI!dF6c4GbRE26%#*5He3m0!11R%2VZ&X3m3Vd%4&bZEDaea8Q`GX*&V
+meH6+*@5P$CER`cUXcD"4B1cmAkLRe3$JU)q,(!PpZcJ'[,YSVR233AXEViC-S'J
+I+N-N2l895$ff)6D5RJ,U[ccfLYjT`(jEp%UCSpDSN!$r",5UYM%rK8IJ(+1QjX2
+e98ebX"'p4)KeZX1)8NbZQacPD3$V0q2"JM6D8&!Ap2+HcrcKc)ae%*1!,S!#2iR
+VAJ0lkeiCQCi!SD+N`5kfq4UCm5X2'$05@$BMH)e-04r'md8Kd2RdNJC#ip5V#*N
+MF*CD%CS)f2@BQPfVQVjjY,FZ8E+l-9CiXRCP&c!CJa@ra(`HEFb2adi%SDC`08[
+Pcf'XTXN"8`TefdJYbdPhQTc&ceH`MhB#DQYKrhrUCJPh1R8ZjTlBT022LdUl&A$
+iBreG04f-E"SpE9F@cS99%@,0fN8rENqMYl0NUeI8c*SN@q&dXR*S*HdKC6G'-G8
+e$R8d+4DDXprrCZXS0i+ZI$c$EVFpM11Tk%U*$5qf`Qd&LcADBIUS'L*04YrUmS,
+ANJDqBTZA[S&%dl+Q2&Z9%P'"9hM$[[505"S0)I8d,SB+T5`,YRrV+bfQJ@r0J3e
+TqH4acFV-c82E*S@SYEbRkBYX+LDMXF+Mq5EVM!amlj4EDN*q4cJ6B2lm$UYq2B*
+6D&m,c,m+FNXVS+)285D@%MI"X!m581Q&rc!mQCf*Z8q40Y)T`+Z,Kr*J'!E66+"
+iaN*59V'1K231`8$Vb1@GmMkUEI-NCJp0XEbBDr9`1CfBH"lr0MYNihFrf3cFP2e
+BYBPadjTEbTC5JhV&lFT(ZBi#-!*GU1"rciq&"9-!$jq#$95AeUr!JlG`jC,[V8M
+3Ce(0N4B3H*`ieMBH4l)VUaP2d[Rr32bkhbD[S5P&GeN"0(GD@mK4RDN6,p9r[Z#
+lDeidp!k,mJBAh+$0r9e'jSMkIJ*aSLCI3m---5G2(8'Zq"&G(Mc%$)%)BDQM94,
+j&NS3E%SU&4'ZCJYrq(Rb,&3(`jPerbhCeU[Q5"4PHQXqdih5Lq+X1PTI1ETpS22
+6@Q4J-3Y2+ES9)reZK!MAViJTTbB!3IK%J"`c&9HPh'c9bE)l[a,J#1IcYlhUc1"
+81-TD,ES"fG+bDhfJ4$VCjHjrfk!@8M!kGRRGk64YM4i@HGbYBa-8%p4h!JU6LJ8
+SNr0@%hEDTe6$GNUVfFSZM2XhlDhhqHfZepkK`jZkZId2L+PNEMFPGSXQ1#j)K8i
+iahm36E8ra8d1SR'V9GqqEhV,JeURiK,&f"m*V2Vmf#M(qYR`Kf-$8r(&'Z*+2S'
+fh3,MS"lZXf,`U)K3e*,!iYb&IpPQ&(eBKAJj45HhM&2Y**5j#fSAZl6dJe)D%*e
+ApC!!YKaJZCFA'B#%AZG`khpP[TcL6@ER22F`M$1GGiY65B8@1ADAP'3JZ$+U4Tk
+Il33pB1mHP`4U030k5E@mjDfK(NXIe2N(e@j&beVF[kMFkJmCHq(8@D2'0aHaM1S
+VPM%K%J'Ei'qV38RqhGdqVM3K@[M)L$4eILjl2-ciK0KS!p5$+k63'c!p0jARbQA
+6k'KA"4L@IrFUFc5pTEmFQc$2i!XdM(m&XQ4a)CC-K(E0hH)$)!e9L#j&qd9ZMGZ
+@31BcSC9ecqm8Mf+r53,*MpCH2&"cVAZUAL[%)kSEAfhR$6V'6EI+A*ENUC1X2Rj
+')GeX!I5#+$LBT(m)SJ4lHYFIPI[V6jKQUqEDBI[&Y%cf&#lKPMJ-d6i1&bPrHPQ
+"k85"e(a!Lb&NIZiX6m9mA1pi"p13!,-"&8f2idQN5EkHDBQiDCfX-,$[H9AmAr&
+cCU,(+'@'c@!QFFE+9DJEDeELU1JCRP-fE[5Z4G%kHZ09VLZ"e`AFjXbIrQ3UDEq
+bA+b82iqm(j,h&2TE$ZVm#5LlPqG)4DHNBCQFK-eeL",`$*'pp$4$*Ch4&XbAmSa
+iJG+4k*1XU`)!L2J1D!QZrU&)8Vd%Bp&f6-NqJe)Rj$5G+[krA0pdm5k%K[jp2I'
+XIpNc9hR"eF`&Xf59ZGh[C+1)C1kdLrf(!MZ8'5Z*q,KXCacK2X3UB$mPA-QRYZf
+lrNl*&qIdK"i2S%R8Uq%KUiK5MI)QCbGRTjD4c"K(iXrh"eBa&ecmp,`U(MTJbT!
+!N!!Yr'Y#&+*5@,+k&j[4q!rfZ1`e8p1U2Ymdk!L["#Qk&TE@c+#@NN&'6pc!BpP
+66cD!ek3qGDNYm[F!U6iZX4CU,``il@C!I+(!a2B0$IRJL*USf5)j*,B31J!bb)h
+aM0RB%Zb'$%pq[rRM"8L'im%(TkJ0f0JZU$VB(iclG&DM)p)em)GF&5kH8Ef[X!i
+!P*m$+aTA2ZK+iZrl%jLqU%rbeR&KYQNP$)qmLDbDIVLK'+$*Ij(bYeXlQJ@q53f
+aI2G5FCd%J`ZIXMqK")'#BG6P'kpaBhXH)8afQ-XD21L"UjIJEYrB5edH*TPe'qA
+0SJi`"K'rb8bYkP@MR)YRV8)KCGcaiCYQJmr[%8i4[m-`mf-$J)pKXVUSBj[3U`f
+"HHEQX)!YFIAEjLG&[NJLdREVT0'8lqMC$2'6EmG$SR@3!#EBPN"$NqJqNa#D!Yb
+ZJS&[N!#9%4468MiYUX!L)%je'q*V)c,JPlkhi9S$0a-&DFmH62pCU3"8qa0q%%%
+85%%X4H0XJHDJ''J(rfi[NqS-j6[09BBFkZcC2mpBR'pPiS54Vp9rJp8B[eX(J(X
+h5'"*%cMhqmQ6l!TA5@IJ,`e8K#hV@*iaipqmTMYd6rhp5X,!4SS*H,BDX4h&%P,
+L6(pNiCdqF,I"&iAQPpaS"kF)ehZhr")(drCK6ECX))EV`br%-T(d&*@Y83jCiV+
+4l%UMLG!**3h`IB'rr5Q3!$lqAe9*HZ3382d#e2T%cLiK&bS2F#rpi9pQ+Q!Q#U*
+&Ra13!'PlURd&9$Mq#4@mYK!R0,c%BY'f)2,b!%IiQSI,D'!!EeHJMD",TClf@l9
+dE#Zcb1hDBYl1#B4[P)9#'pl9`(%2Hj9Jc6erQ4[X8SdN(D(YMr9JEk1L(S-E0HG
+JG[mh,c#2cl++VB%5JQPVbA(TY1q(qmMaH"r-#'kGe$!lPBU+fjHe+NHB)A%GG%+
+Dm4'3!-dpX%k@-4JImmB,*Jk4YHTq(+94kd*BX'$ZHX@`Y"`ReB'8k[@b6*!!RP#
+Y9l(j59lik'R09BPKHp[e8I1Xi"%CZB9X"NbY+bpR!`If,FPVMC6KqpRE+c*U,D'
+cRS)$lFaLrae$RSd8e!@L[*I4e9R&r1I9LJNHANcd-Cbk2LAYkKUA!HlU6L3BlXf
+FDj!![42cN6md060fNCK-&AaP9Tf@AaZj1!,-$CCSR-91fG%qKCRHAfXqNIZHH)T
+CCaAAJT9AU(UpdRFc40$"S8cPi3c6"U%*fUH3!,UImAV0D[dN[)@"9bN,Yb6iUmK
+Sh3+NEDCrmp*JLciHk3$'L8+NjaH#C+f4&c["cFGI#V''Hr@PMe2c)%HKZ-c&N93
+rZ6[B4FkPD#F0Uh(XA)'ZGI'FNSM6SMANJmHAGP,8[L53!1I8hl8Ljq4,$DbQZ1I
+4rdD"I#ZK1k2QZkGl0aE,NQlErc,L3YMTqBZh4aTFB$5d8D3bj9UF&F8+bCYkh8,
+VkSUQFB9SAVeK#Vj0LX1ASe#q6BcR3""1eNFL&A9X@k5F*Ba5*Apq,G9%FZk`,fj
+,Zm-[eVS0qMd'PVX#cZQaP*Qi)0aEBrcU@Zja%HI,YL!&bhA8mEkN3@S0%mK3hq%
+T3%'!#M`2bPklV)M*G4H%DC%YcXPF!*SXl0EUh5YR3BYqkLKJBbjX(#P!@Y1'k*E
+qIS1eQlAqCdU&ZIYGYKcprKibK&YUdC4eCMI+DVh9I4Z*S#Yi-8e1LBUdKBI9q+8
+$laR'2[2@I3T6iciZf2,B#Z4*fm4mR1B0NQ[Mjk@adq3US!*Ch3QpM[l2qQ1QNCd
+5qa,"GV-S(m`C"Y!8ke3,#*'Sk5[Uim&ZXT0HJ#&Cq#5H)$I"FI6me"VCV4)GCi$
+lNTZ[$05mD&2@lG[b*GG*FcjVBP9A-G%VlS6%(V$EKIkF3XT(0!5elHYJrECJpDY
+U[TaT0"pE9b+b54Y`F8lF#3B,Nb@(ClGF(`[&e#JIXf6+eUQa2J,,NV[S'G%aS41
+Vd&AAB+$Dd"N"J6edhMSd3(@+#BQL2Acf[5Q1VBjDLQKRlfiSBBXPl&FR2TG))C%
+4aB+jmIP%,r)FEe'1D#S+e,MK%Md6iA6$0ae2*UA1#D[JL`a0qD4,J'8#85q04q9
+6[Y8rp&lAQ*`Y1-AN1,B"!P[,-0R%Df%1Uh2QSV1a99Al0-D#r4iPfIppG#pP[KC
+l0GHIM@[k$F4lbDm[SP[UU2mh*b2ic`QN`Qd)Z-DRX*!!(4'iELiYpkd#prdm&ae
+GE1(YhGhMpN,V6KS[i*bKB#flXjqDX"cU[3mE1c49CCj-[(F*fN#p[!cPlYFr5D`
+`c"9ME&`%d"2c22m4cqejq"J0&0Yi83)TL,KU-S9605-Am$DpBcEjH18CTmM1C`p
+I[HGVlZJ!rP)AS&61SS9fJ!'DDm3PaPQi#I+FqAbLqI"1J(["I+i*VF9%C9ZUa3)
+Y1(p**dPYrdLj2XNeNjm#F'aBKa"jq"hG*EiQ6SJFmfp8p8(P)p*(5$%#Ke9B[K3
+A)-Y"Q+mDXUdMPB'h(6ZDJ"3Z5Td*MT`0N5DD+ZKSr'`JR5)X`5j2G$dKYXU@Sq`
+Z-bSNSf3q3Ml(f[EZS&JlRSQF[,a(5j[YQ,VrIpX3+&8)AN5!'01d3JK'MJEc#lS
+,8aKJ1V0(3#3#rMe3hJCSK&!1e%&&Yr6Ka2@P$rDT*Vm'pffb&6imjeH&*,4c6YI
+!EjqB(rprjYhhkI8QYUGEINI3Q3EE3+"llqq1MI`9kLLc[G0C2EM%4"@-#cIBb2M
+,`S)*(92A1ePjp)*mQL1CmH6#aT+A&1%3hCZ%Z8A)3%TQ`'D`10MQIq3H4+5Xr&9
+$GrmZq"51pJA"i5qK$kD0KAD`APfS*h'F[#h$B,+Ld$'!4!)mX&%%Trb5jG2`JVm
+0P(Y+MZ#B)QUJ@4#'a+V2lNk91#HS0YhXad8pcHMBP`&")hV@%2q&(rY)"HIl,S)
+JrGC&ej%RjK%Qb@,2$(25B6mmE'V91TfMDa*)hR#)(2[!V'SILpq&8,UeB6+@L,R
+4UK2+q)NSl!"C4RBhD24Mfb`Z$#Jd$jUdU"AdrUqMP13dT'Fbj&S!eAm(""+(I`R
+9bk,f*le@cY$#)+ArBGQ[&0J","dZlJRrIi4$4SI%ic`!IA-pETI,@Ye[5[C+`'e
+5l&rfNe(8(k3c6SlCqT8$RkhYA4j`3m*rrfpcm#(CB!0Urf#6e#F9a3cr0'[LLUF
+ScGG1B"SL6k,MX3lL&04+qQj4G9(+B4c&ZH"aK-rKc#J!-AJ0JqeC43Pl[bk9iE@
+PM(US@#%B(a4cAiGAc&0AITj89G+N&TNc3-P[U+YmSG8"Q4JdX`4rQ0VK#J`0aLZ
+fY$b-%TMli)2,S@BIffmhfq$l`YGR6IPfqD@ShaRGBGiLY`Z`B``e2L$-UQ!p0Gm
+d,eK2`E9h#4EfHFd6lq#%BSlHBU*lXFB+JZKci",caQ3jXlQjUpY9h3&+i`'["m,
+YL(TRip1r&Y,rI,jk`(94YCAE(ULZCb!Mrhc,AKNVc(piXMp2M(&3R8kDkr1p"Dh
+k,r9JF,lrIB$Uhl4TA@RJlpXi9@j"hPcA2',e,CR2`YrEljKd(X(-rD6%[%Hi!,'
+T"GZGZ&Mf'bD,8QTakfIIYbVcAh'48c$S$mc-C0HRGS[jq[fDYe1Cj40bq"MKS`,
+-,p'iJQSc#kLrYd%r8U*NmqVDBVIhU)p&FDapGDK$f$Lf5Q1rZ+5&G5jqr2VkiNb
+HUNT4dql8VcclK$ZSaRQBc5eNhkhNfR!JLb`*,5RlqVJ#rhiD`b9aKU5U8E!(c0k
+Yla(fhS+IKh%NKT!!eE4i'3r)F0GF0+c2TA[R8NcT9$VK',V%q)l(RXYP'0Z4M[*
+YRf)bH1&q-*M#JiDD$ic,JjVIVqKDJ[kdU2!+R3%!kI#%eLFYdRrFF&cDj#&e1`c
+Te[RT'rD@29ZjRA5@LqkRPLhXh4c&Qb'[D$fHA[,q4ZPX+dTGFZ,liRY`RU#f*K$
+-V(j8pI`(rfX0@5[`jjYKH+-U31X3*`1QD"K'8#JJ,+i3R[cIpb8Mp,T*5[T'S6K
+(HeC55*h'Dmeq46Lq&pN-,R#l'T6@TBAPep,b&$C,ZFUEkpA&4q+PVkQiJ#S"065
+Vc9ARiC%IYI5!2h0RNSFa4[clpEVq8cbRrf*JHedTdU0d$Br2XIm"!bCR&SBEd5J
+XY9SFc'58AX,q%'*VaM5&Db)GXYm%b8`!XUMAHEk(M'C2DLk4RE+&Q&G1i5XX6ZT
+M6BU`$KU+a4A,LP2'rdX5KXZ&j6mi'!f!3A($'!&Yb0[9Z-aDjQBGh8*rSr6T"Xi
+C4TBZ3N8A)Z!L"X$l"jpX44URE03pl9"6Y`qi)EDpk$(c2AP-V#EXc1lZ)3aDSU4
+SK5K&XJH"iaIrCfV@NHR%UV0Cr`*"UiI@!B6[A+DJeY@HKU&map(XFr-3dFR`%I4
+41b19&3"eD4l2a0`H**Q$)`1K-0kcQ82AbV9`Kr[dfe#VG+QdQDa9D8d'#-3GTAL
+q0T1fl[Kb-Jrr%kRHf,i@X`)UhiD$K@%U2LT42JIQeI8KcrH)jRiJRPh)L)"IqU@
+99F(cL,)YcX$'3J2-0"5cq!I0)*L5KPkfTRGQj14$h&+4R$BcB6ICB&b-DE"Z`BC
+S$JT*B`3-ll0),DN1)@@CrhbCU"j+2r,"m9'5he,jHVL[+9RY1m88jUB+l3M$`I5
+P*JJjbFejHG@&BR%l2-mCX2"J%04'bIJH6ICGe1@8-I#Lq2TeYAS)("%"T5Fe1Up
+j!lkUEVp)X%lD6kp0+9D"q8#6c`+,k[QIS5Y$*`FBJfdK*X[03TM28kVmU,`,9lU
+EeeL46SY48kK6AjZ+q048YBa2B#eHEILh,cLdTmElpEk8SZE%`RkX%1HIiEr2U@H
+ULD&5(Zekf1Np+"J-!qf"AMc(1fGPajd,X4Z4dj15qdj$0mmUYS6@k![+fiGa$aQ
+HB`"1&V0pjqfae[%k#&"jD@1dZ-,aZ&,%2!k&'#C2pFj1B2Pii240`1mkl4SKMPf
+MCHXTK@PbcY5a`D@!crmmd[(jT"JMUfl5`QpQJa5-*[3HT*c1MaCI8``TU@TPl-4
+0TeJ"DFMpU)ATY9-T*pLBJk6iUV30X-R9C6`VV1HpSr2mQNiaYQ460jmIa*M9GYX
+DSh!RiHY)3"%ld%D4HTChH3V!&$k"dD0B0R5K'BZDf0fdJip&9aN[+DJ-hqrM6ZY
+2kJiaN`!63eG35GPErLJRM)(MU3JQ%6h$5-hT35Fr9A@[mf4[9*GHQ4'de4a#D[9
+U['2#`b9lHrYbeJVr$4-9)*fh+rDI8FU-i[BhkKL-T83lTp'R#(MdBmp+!f)UrQI
+a1+$fN8Sj!KQ[c(6M,EQHV8Nhq+Gq4b`RaeH3!!0rbdF)kp!ifF6DaQ(J"*JJ2MQ
+5+IU!&T9qSF'&KK3pH+h5ZlISM,EmJ0R-jb-Eqd'%rbF4hB3pIP9Z$U23VhKjrXT
+SG2prrhhB5-"Y%jB&V(U@)crqNUC#jVdiU@pM$e8F8#Sq!CH'%N0mpq+6P4@(T-S
+i(Mi+,Ja3*cdV$DS9ck41Z8m9Sm@j)#Q!raCrY)mk8@(D0"cYj%T`+,&EXa)RdMd
+ZI4F$X@pD"BZVC+RRlG+!@)aCl$Iih9Ed%aHd4H,3r%!Q!68JaC!!5G%qq"Gdbrd
+Bf6(DZ0+UJICJHD&jBqedb@%HDN,SN!"dTc91G'+0%ES*3R00*Tij"PBEfaY0'13
+@`FSZU@YkJCpe(l3SDS"ES+lPm"$@K0j+DfcfEm'DXZZMcIprrhrrId4[RZl[5-Q
+X'pE5lefU5ZZK!UfR*V+8Sp16(B[KTD&ijFdm"4SXD-R"[[QYKM&(8(-dR0Fr$N2
+M%R+90&)h()[dNhpcp+T&`L+dXl6P9YLfErMK)HNdDJ#L4pCUi"kI-IBN(HN)em#
+QpjUSd$'GdUh%%HG&*4T1"aSd[Y-R-jMI0M(f$$24k4,fqQ5cQ"i[Tl%VQP6SAm,
+1V`M6K16r0QRcVKA3X-BSefHjrBdH`r-%%ZerfNN)YADi4c+!Cf'Xe**Vb(l`-fm
+BFl**")SdK'&jH!DMMpraF5EG2[G%#p%ZJk5b2haJ(bfCe"c4I*BrKI%jZ6r"aC1
+e[rmCU0fM8'R3l(i9dX2J0cKP4YMYh2BdE[DN+MKE%V8p`Lpf5l3UlmfMVLC[cCA
+Fc1E!(FX0F`lV!3R33[efJ9Qr6l"NM@`*T#!Df`DhCkDA+kKZJ8Q'2RNTq9&mApN
+cYd%LImMqFJh0kbT6fIMjL'pb&![2F"$S4`)p5i$brEAep@SQRcke[UTrpZf2lG0
+IfkVIYT6r3f+[Y[R[Yd$r3h8[YdMMjpchfkDhfl'FEkUlrEVIrYd+rE9dqITCqh5
+MpZS(lA,r0d(r0URr0V(pZeIlG%[fkGrYeirEVh`[e9AqV6M[UVrpY4rUdpr9H2l
+G&lkQr[U[UqUMqqUQ[fkkrYd%[U[$pZP&p@TSq((+CXKfP[$%VAA"T"hkGN3AX&+
+ChUe'$"RLeqC)Zfl"de#MS"KD24SXm9,0#4'#dj5iS,8IN!!TNTQCER*rY2VV+M!
+[&YKT6G9hl@aa*r@2L#9U9hVq#afX[L6cUm0$Xlb9,B@9@P$h0SHZF-N1Nk$bp@@
+2*h88-GhI1p`J90184F9Bkd*#R0@-ih#G4c,)[NMp0()F2*!!4B'kf1Sj@2f-*2l
+P5$9cP,*l5GCJm+8aZbqXmTVhBHJS'0#[h8CrmT&8R$-+%%BLJ$h#TMDAFJ0)iHf
+l)dmJQY+@r$dPj'`P8eKh-IJfCJ`9M)F&U3YrpPmS&h*0#),Y4Z*AHD5(2(mEZ0p
+$mT-D`hd[1'ekaj!!%Fd@F*H[(KR(-hH[aD+9&ZRjrbD@Ii6,N!"5)LI[(F4)qpZ
+'1CMXYTj#b92QPqBPB+ZFh&Hjcm$9FTFFCP@2fThEG1jBCXpGb$$B,0!3,j)B3C6
+lk0PAJ6,iH,I,40UK@jPkm@UNM`5eMAi"cYa)e*J,FbZj4@'*9ZY*E3aKPFfHjEp
+B0Eh*qIUje3keG'I6'1!*TIhY!(SJC!l[rZVXclVA(8AUiLZ'+*Ahd(V%$NRmEb"
+PHB+kKJdcHpLqATS!S+"KXLa5X`MfTTUZJA`c6C2FKm6j!!J`p2-K+m(q[X9"&'b
+)B))FDE!hYf'K*2T2H[9[-ArF0HVA*J#25`""FPVLqpCYA"-Ir2Tj(!Q(&j0Mh'p
+-c+Ejk-'0`TGDRG*JlS0mV#XrYR"P[-i6fjXIP&Zh*jpcBdFPS*Y8NMQ1-r69DJB
+PlX"JRYASb`86f!,YB`r6M5Y829N-l"hS[Q2E5!Iih,F914QpXph&D-AmSS8Z(FG
+p2G4a41DFKck8Rb0Fm!ZmYFq%LZ@T,lHGlN'J4LC&M[A[`QjBcF#UI")h")FkBmN
+0Q(Re!Zprm(F[C(MS&&$59iP*e8I$*IYFik,r3&B*,`p&8Ec)`FSaCea[(r["Ke0
+,2(LE3#`X3`hYeG(ZETIjc#$BrG#U$Cm2JpjTcJeDQe%55*C5#-fT@CRF"lT0Bl2
+Q-MrmiR9T34h6CeK(HQlU#@9N,HEk&E+4lVRmFlAmMZbeVjNP+r5S%#bVG+A'E"m
+UQ2l'Y&m-"eehpQlk6Kfq!lHBjV9IKi"lbTfU+ehe(G4%GpXlQ4r3,&Yi4N5$*lK
+6,1PYl6Bm+UdL1f*r#Y2B#qeePFfFI%CRJD"!DEV!HlM-Q@)r#FAF!2SbZB6F!D+
+!X,AcGG'*,1@M`6d**-f2"ArZXZLH-eUa@c`#ZX2fX-E$Y9+3!(R%NAp%U%!h@F`
+-fP(SL*E%eB!cTmaAk&V@R2S6H#4e@al+cfDPIYI!&0j!Me4Y'4b2r(4[8LY&55p
+"cXZ0bjaQlk$JL!GH9V!NA934cSqEapUeQDk$kTR3GYB2*eXrfr+I*C5Xi2!6j'N
+JHVdlZDh"XHA!)S'T*0f'q`aY*5bVA,2T0dCRkNJLQ691'fQeHZCa3k!K[!1C+(%
+CGi8"kbBH4MBUb`#lCTEM`1`hHlCS%iF@C4+XDDLhm@9ImBTM6jXXDiZJbRJEk1P
+"pEACIT-L@1Jq"Npi3(Rp(`H%Yffjp&mMfV2@qRiY*X-+e[lm)+pNI35rZlFRrAE
+QRH`4F'f2k@MB4LTV(h@mrbaGhaj-G9)FAhZ"i&E21[-(X+#$N6XChBX!&"K@RG(
+$jd,8-NH,dNQB3%+$IEUkb9VFZF'k8qra`4e0lL!X6$GNi%N[,@KLhDIU`K(qA&N
+V$EeqA!ZId&NS@M""L26'bMjb8p(9lhYS*9LM%AKFH(k0N!!qRVEY8JA3i#3&LbM
+"VHN(6c++'X(3&KUXK0aDJAaqB!pi[ZZGN!$r0U[H3NU$c"*f9*)JK0VViMq#%Vk
+LGL(R+eSkf3A#6A-hU`#kB+*QrND-Kc6Jp*@S%(Ef@)De-QL("[+,-K*P$5Y+!S@
+ejiar&!U%S$QdQaUJfA'EJ1H61VrX8F#+iAJ#GNe)IjeSJNiP1P'F0)QF(Y1+Z*`
+hf#q#@mA64m5IjYG'P#U(hFH`i$*U[G!YdQX)9"q[8e[-jC@2"fQKIN30Bp"aYD5
+bCINd4-fm`M'f+ePQpQDKGed'5F,5)H2h1&[#ZjPUXQ$G5c2BA+)U1hjc`f45)I#
+BN!$I'NrQLm3HQ86pTm!*f2PE(5H+X!',dT4QM`!KP`E$8YGT[L2MIpQ0jY&d*,d
+G2k3Cc3C*UIE#!1PR`Tf@j&M$--KrGFGFP2$,jLc,pN1rdQqfr!DQ0(PS`Xj$8[L
+pN@HGbfpH*(ifkl"e)LlTGJbN6ZJ!k35PJklAJcA%VQ+NUa0Fq3KVm9-LH"k%Gf(
+EVLJ%QdYqd$&92$9J&05)Th2TLM%JV8J)QcJ8j,H&2@HVh`*bZN"A4ZlVYm`3)##
+mdYJIijZrJ3f(B'MkX[X(L+Ik'9LpKH'fh,F"*[[QjJ1a+1"!K#+L0B9K68afeET
+YC6Y6C$dLhC315e5X1!j1L53G31M&r[4+iVV#0DKl#hp[KFCcF`F+"r["UX#5fY8
+lP!V&,9ibr)4"NR(+8p-8SBSE256@PCSFfiekB0b1jZp)IdH(mc`V'd*Jj0STMHi
+apU&ZN!$Al19Pj!dP'b#KAAl(@G,,RS,S#*-P)kjXPVpU44U`jHQ*mUac8aX"i`E
+b*$"6&$j1c30RRJ1L,IbU*XJ$ElKG($$)J!51D9&"JC,,K-GHB2AGR)Lr"JkP(Kp
+h*9,ZkD4b$P+)'lkcb8YfdJ*&)ZA9Ua*3ZCeKCcY$$rT2%Kl8'I%PLZTV5+KF&U`
+)kYq8di+"1Z,*Fl3,6,P1D5`GcKeieYaG3rMLM0Ff'eJ%&V9*Yc+"0"G,L!e4VR9
+HiMZF-@Q`85H)(ej9bUkZ5p)Q,k-8r03E!P[)KT3F-8[-ciLVK4MGV-MHT$AJ*Lk
+k+BFl@dbVih'"NKdp$!8$r2$q!PQI*&EbSPqSZd(L(mBM'iDif4&5Nh,jGD-I&br
+Mq2I1($pY[KKmaN$6,f[E!"*m[B5@,f2-FVMf-89#FcU55118IB*&PY'BGF+H@!*
+2VUj8K'&dUVYEAZHX029EpB&%%QpBZrcl#lbAA'U3!2m"P4D!`@0Fq*SNm`L0U"S
+e*#YG09QX)MI*@2p#8#69cEqL(JhB&XN`KmA2PhM1'U'T!"(pE03HXpF6'9cmbPQ
+D$SpVb$EXX%R2VPpRIF@#jH-H*L%f`1eH6b"qMhb9NFabe&0iUqEqj!jeU'TElPZ
+N!0,LZLF@N!"eRXKN5G#-'c'AlU9r`A*#-)Z9GG%kpbUV%I3IHL9,53U8F"6YAAA
+N&[`5#AGYS`cU1@QA[#0A*#kiQ%kMVi3fb,MYcSm$[&`G$cl9&lV%%3[,T)R,SSl
+E4b6q)"B$SiadF#Nh!#-bF(,1Sd3R4"Z2,!(QQ5lbQ'SBP,iQ5@r+DDM2-bK1+J6
+j#C*%,m11e5664r"a9AZYeb2m&$00YL(HT'XkcaTXmCTQ@Q,h`9cqmEh-f1ZlT9F
+eB6q)i`0*QQ%,Rh9FIj!!i9ZA[ipk1Up+b9Gk9LV4e@51ZAPFbIiN3@dPNN8)&+m
+m!Y'ieV`YQV9L'CKeN3K30)+FSQKFda(TGfTZQPJdGUl1ZmMK4QS$T0k6K&d6RGP
+li-XbQPIHb6K@3mUrJmdp2XU(J#ei5(a0JKee#982IT4q8H-@c[HV0j0`XhkA"EQ
+2fhJcr6$Z)L`i%eQ20G&-TjkQlcc)Df)0r`$[T1cj$eUXSImY5JlG-ee$p[hJT2E
+%Ae[pI14`DQ,@Z"1)LL1B`Ze1j"XAc5k!phEArVS$Z-%([DH"YRk1-XZ4TcB9@1F
+%qrXA58(E"ST9!p5I)(P15j4T)Y&,,0N1aGN*"2[f2U5G+`U(F8AJmKhM9%Dl2Pi
+,&F5jYe@%R-VLp!Q#,5PG`(kKpe%'-DMpjYj@PK+e+9iG#,L`3'bES,0*dI*4Ql+
+bG8!83&pIpYG+U[bXNYcmj$')b"(36VcT$"3m`"+5$prDm5",ldiKA5ikh6BFhdf
+C*Kb2pXAaqci#5pC1ADNfP'0PM55LPB@+U0l+$APrM@QXXNMGb5TD+,Z`GdKjPqR
+5U4YPI4lb09`UebqSV9Zp4QjXB+c6!jFk-`!m+rD#ekh`#5hp!R9'j+,X$lHD+3U
+'KG1ql9XbKkl'LH46Z"G'J@!,I"#Z&2Ik89ElY'&'TCF!`-`HVbD#jDYebl6XQ2Z
+rVpU@KT6B-P-Bdp-22#r94%5G)E&m%KK+430q%EDb3$+,kdN-)jdPAS0`JP5a!d+
+pDZACK'e@K`dNMkHc02M#IC0VFkT'IY'2UAkET8e@bc'1k1H3!+@,r%NqQRZ-ii[
+eL2Q5lh(KiaBIBjNX6p`Sh&f"9GJSm,UmSbaRB@'VDb@UaXG5`3*B9S+l4dZ48j2
+mJaV@F!Vp`hiFL%QIX[S5)ZaX!kp'lUFl$Jf*UpRrCZ,@Y2JH#ZJ,3(YB0e3`#[5
+(,5SiD"#+a(R[LhKT1P5EcA4+FCkkPab1#)CrdSDJ0E[4"iU6kXhpE#1e-SNK,5"
+RGVkF&FGe5`-A#Q-Pq"C%GPE"PhC#FZ8[$LGIBD*YM[pa$e6Tq0pQE@fVP8'B0P&
+MC4XFhlpjSQ34F`(GXQ$P@5YSTi-'!1#dHEa0*6D3!*9PAc8k&pK4R9q29!QjCqP
+r3Bkpciff-@AQVAI40V4Gj!,AFX2UKkj`8!qAD#hPqUL6d'c![Yl'Ye")pXicql[
+bR5qJ!lQ!Y36B1E898r+D*h!BA@6pCmN@#QN*3rpJA062L!&dEZ@G518@'c6hBQq
+T,cET%c3H[(#-,+Udl3h4KB3`bF*F'UKL@,brJ4R,!9H0VAHch"aGQ0V@K2E99Ha
+6hMT@Pja"aV`c6I+FiP8%X'*(`IK0N!!Ee+bRpU1A,jA(hD@LGKf2P8-D#f2KMR6
+dPC-IN[DNNN'AmB2RBYQ%(mBL#0CPGK#L8#630@"X,f'NH`C@"+d)[eqllcaX`5d
+$r`ead5C9e256ef!XYSY(mR8YE5SLAUS$H0dihZ)c@Ba3S[pQ(4X-!dhf!MD&m61
+aB%-p!A%0%#B8Fdi(N!$+*&Q%$Uhh'b1bNiRS)I89Ybm9VGZQFkE)Mm$lBiK1K@m
+Y"d9`j`G3KqZeQ[lJSG@f44bV[hmjA'bl"!`(ZfG6NC(RISG,j)*fRK0`#6#IiMp
+Sj*%cP)AD`rZj6J@PFUl5)"idG%YQ9D*V1I6)`*i9`C!!DlHi*,"U[HkA*Sh$-V*
+)phND(,IMkLq*DYQM@%fAQJN*(9h-)UGX,P8bbadhl+GfZ0FEHb)Ud%r,-JI1VLI
+f2hV@Pb4m1G!"`qNrYNJ+9ZDEjm`fVXFbhV"`AqVhZrpYrSGBhVqVXAe,8Z),F`9
+[MfXM!eC)F[EYU4",3`6[UcP@K'[0c-c#p#FhPe&Q1%`8*B4iJFJ(V`e46$`hJ@k
+BaGD'[T[1*&!M$B&&l+RQl%DS2`06lJeh8-Zd23Z`IZ2,1TPCXd-TRpE*DVKMB!(
+-Dd%1&Y9GMAZV6q*VAZNqdP$`jfrqDpZ-p"S6[l25DNBK6f(mlh913"V0Q8@Mr6'
+f*eAmUT1K8G*'#d@FLTXaa(DYFkpV4Y#VD8fPPQY0fd1rlbamJ)qp+82UGfQJL`T
+-h)(q28mZ%)F#QiUJ,@Ha8[Y#QrH"BhF3h,e'JSKS90!pR%fAR64,-@A0j+!%mVT
+eIT&j+r0&6V8)pDc4NN[kE(93-9ASXB*%F3,EV$!%E99Zr@$D1FTUFYBK#hQ9fIA
+Fd`4Y&92c`Ah1($qEQKGIf#h@k8jmX$@+DVkffILXdKYp)lpLIqB#q+!b%1ZCBPM
+!FfA)H&J`"QZ#9P$9GE"JV@$e,381aQ9!C8"03N81GF(MPe%j,@@Z3jVf#CcNF5'
+aX,'Y"m*a9PiQ)lQpDSprBU`8M3JibPP,82#KeN$QVfFi6KREC9kb,[D5rS"-YYH
+%&YmKGl@dX,8cq8(%G&[bEm%rMb-$r00JcN"(-k&PVjf'JkP'`JUFjH"cIC-idUF
+Y##Z["5ZJ9c5,51MX4$6JZS&,@FkIcJp9ljp#C!m&!)`iUFHfdj,KckU66'GRL&E
+S0J`L#-mThfr#a[@52A""r1pi6IZ+$kh@E'P9CD4DQ)U[$e%SeB*d$1"28B`$6@4
+PcB`92%DZqEG!C%ZG!0kViX-a$8`*E(P1T%1j!3C3"aASUZTNS35ZL(J*Bb6r1&d
++b[K%Y$i'Y[Y@#[milJm6cpi5ZhCcF#-9*ISLqC-bi#B3Y*eRM[hDd5EVFcZJpNX
+VLbYbF+))(V,Ipj*V*kLUUI1Y8-k2S5r`#Fb$bSDH%TD4Bp*DC94eeI9d9H!i9[@
+l49TKiJXJL(iP8bf+#f(LfATF3&3*IE5SM(N!jPd2S3LTH%1cMNlYb5CB1`T@ha)
+F1AI9L#'18fqSrZFrA&LELDE'Td3D2h0idqfh(%4[(h9)f8cm2L4*"C328lZ*JiF
+b#P-CX6YabA&6ekR"QLd-mXUe14S#Ib11Ua+28eYh5edpSShUR$TFk"DKGk!*!BE
+-#YI%Rm@J[YT`T9bN+,i+NrprQRXE#I'IQ!#'1pkb)9pPQF-F2,'k2H#"4DL$fRi
+LhHdA&!8q"AU!mCfG4'8LFUph8RK,2A-pV1R[AKqX'9[Di*RJ0e,aq!a**J-Valf
+0LK'Nf3XTelrV45[Y&jGP+b"6+VeHkHb,,cDcFAqPBkUCZB+RE55XGpqhD!i9CYB
+'6&NbQY0Q*B1HY#+&0RB(1SH+B"Hr!9SDSC!!CapJARRaCcbkQd*00G`E*cA&"iX
+l*kB86N%lDX!3**`CD!YLZ@fNmarPdJ'"Zf2*1DE"A(mhH2&l3b$()l"Lh[kB1*1
+F3a9++5AP%d#eUKGeLR(%@"([G[AA"$0*Q!PZ"(f$bH6aiPDT[Lp)-Mch#lS&"!L
+jN!"5BjBaAkj$mRakDfVVf[DQa38k[4(B8qb$bHTT46",C%(!,$*YFPPh@'LQ$BV
+-0SZhJ#,+jh[`LGcGcbN3qIIFA3020rm)hCqH"AM#NF+Jb,'*UAJM!IZb3XPK-el
+HiIp"Aqb2*03da4X+i8A(RXYQmK*m$dm,ec@i9NeSA`d31KL9"UZ0Khr3@9fm+I5
+Sma9prC9k43(4mZ9bqCkHlT!!A&J4eY(S'E9%1mre*NYVr*TS&lZN'0CY,[bhX0B
+f-PQEP9`"I!))USSPVMLHIme!Hh"*d!!kZ0+apF"h#E&F$3r1[5Ar!h+fbaX9K16
+DMl1`4lqMCEm,kISd8fp$m%L[bLUK-kq6-R9+BHHF9T-5PAFp#E)!S2+M(hKSpjk
+E+Y2l'J@K4RKC*N"G@'9V,p#9+a4QDDK[$(#+200BSZB![%fq*!**C1cUic5-4%R
+)`KXeJF41iJ5'G(PQ"@Iqc-84I&14P-J23JDh4Z'2hDl"p8SQ5rjSpl&12l+ai&N
+h"5-$%G31b[p+EELpLcZ4X&h$6F3I@KJS(Am951Bk@l$Ja%-3!Ij$$p9N1FTM5$Z
+Fb(9Fh5bB&[[+N@TiKjfN`"m-Bp@e"6la&mLIUFAGh63'rd!4ie!,lLFHPS&`bkY
+kZekFiDd!QiQSp'NK'P*(1GZkp5(+[XRm14*f[b6T3Rl-YBN[1Ie3+p9V'4Xp'dK
+j8AM,q'`CiL9UkMY2KQ**D)hAQ,#[U#TSB%-fpbV89RD5q@I4iJEr8!9BH0SF'%-
+-jPAIP'PX82,&XdQ*[&*D3T0c`fJ1-QjqKirAL[Z#@FQ$ckU*Tr5q`'Ir&R&c+M5
+(j,,5J[hH2R#p'GdC-TlB$pp838`E-+*QI&Z#JC*lca1G9`JGE4N&Lp0SHdeM1!8
+D0[b-r(&N2&HjkqU+G@GGekP"A34MKSC5Q9FQ*KQ@bfTklLL)j"E@H"8bhhiZcci
+cVS9&raI6ZKPeSS#1QDBBrbVqJjKk#-l#PfH4FK6"dCR+hJRKKPiEQBbbc6lpIGL
+cf0RjP51Kc@r03IhCaDI-dV,U,E4ASL8!mSRBhB,N,IGd+Y99[4!@IC&+SE*jDF[
+j4rV5TqBmM1c0!bEDR8!RaCQc,5I8$#q(ef*p4drEK1-(()5N"&+DJh55,@)@#TZ
+ZA8Z$+HS2fNaDC*KiAq@b$2HL9!X'Xee+YAQ0DrbDXmh6YVE)#4EJGa'kqR1#BMp
+ZP+SFmr3-"Kl@C8cU0rb*5$rSKQCbc(2D1-jMUN9L$H`r"1ZMd%p5&,T$XlkiXT3
+,EJfH-A'&`'RD)iS6LG4@kbBdr4R%l3I'Xep0RbM$p0d(93'-13P1,$"MZ+4NLcV
+!,ilkA!$Me[EBLF[(62c(-d&+%BdZH"4!bq-fpUiKG!("IGI9Q1*8l1jLiAAUMm4
+)'0rFU2b'F!cXG&fRcecQL2`dIPhA$@3[HiTr2ad`X')5HZ!-8hG"cV#[1*1miLF
+%093ak8b'*Jc*[5m`mHESZQ4ZJXAP4DY[[MHXbTRGbJ$@PEe(6r0R+Gr,aRhC!fI
+dB[3UCJ&I16(qU1-8qP`(IQQeUIc+iK+['8HiABT2RB#r#i+H6JUc[91hPH'C(3e
+3))iSR6aFI*G(('UPNfr*&0$B5*Z6@%mI9NlJ`UJ!ljGUmU@*4mPp%J6kH!-$A&`
+(l)9(-3i)E+"i3!&NFRE--X*[i6k@X)db!N,hKm-6rd'cb0J%JpZHZMPU2"%C8@P
+*Z6h4'9b+pC[$FB+a)JEk6MA*PC)[N!"9ll(DmQUVKr$)deZT$#jYJ2@Z4Qf3!*8
+M0"&V+ZB!L#ekbF[p*R0qmfIBU)!#&!5M9,mcBVel+!#&1GEj[J2JZ--%qJdfp$c
+&cMp4dRie)"jH(LYLNQC@['6b$rj-"E+"F`HmMHN1%FCBp0-J+A3L3PAH05YVFZ2
+F&&lih`6J+#D%3MIqjVRP5$c6hDj3Ijh)ZFbVXi,I0[6IBf1V[R*NaeXIf)bY([+
+!(S)FmNG9lcjeRrb!Ya[TC+JFjrDdNSaNMF#dcC!!NDq-19c,a4+&crLh+L'+q9[
+l9jq+906m8&XBAHST1GhL&r@f2@U$d4*13j-+@bm*$C!!mrmXLZ2fV,#R9cK1K')
+GJBBkY,SZ&!3l"hp)%0%@L+N9Um%Q)'$E#,a*!KC%4'Qikh&2"M*0K*D8A4!GZp"
+8rP2S`+)0&bA%AJERi"2qpmYR3qMIT&iI3iidG!5pDIc&DpcdmEG"YR'i!$!LrIa
+dJ)k1@U[HZB6(ZdEa**e[aLejr,X`1Rc`jKM5S4'3!)8k@aFdPUpTkKcIF*Y)mZY
+JcXM5N!#-bK!qDq@[MHZ0Qic!CP1r%TL(BE(Mr9VK5R`F0T!!DS6pH%68qD!k,La
+SYUl23GeAlkDfF[MQ[a!)+8L53e4`f"kLXq43$43L"jQq[1#%qbpFb9rqXUc[#mk
+QZ%F&&dJ"LGkA$Le81!bM(rA%!*&LeE3["KeZRpD(@H%G8R'aQ-@#l!9@U1-Q)Lp
+M$$6!VUr8Lq!rJ!A"R+%&VQ)dY-Fa(p$X-6*2kBVbbpUe)5mNNK*d`C@R!,JVCkY
+QPE#Jm`-F"%T6BIQ(K)J9E9AC%'H%jb(20QQ`MpE!0hrPpB@M%2aaAVV5qEeD,ZI
+GE60GE"#1F24R(LNbJVdrK$)T04-Fq`B8[PSRA)dFaYb,3QmhLj3QG+(ea!"jS$H
+U4lmIBYGAeprDMd[Q$D,+f1AB'(R0djNSb1UL)Nq*H$QGe*Sb0SdC9*e8kYIqiCr
+0q64K!Yr-DY`,P#5LD4+lY#,l-,((UC(pjLJX'd*Pm38lZQ-6)C8@#(k`,B*3#h,
+%q4aqcXj#U$NYj`)h&UF$U2Zci8CmdIL(Z4IF"KQ"j9Y-ci8"[V-lS51jY4&D,jK
+cVK$4VT!!-[6bI3BekCbmHm+Q"fKSVfSH-39YmV`+bTTrmDSI*[2TFbm%@%Nq@IU
+r4pZS(MXI8S18c@-ZhKFIP3a*lAeNC8eKCX!NF$SF#RPR&Bq8Sm,jY@5"[9JNMM#
+`A*!!fKS,eqLT*d0i!kD6ECq6CqaZ0c4Ih6k4BRr6cAC+'TPKZk+,#0Z#m"2rENZ
+0X%Tdi"d@LFAf25P*5!"iCBKeF8Zk5X,RXYHNVR'96Ri19EQ3!)#AhjLPafDLL!q
+@*hb#!1+d3'$TDXSL,Df[-q&#%a#FYiDQ-N!aVD-jpGS@F5dQZA"8EDcJB,iar0'
+5+&IbSE2&bdXh2jdKFGBK6`BUU11mC3h6S1PqbqU5k-DiCBarhB[e2"pPA'k*G`f
+6XV6B+5mp`Sa`I,KMlEG*jY4,0Z$`AL%BLRSbIKhEZmhH#eThQ5J1pq1Vbchmj[4
+RRUH9bQr21er-q![c8dK@KGkP2`*"X&$FAAK()d&"l)5h[M$b5e0FYK0(MM*H`S&
+FqLTYmmPLSXJ3)%AieRVi+JTAD(TB+blkY9A)TAX4ZYL4PFUdk"`FXahh!SS"ILX
+3Eh`BaK,6k"&X#8!!5YHhCN5*@D#AGUKrp*[,20X0X(Slajk"2lZNA-MBJ("mS&a
+*#cc!fb[E6,#!Pp!&b$JLee3aTG44C)Ir%%%-1fl#M0KZ9&AHQqLIT'ae[K4GqL+
+aRE9P@-'dP,"pVeK"jfYNVkF9c&Ll+'L$h'GA%!URd9FSA-IEmBYe#9BPD)Femf0
+V6"HF!X+6L[Gbd3XqU$qMiHdF!"*Z#,Hfe`@q5jNi%-%CHmLCka*6P-iK6UA%eI%
+pp%6I8-))#d8E3$M&XbK0UI,Zj+(Fi-ZlA)V6VL%J4G20JYEcf99J0dJIpm4J562
+cM2XYJe`$i5-M[j-qI@NB1RX6(SVSQfPEV6`'L&kNdS[D3G#0%fh&$Z&cTNYqc"j
+hF'BGmSi*-(6$Ir*m20#0a%KT0SCQ9TpH,QIHA*C,l@NGSIDf8@IjNa&mjMc3"kM
+&*d#'L5R+4Dhddka$![1,T6[&lbZ&6j)pA5UG8Q0ED,a9,3XLEH5$5&@Si#h$IU2
+KZ81TaC!!DPAGX"A-qaN%!"kCAHEb@hckEYXhI`[ba(D2USr[HcY30B`eHI,*64p
+B%jZ1cSGQ#j)GfbZ(C#(D"!DFMc&%8edj`q1rFjma6SAjf[@H5X*c%3"'pR[5%Qi
+ZrMP#0p5kk[9QSelhZFA9*ZS*3KFLHH[r0*%&dlP4*kYM1qlp-`G4Uc@Ld*cYEa!
+L32!T2*rN22104I)H(%`3hE$FU9mV($994kUcZk,f6VSS&9$j!h!LF`qDUhKQ93j
+q6LTqFC,%R(TZ-0Q,,%$6l&+CkL,q[V$3!9Upp-VElhlKBq'CAVrcffDmF'Ff-2e
++0'cb0@SNk$INF01Q4CM'RqB&BZ@%"cM[8arE@Db-6m+r[1Qeam'&EDBGbPZqrfK
+0&JA-e9iP,XhKN!$j'iAQ"fJ@ljjJ"+5EHM'"epAe+JJMS5,ZEr9UT!&0BIbd"!Y
+VS""-f!Tr"T58%DP!Z,Kh`e%#@Z(,P+,4&pU'HUE61qm&4,P!Be)U4aIk2lP4Ff6
+-%R2VkV,cG&F%irYl$Zj%rF&J+%X%N!#+830Rq1C$MN`R3hXi@!Nh)IYePAMpfbP
+ce4+Jr*Vb,S8Fr+(eP-&d8JI*i,kNbm`[&q0eqbclTLYefeGi0bl*rh38pdkH31N
+Ym&PiIArda2$eM8fi$6#@a)Yj3b9qLHD6@la4eSjlApbmi&ECLXc,L0C!q0BrNC!
+!+Skb$@kYS(VXLSTPff1e#reGQU@ZrdmQL$Z%1!m$"&BZqXDibLQ+UC6ST"YKR0U
+QC1b)`%P3r'eR!EJGS69j+4V458rp[c"cc"Vfa3r382HcjC3kj&[i9%0Bqi1Jd&(
+XI$lc4$3VPXImhj@'L,F05#PQbKfbFVE(l`j0daKV6TDZkQ&,9HDVAU&F&I3hm*h
+j+CUrc2X()96mKjX#05pPPj481A#F89D)%J5&m-+CGMFba'Tfh&#'*fEQS5-9IhN
+9FK2YT$q,&8m*'a4)'2@Y!LrSX1kc`cfQ`I['%06&--GJq8`KZa##N!"2dF$9LL[
+E0j&,B0Pi*JB1D4IXDbG9E(4Zp2LNhU'aTV-[3ql0H%V3kchY5!qXPee!$"q$5$&
+hq6qA9BFkL"c#)X-JGcI2$'@#dGGb--L-pH6jG2c2lMMA29*kIALLa96MT1m`cDI
+YdpQpJ@+Z[h`A@brc'*dVYN`k0RfmGYVRId`faE1`jA2&5EP`cZ"Z)RH#SjH$#!B
+,68q0BAI&K3Nm"db6MHNb`&kZMp-c#a00H!$-9a!0XX(T*%R1j"EVD3+1[8f9I%V
+K0eP3!RhdM@&Da*')rhM`Xca*U2H9%+hC[@`M!Nr[q$m'%X1$eGYa%hEJL2`J$l,
+D-NlpiF$"!Pbl&p6@$69V91iaYRj5&qC$9h,AEN-qd)RR,C*KpJHiU-9DZG3Di1+
+P[Gl6$aE%TG(D+FqAq*[`E[916J`a!"@D"FbfVr#*krF+AbXPi"5iX+B&RSYcDrL
+"`JPF)RP,GTCb#cQ@j0SlTP*LhCP6,fGBKS8Hi&DPjUq3!$-+3&1XN5%#-`Z(a0p
+%EI@"R3C8-hZCi+JI8hUV`Se&3&hU[Fcq@TNmJZ@m5daaZhf,MFFUN6D$'R$A(HQ
+Smb(G[qYBkkraqXI*!3iM(8ITEI$&Y@YCB#(FBm$$k-a`&r42Kf2S4ZTBk!N8lYC
+B&R,Ai)p5"XYZB-MID&bGQV0j)pq#)a&+rYD0(Dhi`cC(&P8mqT%4e6lqm"KT,)X
+IG&$IC)a2P3,C`NP*q3d)i2JJNmY*,b%MVeUlr*NXfidhZDG3R#5F!mi98J1SDHk
+q&)+MK46M(f0`C-4kj+-*)DfK$f%lG(i*BJ0P,q#[&0(DSpJ&ccJ'"-32Hpa+6Dk
+e28NiJ5&["3jp*XESc0r-@1d)6XaUa`8NY["M"Fb9cb*liU&$r`(8fTB['h6e81+
+D-%f[,!%MTI*0$a9CY*!!BL8rfH#@jb-@TH&3hbFMpAZXZ0[k%#lpirIk`$-*6I1
+`PK1XrS-8MM,196m%DdbMj4Le'$+ldGiaUp(BR1SXR`'If$Yd4P8KM"Ekep9M%LN
+USqB'Kh"9%CM&-B(j`aK'S,m$a26eRkINS)#Gpr'FlKN8ihVGY9TNQ4Ya`r`8$jc
+8Ib%kTK*bc!*E6Q4E`%AK54Ya*`%c),TGaaA1EKCiADclN99F[b1E9f8jYZUa"U@
+YeNNeiFebQL1PqH,L6TG5PJif+4%cSZK+caI(1mM[)#"rk-CCTRH0m8iR1L+LkqB
+d1'&q%,CeK)0j&R1'c")1L*k[(,c3%LfS-j!!dUe$Gqf[$VZlU`Z9@iJ!A@q5U*p
+2ZBKZR9"QhpcRk4rkj6'@*d5Z0[AifPPF,45*N!!P+F-2'YfmK659FZDhMH@lUPY
+L8!ikVq0TSd[QYc&YjbjaSQ%C(5E*06"NP6McRm3h)6P(`HjLZl2R2k,B`FTckU'
+9`CCNM2b(KP(XliVjhi`1#TP5-9fiJjeL6K"d3jMVdNCAFN&i`fK`#D`rc-C`b1m
+`3M,,DSjZBP6CJDVE!V"1iPkVfC,TYqc'j"'q-K3ZM)jeY9Ea&%Pj!K*kbVq-e`5
+Da%deQ544k4S5'emQRb)4(#H%D&miCli%lMJ8rNlBeXla1H(L3N$!&@0HLia"JD*
+aKUQBF9#&CYec+(*5#NmG[JmCpIp9U-hCpG2N-'Z5Ie%Aa&a3L!dDhXeEVJ"`"p3
+["'f26bBGe(*N0Q#9Bj&Nm#'ep+J8fIXqVNpRH29rp#!'!,CKmQi$4$Dldaf"0X,
+4Qd+j'd5aJ!#a35fkR%Z56E`q5ZT[2Bjq*MaShQ""NZX-3aJXEk-a(R@r!rHF)*K
+UE*MUK&#jCUa03@SmL3%`FKpa$hXjZd"%SP64@[b-bZa[apIMd9'i5E9[URG92!A
+HZ11dbl5PaK#1KarH+qFLI4)&6JS!N!!"ama,XGGZK*YHV`0PNHF(AilQ[UjCh$!
+R5F50Ud"MLGEfiBqRkQlXE@hpDeXY,cMRYF8&Q"N,e2THF5LjdPZ$j5djp3',Z)E
+!Q9D[D*F(Dc4Mflc5AKcI-Lf5!*B+,9pDK2pG-VZj2NSMkf5YQd!Mi$68(+V%@4P
+!0KifV2a6XeV*b1eFd))Na+TS%hIK+T!!"R@S+#mfUq-$#GIM8b8@Mr6r-5K32!'
+Gp%G8J$3"j#TbhN$ULV+BXfSqkNqYSbDRF)+m$FP%dll`!3IGX3$`jLjK'a9k+Fa
+ZZ3%`l(kP3QU-2NG$#P,bJj!!8phF-HI[81k5G069M8M3jp(8rHZ,&5`KY%-TqPV
+j[Xeq%eLC[%J*d0"Re!!lEb&RAFd%lbf)l%5H69eCp+r1#cbKESDPcY"S6F!r!M!
+!2RXR*lKm,rm+B`b@e[l@AlTU5mKF2!-"UZ%$EUdNTS[4[D6,YR8E,f6fRaVE!)D
+N#NZCGX1)hYRk'cm$E",$,$q6Q8AE+%$8r-X3JPV%D%1*[Hi"CdF!5D)K,i8f8@C
+TMa@rbf,HVHHJDqar6*!!``RMVb"Y0"(DVq[25m)E9iPJXU6lY,&8bJhd'0+%[6)
+h!qR6Y*TGmR+#(!dEFFXd*[jpT6@(BGJ%SpC&#cK,SH3k'b`S@ViZ#k+S-rH4BRf
+De$ARF0KD*r-K!@AIZZeQ6%RQQ*fdVliJR"hejCp4'i3"eNdecVpM+-E"&UIF+)2
+,RK,9CHCjYeIUkfKChFEEYm")[@Pq(T&Pqr5D4(Im[Sj2SI9rlkXV"SaMm@"PJI6
+AaHc6662ERpTN(`))Y0SQbZ-l'e[k[j2%qD5[NUalq&qA[VjP'JqBE5P`Q8eQCHF
+lMY1KU6fd2P'rKheUI+aarh(NZ8U'Kek2EF2$Jk(QRI'Cf2GUTP+EKrYNAdHPkN*
+Ll(-HkK&KeMEX-Dl%b4DrPU"U(,Yq%cmUi[Z82TeH5HDLjeaeq8$UF"8P@`)CRC*
+m61+j`$0k9Y$!fR3Cq(b1&IpTKNM[M+4lCa2B#@)2!V%C+J[G0M6$Z5QqVdVU5T!
+!N6Vj[LdX&0YCVGFM4(#8Cf&e*La,HMJ0e55Ch1K0K)IZDPU[U(T#ZK[$dRBTH[B
+VJT0,*F2Ze0M*p1VM`[4k,U-p9UVA6*J%*jLM0H61`VLDLBD&b)R#CUKRZH+GRLM
+ckI8jrcaQ%l,2eZf$jh+b(V@F9BUQLX"Kh%lp'XjEI@F(jB+EmXD2H-ffdi*0rcE
+P9Z@-%bH0#6(()1FE#b@3!$qZa(*pfJ@l$0fDN!"$jXhMrTr,-1c(d5CTaYBC"Y3
+`q*N'c458q"N4d[2!GYE6dC1PYNE2iD!P9AR5`HNUMebC'E+VV"@R-bN&-`rqCE4
+Sh'$PdeN9Sp"V"[*qEFD)HZYfR!IiS&&,,LPkKSJl)lUZqb["Bh+DDT%DMGNfXIX
+9-0K82ZL@E,N((SYm*q[jI1AVT,KP)pNl1$Nqbjf-`QX'*BT0MS[1Q-A`q,CU@T!
+!TdTk&BHM2Z1lBPePJ23kj!!cTd-rp[T8D+PSad%X2kHXULHGPTUCZ$LQ*#,c4,2
+k[br-TdF$JZ!0)4Z$fre+Ej!!FZ*-(0m$!,dJ"kkkI5)*NrH5+01--eNQde),%Pk
+3!+9eARl@9BpfkM2'qp'M245b#0b%EGH3!'T1mVLaKdcambBj(GX"H&m$l9A@B2[
+R%)jYZ`1#-()d`lR13kJSA+SYEQ*H*)-$K32S[i6GK2%VZEVY-*hB!KrYeKYPIYP
+p',Zf4h,aZ8UBBSX,M*K+)(V*1UMmrdapd`TC,($K#b#@kS')JR9`kjfVMN)J$!4
+)6bYb[fN8IUU82B1-M&r`DL%H62a,NmPI'!qZ#RB,T`+SH*L4f@lP@e045RQMCp!
+U+Qd0[f3[i3DHqaNdSEDre`#R**PVZr-2!Nk-j)J3P,HB)Y64JPCY$VV4M1)B0I-
+M8hDiQajLlc)3*@iQMmP*)FYHfD'@Vm&P-2)$K)T0P`6DHB!FAH`&fh`e&k[HeQa
+MhK4c,"6'PpCp#rVb9qDYY3pj"8P`,bHb%I9&p#-,+p[(kIV&&S(`NeT2[P4R&Yi
+$J,f3!0BIhVP[f320MH[pmE4fIF+KI#L!Cc,#`MXr+JP,0#rH$RQefppckBTRlVT
+96UpJ#$bA8Zc@Mmk4SKYfkEmLRY9E,FD25qPNL,13!-`5ep"bq5iVPl-qp%SE-+@
+d*D[dlN-Cdmi2EkA&$U2Mh&-FVp00160G8fqBDIUSE@GlIT!!aYQB66i3YR5HAck
+kXS(fQJBY39l!#1U82e9`3lf2l@BaPb$bDYJFYJ&I[5-#i-kVL(RY4Dkle+*iZLk
+KA4!3MZhHdL,*2pFa,MkImRr')6VN%YMYhfC-a`BDD(3-eEiImP`"ALf(2h,*",%
+NN9$AmkaYPG0Lc&'8e!jAY0+M&jmYQ&e,`1aCBELj2pq%@$b-`(0[RrhQ),$H"B@
+"&pHclbj-@ZDEcYr6bX)kq'r-e8e$*"8R'BYb%ADrqb2#ppJ2ST@YhfAjKJ'3!29
+TJ5iBI5p`MEKE5qM(8&'q68QMabr"P&F!4CKHH8Pdk)RG[j!!cb+JabSNZ!C8N!#
+F(SBJ0LY*46'3!%PBN!"Ukp6i*V)Cij'Nb&GJp9N)i``h'P)eQ+pB$bD0eiHqKZY
+VZ-B$CS[90+j9dpfG!S"$m!qV#0Hbika&-ALBAjpfRL,"[j!!E$f$bfN[k[Z@K2j
++)86-aD3ZmAcZkX`HqEIr%QhI"erhYUR!b`4XhZVU$mpHBpH4'f`5T6H(V3Z*X2'
++(d!pCEDdA&j&66KTTPDiI$Q-p8ljB+U)YB`2bkAq"3qdbSR`(hXr3MD%8G-C,3j
+c[*SAhU`je$C[`,,JBF0RFB'0-dFAfq#@VmBdf2ANLd4`-4P`Fc,!Fr!L"c"#1XA
+82E*!fBZi)'q&hZdKD0T%LEaEicKjVi-3jB4iTU-0HYdA5[ZY68lA'!MjD14eY[,
+#@Rq-fKi0`dkJbfMP%mLl3[DbiUfFXm'*1,3h[SN)P&,$%P[!8'@#V!Q*T$rmY%d
+Z@[I%)P5a))Z@RTQZ1D@d(i,YekCpa'HS2Xe@$m)!F*m`6*ZkKK6`6QeL@V'DhNC
+M)2QDD3ZJR&m2R0'rR8"1,Q`Cc9`8Y1RLRU(3'bb3!'P0DI#GR*kmXJXfa@d3alj
+Z4lNSeM`&S1f[eS4SbrVD%3CqM$93AhK3cbi9FcaF(hr(3a)fRc$246@KF4q!d*%
+l`0)E9hf'82@3!,hpad9&IeN&&!FC$'-B3ET5[X98YaU5aA32Pp2ES%YX2GU&%U1
+T1bQ"d!r+#'#rIMBJ!#JL'PXVl&[2TNp-hc9I1Dp-X-KFRE1b9b4QF3a)e5mr+%!
+TlS0HD2Qq2Xl!MSfT+Z80'crMUaKE1eBAQB@k$h+hN3HGT$4B[i5M0lCXCP5`Kk3
+fYF0EDd9XN3U*-M5XKB8TMmd'kpeH(YhUSA@ahYNQSa1"q`*[N6Cr!k8YU89ae&l
+5GkP81Z&`4Q"D6#@Nf,L3!,'lK9XEQ`1c`6KeF$4dA(("F8kqjlrIJM,3*FR'G(m
+AehIrf3!!!3!!!L&S!!)JD!!!!$)!!!!!!!!!!!!F!$)!!'PMER-!!!!+[lRrr`!
+!!!!!!!!!jLJ!:
diff --git a/data/icons/manaplus.icns b/data/icons/manaplus.icns
new file mode 100644
index 000000000..0707f5342
--- /dev/null
+++ b/data/icons/manaplus.icns
Binary files differ
diff --git a/data/icons/manaplus.ico b/data/icons/manaplus.ico
new file mode 100644
index 000000000..60203d565
--- /dev/null
+++ b/data/icons/manaplus.ico
Binary files differ
diff --git a/data/icons/manaplus.png b/data/icons/manaplus.png
new file mode 100644
index 000000000..e819eede0
--- /dev/null
+++ b/data/icons/manaplus.png
Binary files differ
diff --git a/data/icons/manaplus.svg b/data/icons/manaplus.svg
new file mode 100644
index 000000000..5180f6057
--- /dev/null
+++ b/data/icons/manaplus.svg
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="85.270569"
+ height="88.65316"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="mana-logo.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/bjorn/Desktop/manasource2c.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <metadata
+ id="metadata9">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="951"
+ inkscape:window-width="1280"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="2"
+ inkscape:cx="44.590205"
+ inkscape:cy="39.592402"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3496">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3498" />
+ <stop
+ style="stop-color:#1d2dfa;stop-opacity:0;"
+ offset="1"
+ id="stop3500" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 50 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="300 : 50 : 1"
+ inkscape:persp3d-origin="150 : 33.333333 : 1"
+ id="perspective11" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath2386">
+
+ <rect
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect2388"
+ width="62.61343"
+ height="26.678766"
+ x="124.41016"
+ y="66.515427" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ id="filter3374">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.5296557"
+ id="feGaussianBlur3376" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath3388">
+ <rect
+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3390"
+ width="162.63455"
+ height="49.497475"
+ x="564.81299"
+ y="219.43652"
+ ry="7"
+ rx="7" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath3492">
+
+ <rect
+ y="405"
+ x="51.928932"
+ height="78"
+ width="671"
+ id="rect3494"
+ style="opacity:1;fill:#fa1d24;fill-opacity:1;fill-rule:evenodd;stroke:#919191;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3496"
+ id="radialGradient3502"
+ cx="348.73093"
+ cy="462.78244"
+ fx="348.73093"
+ fy="462.78244"
+ r="30.905592"
+ gradientTransform="matrix(2.4798313,-0.1095192,7.3709675e-2,1.6690008,-546.41268,-274.89586)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <path
+ d="M 37.929003,26.172935 C 39.619294,26.172974 41.272858,26.356703 42.889705,26.724124 C 44.543244,27.09162 45.95796,27.789793 47.13386,28.818643 L 47.18898,28.818643 C 47.482915,29.075899 47.776882,29.20451 48.070882,29.204475 C 48.438309,29.20451 48.860886,29.057526 49.338617,28.763524 C 49.81628,28.432845 50.459333,28.08376 51.267779,27.716265 C 52.076152,27.312096 53.105037,26.963009 54.354437,26.669006 C 55.640505,26.33833 57.275697,26.172974 59.260019,26.172935 C 61.611713,26.172974 63.614365,26.466941 65.267985,27.054838 C 66.921495,27.642809 68.244345,28.469592 69.236545,29.535188 C 70.265375,30.600854 71.000295,31.923706 71.441295,33.50375 C 71.918935,35.047107 72.157785,36.774165 72.157845,38.684926 C 72.157785,40.118041 72.047545,41.661369 71.827135,43.314914 L 69.622375,59.189157 C 69.585575,59.48313 69.438595,59.832216 69.181425,60.236417 C 68.924145,60.603879 68.630175,60.971338 68.299525,61.338795 C 67.968755,61.706257 67.619665,62.018596 67.252265,62.275816 C 66.921495,62.533039 66.645905,62.66165 66.425475,62.661649 L 58.488355,62.661649 C 58.341328,62.66165 58.267836,62.588158 58.26788,62.441173 L 58.26788,62.275816 C 58.378074,61.430662 58.525058,60.401777 58.70883,59.189157 C 58.892517,57.939802 59.076246,56.61695 59.260019,55.220597 C 59.443705,53.787516 59.645807,52.336053 59.866327,50.866203 C 60.086758,49.359635 60.270488,47.926545 60.417517,46.566929 C 60.564455,45.170603 60.693065,43.884496 60.803349,42.708605 C 60.913541,41.532759 60.96866,40.558992 60.968705,39.787304 C 60.96866,38.170509 60.803304,36.847657 60.472634,35.818743 C 60.178622,34.75314 59.792791,33.926357 59.315139,33.338392 C 58.837398,32.713743 58.304582,32.291166 57.71669,32.070658 C 57.165459,31.813468 56.632644,31.684858 56.118242,31.684825 C 55.420029,31.684858 54.813722,31.813468 54.299318,32.070658 C 53.784836,32.291166 53.472497,32.51164 53.362296,32.732084 C 52.994801,33.393542 52.664087,34.146833 52.370156,34.99196 C 52.076152,35.837144 51.800558,36.737418 51.543373,37.692785 C 51.322862,38.648205 51.120759,39.603598 50.937065,40.558968 C 50.7533,41.514385 50.606317,42.433033 50.496114,43.314914 L 48.291358,59.189157 C 48.254579,59.48313 48.107596,59.832216 47.850407,60.236417 C 47.593153,60.603879 47.299185,60.971338 46.968504,61.338795 C 46.637759,61.706257 46.288674,62.018596 45.921245,62.275816 C 45.590501,62.533039 45.314907,62.66165 45.094462,62.661649 L 37.157339,62.661649 C 37.010334,62.66165 36.936843,62.569786 36.936864,62.386055 L 36.936864,62.275816 C 37.047081,61.430662 37.194064,60.401777 37.377815,59.189157 C 37.561523,57.939802 37.745252,56.61695 37.929003,55.220597 C 38.149457,53.787516 38.351559,52.336053 38.535312,50.866203 C 38.755765,49.359635 38.939494,47.926545 39.086501,46.566929 C 39.270207,45.170603 39.398818,43.884496 39.472333,42.708605 C 39.582547,41.532759 39.637666,40.558992 39.637689,39.787304 C 39.637666,38.170509 39.47231,36.847657 39.141621,35.818743 C 38.847629,34.75314 38.461798,33.926357 37.984123,33.338392 C 37.506404,32.713743 36.973588,32.291166 36.385675,32.070658 C 35.834465,31.813468 35.30165,31.684858 34.787227,31.684825 C 34.125781,31.684858 33.537847,31.813468 33.023421,32.070658 C 32.508962,32.291166 32.178249,32.51164 32.031282,32.732084 C 31.663806,33.393542 31.314721,34.146833 30.984022,34.99196 C 30.690039,35.837144 30.414445,36.737418 30.157238,37.692785 C 29.936749,38.648205 29.734646,39.603598 29.550931,40.558968 C 29.403934,41.514385 29.275323,42.433033 29.165099,43.314914 L 27.015462,59.189157 C 26.978704,59.48313 26.813348,59.832216 26.519391,60.236417 C 26.262159,60.603879 25.968192,60.971338 25.637488,61.338795 C 25.306765,61.706257 24.957679,62.018596 24.590229,62.275816 C 24.259507,62.533039 23.983913,62.66165 23.763446,62.661649 L 15.881443,62.661649 C 15.697713,62.66165 15.605849,62.533039 15.605848,62.275816 L 19.960242,30.527329 C 19.996984,30.233395 20.143967,29.884309 20.401193,29.48007 C 20.65841,29.075899 20.952377,28.70844 21.283096,28.377692 C 21.613803,28.010268 21.944516,27.697928 22.275236,27.44067 C 22.642688,27.183485 22.936655,27.054875 23.157138,27.054838 L 24.259517,27.054838 L 27.842245,27.054838 C 28.540405,27.054875 29.07322,27.109993 29.440693,27.220194 C 29.808138,27.293723 30.138852,27.330469 30.432833,27.330433 C 30.653294,27.330469 30.837024,27.293723 30.984022,27.220194 C 33.115269,26.522059 35.411888,26.172974 37.873885,26.172935 L 37.929003,26.172935"
+ id="text2395"
+ style="font-size:66.33274078px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Beroga;-inkscape-font-specification:Beroga"
+ sodipodi:nodetypes="ccccscccssccsccsssccccsssssscccscsscsccsssccccsccccscccscccccccsssccccscsccccsccc" />
+ <path
+ style="fill:#ff6600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 43.769585,0.018545725 C 43.050707,0.041368725 42.33791,0.078284725 41.644585,0.14354573 C 17.725973,2.3949597 -9.424324,33.855034 3.207085,62.018546 C 17.630126,94.176756 57.60396,95.314246 78.425835,75.581046 C 96.766355,58.199462 73.710815,46.282055 62.175835,70.737296 C 52.141432,92.011156 10.145851,89.510836 7.800835,55.237296 C 4.819479,11.663366 48.960105,-8.8810583 75.550835,12.299796 C 67.921275,4.0849567 54.55275,-0.32380227 43.769585,0.018545725 z M 78.175835,59.893546 C 79.704185,59.795515 80.973825,60.263488 81.707085,61.331046 C 83.383105,63.771179 81.593135,68.463516 77.707085,71.799796 C 73.821025,75.136086 69.320615,75.864936 67.644585,73.424796 C 65.968565,70.984666 67.758525,66.29233 71.644585,62.956046 C 73.830485,61.079386 76.210815,60.019586 78.175835,59.893546 z"
+ id="path2406" />
+ <text
+ xml:space="preserve"
+ style="font-size:18px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:URW Chancery L"
+ x="306.18881"
+ y="79.207848"
+ id="text3160"><tspan
+ sodipodi:role="line"
+ id="tspan3162"
+ x="306.18881"
+ y="79.207848" /></text>
+</svg>
diff --git a/data/icons/manaplus.xpm b/data/icons/manaplus.xpm
new file mode 100644
index 000000000..3c8cba0bd
--- /dev/null
+++ b/data/icons/manaplus.xpm
@@ -0,0 +1,40 @@
+/* XPM */
+static char * mana_xpm[] = {
+"32 32 5 1",
+" c None",
+". c #FF6600",
+"+ c #FF6500",
+"@ c #FF6700",
+"# c #FF6400",
+" ...+.....@ ",
+" .....+.......+ ",
+" @....+ .. ",
+" +...+ ",
+" .... ",
+" +... ",
+" ...+ ",
+" +..+ ",
+" #... ",
+" ... ..++ ++++ ",
+" +..+ @+........++....... ",
+" +.. +.....+......++....+ ",
+" ..+ ..... +..... ..... ",
+"+..+ ....+ ..... .... ",
+"+... .... .... .... ",
+"+.. .... .... .... ",
+"+.. +...+ @...+ +.... ",
+"..+ ..... +...+ ..... ",
+"+.. +.... +.... ....+ ",
+"... +...@ ..... +...# ",
+"+.+ ....+ +... ....@ @+. ",
+" .. .... +... +...@++...",
+" +.# ++++ +++@ +++.+# .",
+" ++ ++ .",
+" +. .+ +.",
+" +. .. .. ",
+" .+ @... .+ ",
+" .. ....... ",
+" .. .+.....+ ",
+" ..+ @......+. ",
+" .++..+++.......@ ",
+" ..+.++.+.. "};
diff --git a/data/items.xsd b/data/items.xsd
new file mode 100644
index 000000000..2fb6b6671
--- /dev/null
+++ b/data/items.xsd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <!-- IMAGE TYPE -->
+
+ <xsd:simpleType name="mw_ItemArtType">
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="0" />
+ <xsd:maxInclusive value="1" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- ITEMS LIST FILE SCHEMA -->
+
+ <xsd:element name="items">
+ <xsd:complexType>
+ <xsd:sequence>
+
+ <xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="description" type="xsd:string" />
+ <xsd:attribute name="effect" type="xsd:string" />
+ <xsd:attribute name="id" type="xsd:positiveInteger" />
+ <xsd:attribute name="image" type="xsd:positiveInteger" />
+ <xsd:attribute name="art" type="mw_ItemArtType" />
+ <xsd:attribute name="type" type="xsd:integer" />
+ <xsd:attribute name="slot" type="xsd:integer" />
+ <xsd:attribute name="weight" type="xsd:positiveInteger" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/data/sfx/CMakeLists.txt b/data/sfx/CMakeLists.txt
new file mode 100644
index 000000000..e006c71f1
--- /dev/null
+++ b/data/sfx/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(system)
diff --git a/data/sfx/Makefile.am b/data/sfx/Makefile.am
new file mode 100644
index 000000000..d4008c0dd
--- /dev/null
+++ b/data/sfx/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = system
diff --git a/data/sfx/system/CMakeLists.txt b/data/sfx/system/CMakeLists.txt
new file mode 100644
index 000000000..bf6f0f0f3
--- /dev/null
+++ b/data/sfx/system/CMakeLists.txt
@@ -0,0 +1,5 @@
+SET (FILES
+ newmessage.ogg
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/sfx/system)
diff --git a/data/sfx/system/Makefile.am b/data/sfx/system/Makefile.am
new file mode 100644
index 000000000..e744932c3
--- /dev/null
+++ b/data/sfx/system/Makefile.am
@@ -0,0 +1,8 @@
+systemdir = $(pkgdatadir)/data/sfx/system
+
+system_DATA = \
+ newmessage.ogg
+
+EXTRA_DIST = \
+ $(system_DATA) \
+ CMakeLists.txt
diff --git a/data/sfx/system/newmessage.ogg b/data/sfx/system/newmessage.ogg
new file mode 100644
index 000000000..570a6e51c
--- /dev/null
+++ b/data/sfx/system/newmessage.ogg
Binary files differ
diff --git a/data/themes/CMakeLists.txt b/data/themes/CMakeLists.txt
new file mode 100644
index 000000000..7f3bd69e5
--- /dev/null
+++ b/data/themes/CMakeLists.txt
@@ -0,0 +1,5 @@
+ADD_SUBDIRECTORY(blackwood)
+ADD_SUBDIRECTORY(classic)
+ADD_SUBDIRECTORY(enchilado)
+ADD_SUBDIRECTORY(redandblack)
+ADD_SUBDIRECTORY(wood)
diff --git a/data/themes/Makefile.am b/data/themes/Makefile.am
new file mode 100755
index 000000000..46bcc018d
--- /dev/null
+++ b/data/themes/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = blackwood classic enchilado redandblack wood
diff --git a/data/themes/blackwood/CMakeLists.txt b/data/themes/blackwood/CMakeLists.txt
new file mode 100644
index 000000000..210e5fd4e
--- /dev/null
+++ b/data/themes/blackwood/CMakeLists.txt
@@ -0,0 +1,44 @@
+SET (FILES
+ button.png
+ button_disabled.png
+ buttonhi.png
+ buttonpress.png
+ checkbox.png
+ circle-gray.png
+ circle-green.png
+ close_button.png
+ colors.xml
+ deepbox.png
+ hscroll_left_default.png
+ hscroll_left_highlight.png
+ hscroll_left_pressed.png
+ hscroll_right_default.png
+ hscroll_right_highlight.png
+ hscroll_right_pressed.png
+ item_shortcut_bgr.png
+ mouse.png
+ progress-indicator.png
+ radioin.png
+ radioin_highlight.png
+ radioout.png
+ radioout_highlight.png
+ selection.png
+ slider.png
+ slider_hilight.png
+ speechbubble.xml
+ sticky_button.png
+ tab.png
+ tab_hilight.png
+ tabselected.png
+ vscroll_down_default.png
+ vscroll_down_highlight.png
+ vscroll_down_pressed.png
+ vscroll_grey.png
+ vscroll_highlight.png
+ vscroll_up_default.png
+ vscroll_up_highlight.png
+ vscroll_up_pressed.png
+ window.png
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/themes/blackwood)
diff --git a/data/themes/blackwood/Makefile.am b/data/themes/blackwood/Makefile.am
new file mode 100644
index 000000000..57e9696fa
--- /dev/null
+++ b/data/themes/blackwood/Makefile.am
@@ -0,0 +1,53 @@
+
+guidir = $(pkgdatadir)/data/themes/blackwood
+
+gui_DATA = \
+ button.png \
+ button_disabled.png \
+ buttonhi.png \
+ buttonpress.png \
+ checkbox.png \
+ circle-gray.png \
+ circle-green.png \
+ close_button.png \
+ colors.xml \
+ deepbox.png \
+ hscroll_left_default.png \
+ hscroll_left_highlight.png \
+ hscroll_left_pressed.png \
+ hscroll_right_default.png \
+ hscroll_right_highlight.png \
+ hscroll_right_pressed.png \
+ item_shortcut_bgr.png \
+ mouse.png \
+ progress-indicator.png \
+ radioin.png \
+ radioin_highlight.png \
+ radioout.png \
+ radioout_highlight.png \
+ selection.png \
+ slider.png \
+ slider_hilight.png \
+ speechbubble.xml \
+ sticky_button.png \
+ tab.png \
+ tab_hilight.png \
+ tabselected.png \
+ target-cursor-blue-l.png \
+ target-cursor-blue-m.png \
+ target-cursor-blue-s.png \
+ target-cursor-red-l.png \
+ target-cursor-red-m.png \
+ target-cursor-red-s.png \
+ vscroll_down_default.png \
+ vscroll_down_highlight.png \
+ vscroll_down_pressed.png \
+ vscroll_grey.png \
+ vscroll_highlight.png \
+ vscroll_up_default.png \
+ vscroll_up_highlight.png \
+ vscroll_up_pressed.png \
+ window.png
+
+EXTRA_DIST = \
+ $(gui_DATA)
diff --git a/data/themes/blackwood/button.png b/data/themes/blackwood/button.png
new file mode 100644
index 000000000..842cfe43d
--- /dev/null
+++ b/data/themes/blackwood/button.png
Binary files differ
diff --git a/data/themes/blackwood/button_disabled.png b/data/themes/blackwood/button_disabled.png
new file mode 100644
index 000000000..5472c54f8
--- /dev/null
+++ b/data/themes/blackwood/button_disabled.png
Binary files differ
diff --git a/data/themes/blackwood/buttonhi.png b/data/themes/blackwood/buttonhi.png
new file mode 100644
index 000000000..1f0cabd0a
--- /dev/null
+++ b/data/themes/blackwood/buttonhi.png
Binary files differ
diff --git a/data/themes/blackwood/buttonpress.png b/data/themes/blackwood/buttonpress.png
new file mode 100644
index 000000000..33e1d6a49
--- /dev/null
+++ b/data/themes/blackwood/buttonpress.png
Binary files differ
diff --git a/data/themes/blackwood/checkbox.png b/data/themes/blackwood/checkbox.png
new file mode 100644
index 000000000..828ad572f
--- /dev/null
+++ b/data/themes/blackwood/checkbox.png
Binary files differ
diff --git a/data/themes/blackwood/circle-gray.png b/data/themes/blackwood/circle-gray.png
new file mode 100644
index 000000000..8e099e926
--- /dev/null
+++ b/data/themes/blackwood/circle-gray.png
Binary files differ
diff --git a/data/themes/blackwood/circle-green.png b/data/themes/blackwood/circle-green.png
new file mode 100644
index 000000000..1eb28138a
--- /dev/null
+++ b/data/themes/blackwood/circle-green.png
Binary files differ
diff --git a/data/themes/blackwood/close_button.png b/data/themes/blackwood/close_button.png
new file mode 100644
index 000000000..10ffa7aab
--- /dev/null
+++ b/data/themes/blackwood/close_button.png
Binary files differ
diff --git a/data/themes/blackwood/colors.xml b/data/themes/blackwood/colors.xml
new file mode 100644
index 000000000..75be08349
--- /dev/null
+++ b/data/themes/blackwood/colors.xml
@@ -0,0 +1,52 @@
+<colors>
+ <color id="TEXT" color="#7a7972" />
+ <color id="SHADOW" color="#000000" />
+ <color id="OUTLINE" color="#000000" />
+ <color id="PROGRESS_BAR" color="#ffffff" />
+ <color id="BUTTON" color="#000000" />
+ <color id="BUTTON_DISABLED" color="#333333" />
+ <color id="TAB" color="#000000" />
+ <color id="PARTY_CHAT_TAB" color="#ff00d8" />
+ <color id="PARTY_SOCIAL_TAB" color="#ff00d8" />
+ <color id="GUILD_CHAT_TAB" color="#ff00d8" />
+ <color id="GUILD_SOCIAL_TAB" color="#ff00d8" />
+ <color id="BACKGROUND" color="#ffffff" />
+ <color id="HIGHLIGHT" color="#361c00" />
+ <color id="TAB_FLASH" color="#000000" effect="pulse" />
+ <color id="TAB_PLAYER_FLASH" color="#00ff00" effect="pulse" />
+ <color id="SHOP_WARNING" color="#910000" />
+ <color id="ITEM_EQUIPPED" color="#000091" />
+ <color id="CHAT" color="#744c04" />
+ <color id="GM" color="#ff0000" />
+ <color id="PLAYER" color="#00ff00" />
+ <color id="WHISPER" color="#0000ff" />
+ <color id="WHISPER_OFFLINE" color="#0000e0" />
+ <color id="IS" color="#a08527" />
+ <color id="SERVER" color="#8415e2" />
+ <color id="LOGGER" color="#919191" />
+ <color id="HYPERLINK" color="#e50d0d" />
+ <color id="UNKNOWN_ITEM" color="#000000" />
+ <color id="GENERIC" color="#21a5b1" />
+ <color id="HEAD" color="#527fa4" />
+ <color id="USABLE" color="#268d24" />
+ <color id="TORSO" color="#d12aa4" />
+ <color id="ONEHAND" color="#f42a2a" />
+ <color id="LEGS" color="#699900" />
+ <color id="FEET" color="#aa1d48" />
+ <color id="TWOHAND" color="#f46d0e" />
+ <color id="SHIELD" color="#9c2424" />
+ <color id="RING" color="#0000ff" />
+ <color id="NECKLACE" color="#ff00ff" />
+ <color id="ARMS" color="#d26311" />
+ <color id="AMMO" color="#aa3c05" />
+ <color id="WARNING" color="#FF0000" />
+
+ <progressbar id="DEFAULT" color="#969696" />
+ <progressbar id="HP" color="#ff0000,e28000,c38948,0f6a20" />
+ <progressbar id="MP" color="#1a66e6" />
+ <progressbar id="NO_MP" color="#646464" />
+ <progressbar id="EXP" color="#8fc0d3" />
+ <progressbar id="INVY_SLOTS" color="#e1c819" />
+ <progressbar id="WEIGHT" color="#0000ff,ffff00,ff0000" />
+ <progressbar id="JOB" color="#e187cb" />
+</colors>
diff --git a/data/themes/blackwood/deepbox.png b/data/themes/blackwood/deepbox.png
new file mode 100644
index 000000000..267e867f1
--- /dev/null
+++ b/data/themes/blackwood/deepbox.png
Binary files differ
diff --git a/data/themes/blackwood/hscroll_left_default.png b/data/themes/blackwood/hscroll_left_default.png
new file mode 100644
index 000000000..79fccdf0b
--- /dev/null
+++ b/data/themes/blackwood/hscroll_left_default.png
Binary files differ
diff --git a/data/themes/blackwood/hscroll_left_highlight.png b/data/themes/blackwood/hscroll_left_highlight.png
new file mode 100644
index 000000000..b840da8a9
--- /dev/null
+++ b/data/themes/blackwood/hscroll_left_highlight.png
Binary files differ
diff --git a/data/themes/blackwood/hscroll_left_pressed.png b/data/themes/blackwood/hscroll_left_pressed.png
new file mode 100644
index 000000000..d5e8ac5f1
--- /dev/null
+++ b/data/themes/blackwood/hscroll_left_pressed.png
Binary files differ
diff --git a/data/themes/blackwood/hscroll_right_default.png b/data/themes/blackwood/hscroll_right_default.png
new file mode 100644
index 000000000..772146bc2
--- /dev/null
+++ b/data/themes/blackwood/hscroll_right_default.png
Binary files differ
diff --git a/data/themes/blackwood/hscroll_right_highlight.png b/data/themes/blackwood/hscroll_right_highlight.png
new file mode 100644
index 000000000..f5598b333
--- /dev/null
+++ b/data/themes/blackwood/hscroll_right_highlight.png
Binary files differ
diff --git a/data/themes/blackwood/hscroll_right_pressed.png b/data/themes/blackwood/hscroll_right_pressed.png
new file mode 100644
index 000000000..c456bdd18
--- /dev/null
+++ b/data/themes/blackwood/hscroll_right_pressed.png
Binary files differ
diff --git a/data/themes/blackwood/item_shortcut_bgr.png b/data/themes/blackwood/item_shortcut_bgr.png
new file mode 100644
index 000000000..b2fa9d39a
--- /dev/null
+++ b/data/themes/blackwood/item_shortcut_bgr.png
Binary files differ
diff --git a/data/themes/blackwood/mouse.png b/data/themes/blackwood/mouse.png
new file mode 100644
index 000000000..c01e27b90
--- /dev/null
+++ b/data/themes/blackwood/mouse.png
Binary files differ
diff --git a/data/themes/blackwood/progress-indicator.png b/data/themes/blackwood/progress-indicator.png
new file mode 100644
index 000000000..0d525b3fb
--- /dev/null
+++ b/data/themes/blackwood/progress-indicator.png
Binary files differ
diff --git a/data/themes/blackwood/radioin.png b/data/themes/blackwood/radioin.png
new file mode 100644
index 000000000..bd7958c7d
--- /dev/null
+++ b/data/themes/blackwood/radioin.png
Binary files differ
diff --git a/data/themes/blackwood/radioin_highlight.png b/data/themes/blackwood/radioin_highlight.png
new file mode 100644
index 000000000..9b6964bda
--- /dev/null
+++ b/data/themes/blackwood/radioin_highlight.png
Binary files differ
diff --git a/data/themes/blackwood/radioout.png b/data/themes/blackwood/radioout.png
new file mode 100644
index 000000000..57b9f0e70
--- /dev/null
+++ b/data/themes/blackwood/radioout.png
Binary files differ
diff --git a/data/themes/blackwood/radioout_highlight.png b/data/themes/blackwood/radioout_highlight.png
new file mode 100644
index 000000000..645c9fee3
--- /dev/null
+++ b/data/themes/blackwood/radioout_highlight.png
Binary files differ
diff --git a/data/themes/blackwood/selection.png b/data/themes/blackwood/selection.png
new file mode 100644
index 000000000..9a191818b
--- /dev/null
+++ b/data/themes/blackwood/selection.png
Binary files differ
diff --git a/data/themes/blackwood/slider.png b/data/themes/blackwood/slider.png
new file mode 100644
index 000000000..5a68e0f9b
--- /dev/null
+++ b/data/themes/blackwood/slider.png
Binary files differ
diff --git a/data/themes/blackwood/slider_hilight.png b/data/themes/blackwood/slider_hilight.png
new file mode 100644
index 000000000..6dd783fe0
--- /dev/null
+++ b/data/themes/blackwood/slider_hilight.png
Binary files differ
diff --git a/data/themes/blackwood/speech_bubble.png b/data/themes/blackwood/speech_bubble.png
new file mode 100644
index 000000000..3e678099b
--- /dev/null
+++ b/data/themes/blackwood/speech_bubble.png
Binary files differ
diff --git a/data/themes/blackwood/speechbubble.xml b/data/themes/blackwood/speechbubble.xml
new file mode 100644
index 000000000..2be1fb8b4
--- /dev/null
+++ b/data/themes/blackwood/speechbubble.xml
@@ -0,0 +1,18 @@
+<skinset name="SpeechBubble" image="bubble.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="5" height="5" />
+ <part type="top-edge" xpos="5" ypos="0" width="5" height="5" />
+ <part type="top-right-corner" xpos="10" ypos="0" width="5" height="5" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="10" ypos="5" width="5" height="5" />
+ <part type="bg-quad" xpos="15" ypos="5" width="5" height="5" />
+ <part type="right-edge" xpos="10" ypos="5" width="5" height="5" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="10" width="5" height="5" />
+ <part type="bottom-edge" xpos="5" ypos="10" width="5" height="5" />
+ <part type="bottom-right-corner" xpos="10" ypos="10" width="5" height="5" />
+ </widget>
+</skinset>
diff --git a/data/themes/blackwood/sticky_button.png b/data/themes/blackwood/sticky_button.png
new file mode 100644
index 000000000..b2ab5b7e3
--- /dev/null
+++ b/data/themes/blackwood/sticky_button.png
Binary files differ
diff --git a/data/themes/blackwood/tab.png b/data/themes/blackwood/tab.png
new file mode 100644
index 000000000..e04629fb0
--- /dev/null
+++ b/data/themes/blackwood/tab.png
Binary files differ
diff --git a/data/themes/blackwood/tab_hilight.png b/data/themes/blackwood/tab_hilight.png
new file mode 100644
index 000000000..2549209d9
--- /dev/null
+++ b/data/themes/blackwood/tab_hilight.png
Binary files differ
diff --git a/data/themes/blackwood/tabselected.png b/data/themes/blackwood/tabselected.png
new file mode 100644
index 000000000..bc0c6edf3
--- /dev/null
+++ b/data/themes/blackwood/tabselected.png
Binary files differ
diff --git a/data/themes/blackwood/target-cursor-blue-l.png b/data/themes/blackwood/target-cursor-blue-l.png
new file mode 100644
index 000000000..88d0bf40e
--- /dev/null
+++ b/data/themes/blackwood/target-cursor-blue-l.png
Binary files differ
diff --git a/data/themes/blackwood/target-cursor-blue-m.png b/data/themes/blackwood/target-cursor-blue-m.png
new file mode 100644
index 000000000..ac0189d0f
--- /dev/null
+++ b/data/themes/blackwood/target-cursor-blue-m.png
Binary files differ
diff --git a/data/themes/blackwood/target-cursor-blue-s.png b/data/themes/blackwood/target-cursor-blue-s.png
new file mode 100644
index 000000000..90b22d72d
--- /dev/null
+++ b/data/themes/blackwood/target-cursor-blue-s.png
Binary files differ
diff --git a/data/themes/blackwood/target-cursor-red-l.png b/data/themes/blackwood/target-cursor-red-l.png
new file mode 100644
index 000000000..776c8acdf
--- /dev/null
+++ b/data/themes/blackwood/target-cursor-red-l.png
Binary files differ
diff --git a/data/themes/blackwood/target-cursor-red-m.png b/data/themes/blackwood/target-cursor-red-m.png
new file mode 100644
index 000000000..af657dc14
--- /dev/null
+++ b/data/themes/blackwood/target-cursor-red-m.png
Binary files differ
diff --git a/data/themes/blackwood/target-cursor-red-s.png b/data/themes/blackwood/target-cursor-red-s.png
new file mode 100644
index 000000000..090ec040d
--- /dev/null
+++ b/data/themes/blackwood/target-cursor-red-s.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_down_default.png b/data/themes/blackwood/vscroll_down_default.png
new file mode 100644
index 000000000..ecded0eb7
--- /dev/null
+++ b/data/themes/blackwood/vscroll_down_default.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_down_highlight.png b/data/themes/blackwood/vscroll_down_highlight.png
new file mode 100644
index 000000000..bdae7eab2
--- /dev/null
+++ b/data/themes/blackwood/vscroll_down_highlight.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_down_pressed.png b/data/themes/blackwood/vscroll_down_pressed.png
new file mode 100644
index 000000000..3a66bd86f
--- /dev/null
+++ b/data/themes/blackwood/vscroll_down_pressed.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_grey.png b/data/themes/blackwood/vscroll_grey.png
new file mode 100644
index 000000000..98143a824
--- /dev/null
+++ b/data/themes/blackwood/vscroll_grey.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_highlight.png b/data/themes/blackwood/vscroll_highlight.png
new file mode 100644
index 000000000..0e8c66c2b
--- /dev/null
+++ b/data/themes/blackwood/vscroll_highlight.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_up_default.png b/data/themes/blackwood/vscroll_up_default.png
new file mode 100644
index 000000000..5826f82c3
--- /dev/null
+++ b/data/themes/blackwood/vscroll_up_default.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_up_highlight.png b/data/themes/blackwood/vscroll_up_highlight.png
new file mode 100644
index 000000000..956004b12
--- /dev/null
+++ b/data/themes/blackwood/vscroll_up_highlight.png
Binary files differ
diff --git a/data/themes/blackwood/vscroll_up_pressed.png b/data/themes/blackwood/vscroll_up_pressed.png
new file mode 100644
index 000000000..73f38e8ed
--- /dev/null
+++ b/data/themes/blackwood/vscroll_up_pressed.png
Binary files differ
diff --git a/data/themes/blackwood/window.png b/data/themes/blackwood/window.png
new file mode 100644
index 000000000..fffd82050
--- /dev/null
+++ b/data/themes/blackwood/window.png
Binary files differ
diff --git a/data/themes/classic/CMakeLists.txt b/data/themes/classic/CMakeLists.txt
new file mode 100644
index 000000000..bee9d4157
--- /dev/null
+++ b/data/themes/classic/CMakeLists.txt
@@ -0,0 +1,54 @@
+SET (FILES
+ bubble.png
+ button.png
+ button_disabled.png
+ buttonhi.png
+ buttonpress.png
+ checkbox.png
+ circle-gray.png
+ circle-green.png
+ close_button.png
+ colors.xml
+ deepbox.png
+ hscroll_left_default.png
+ hscroll_left_highlight.png
+ hscroll_left_pressed.png
+ hscroll_right_default.png
+ hscroll_right_highlight.png
+ hscroll_right_pressed.png
+ item_shortcut_bgr.png
+ mouse.png
+ progress-indicator.png
+ radioin.png
+ radioin_highlight.png
+ radioout.png
+ radioout_highlight.png
+ resize.png
+ selection.png
+ slider.png
+ slider_hilight.png
+ speechbubble.xml
+ sticky_button.png
+ tab.png
+ tab_hilight.png
+ tabselected.png
+ target-cursor-blue-l.png
+ target-cursor-blue-m.png
+ target-cursor-blue-s.png
+ target-cursor-red-l.png
+ target-cursor-red-m.png
+ target-cursor-red-s.png
+ unknown-item.png
+ vscroll_down_default.png
+ vscroll_down_highlight.png
+ vscroll_down_pressed.png
+ vscroll_grey.png
+ vscroll_highlight.png
+ vscroll_up_default.png
+ vscroll_up_highlight.png
+ vscroll_up_pressed.png
+ window.png
+ window.xml
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/themes/classic)
diff --git a/data/themes/classic/Makefile.am b/data/themes/classic/Makefile.am
new file mode 100755
index 000000000..6be1a154a
--- /dev/null
+++ b/data/themes/classic/Makefile.am
@@ -0,0 +1,56 @@
+
+guidir = $(pkgdatadir)/data/themes/classic
+
+gui_DATA = \
+ bubble.png \
+ button.png \
+ button_disabled.png \
+ buttonhi.png \
+ buttonpress.png \
+ checkbox.png \
+ circle-gray.png \
+ circle-green.png \
+ close_button.png \
+ colors.xml \
+ deepbox.png \
+ window.xml \
+ hscroll_left_default.png \
+ hscroll_left_highlight.png \
+ hscroll_left_pressed.png \
+ hscroll_right_default.png \
+ hscroll_right_highlight.png \
+ hscroll_right_pressed.png \
+ item_shortcut_bgr.png \
+ mouse.png \
+ radioin.png \
+ radioin_highlight.png \
+ radioout.png \
+ radioout_highlight.png \
+ resize.png \
+ selection.png \
+ slider.png \
+ slider_hilight.png \
+ speechbubble.xml \
+ sticky_button.png \
+ tab.png \
+ tab_hilight.png \
+ tabselected.png \
+ target-cursor-blue-l.png \
+ target-cursor-blue-m.png \
+ target-cursor-blue-s.png \
+ target-cursor-red-l.png \
+ target-cursor-red-m.png \
+ target-cursor-red-s.png \
+ unknown-item.png \
+ vscroll_down_default.png \
+ vscroll_down_highlight.png \
+ vscroll_down_pressed.png \
+ vscroll_grey.png \
+ vscroll_highlight.png \
+ vscroll_up_default.png \
+ vscroll_up_highlight.png \
+ vscroll_up_pressed.png \
+ window.png
+
+EXTRA_DIST = \
+ $(gui_DATA)
diff --git a/data/themes/classic/bubble.png b/data/themes/classic/bubble.png
new file mode 100755
index 000000000..45322eb2e
--- /dev/null
+++ b/data/themes/classic/bubble.png
Binary files differ
diff --git a/data/themes/classic/button.png b/data/themes/classic/button.png
new file mode 100755
index 000000000..9ebbea639
--- /dev/null
+++ b/data/themes/classic/button.png
Binary files differ
diff --git a/data/themes/classic/button_disabled.png b/data/themes/classic/button_disabled.png
new file mode 100755
index 000000000..0ce3aa6ff
--- /dev/null
+++ b/data/themes/classic/button_disabled.png
Binary files differ
diff --git a/data/themes/classic/buttonhi.png b/data/themes/classic/buttonhi.png
new file mode 100755
index 000000000..c47726346
--- /dev/null
+++ b/data/themes/classic/buttonhi.png
Binary files differ
diff --git a/data/themes/classic/buttonpress.png b/data/themes/classic/buttonpress.png
new file mode 100755
index 000000000..e9cd17653
--- /dev/null
+++ b/data/themes/classic/buttonpress.png
Binary files differ
diff --git a/data/themes/classic/checkbox.png b/data/themes/classic/checkbox.png
new file mode 100644
index 000000000..29b64100a
--- /dev/null
+++ b/data/themes/classic/checkbox.png
Binary files differ
diff --git a/data/themes/classic/circle-gray.png b/data/themes/classic/circle-gray.png
new file mode 100755
index 000000000..3e884f405
--- /dev/null
+++ b/data/themes/classic/circle-gray.png
Binary files differ
diff --git a/data/themes/classic/circle-green.png b/data/themes/classic/circle-green.png
new file mode 100755
index 000000000..2c98e9ef1
--- /dev/null
+++ b/data/themes/classic/circle-green.png
Binary files differ
diff --git a/data/themes/classic/close_button.png b/data/themes/classic/close_button.png
new file mode 100755
index 000000000..f87cc2a91
--- /dev/null
+++ b/data/themes/classic/close_button.png
Binary files differ
diff --git a/data/themes/classic/colors.xml b/data/themes/classic/colors.xml
new file mode 100644
index 000000000..e25f8636c
--- /dev/null
+++ b/data/themes/classic/colors.xml
@@ -0,0 +1,53 @@
+<colors>
+ <color id="TEXT" color="#000000" />
+ <color id="SHADOW" color="#000000" />
+ <color id="OUTLINE" color="#000000" />
+ <color id="PROGRESS_BAR" color="#ffffff" />
+ <color id="BUTTON" color="#000000" />
+ <color id="BUTTON_DISABLED" color="#333333" />
+ <color id="TAB" color="#000000" />
+ <color id="PARTY_CHAT_TAB" color="#f48055" />
+ <color id="PARTY_SOCIAL_TAB" color="#f48055" />
+ <color id="GUILD_CHAT_TAB" color="#f48055" />
+ <color id="GUILD_SOCIAL_TAB" color="#f48055" />
+ <color id="BACKGROUND" color="#ffffff" />
+ <color id="HIGHLIGHT" color="#ebc873" />
+ <color id="TAB_FLASH" color="#ff0000" effect="pulse" />
+ <color id="TAB_PLAYER_FLASH" color="#00ff00" effect="pulse" />
+ <color id="SHOP_WARNING" color="#910000" />
+ <color id="ITEM_EQUIPPED" color="#000091" />
+ <color id="CHAT" color="#000000" />
+ <color id="GM" color="#ff0000" />
+ <color id="PLAYER" color="#009000" />
+ <color id="WHISPER" color="#0000ff" />
+ <color id="WHISPER_OFFLINE" color="#000050" />
+ <color id="IS" color="#705000" />
+ <color id="SERVER" color="#8415e2" />
+ <color id="LOGGER" color="#919191" />
+ <color id="HYPERLINK" color="#e50d0d" />
+ <color id="UNKNOWN_ITEM" color="#000000" />
+ <color id="GENERIC" color="#21a5b1" />
+ <color id="HEAD" color="#527fa4" />
+ <color id="USABLE" color="#268d24" />
+ <color id="TORSO" color="#d12aa4" />
+ <color id="ONEHAND" color="#f42a2a" />
+ <color id="LEGS" color="#699900" />
+ <color id="FEET" color="#aa1d48" />
+ <color id="TWOHAND" color="#f46d0e" />
+ <color id="SHIELD" color="#9c2424" />
+ <color id="RING" color="#0000ff" />
+ <color id="NECKLACE" color="#ff00ff" />
+ <color id="ARMS" color="#9c24e8" />
+ <color id="AMMO" color="#8b6311" />
+ <color id="SERVER_VERSION_NOT_SUPPORTED" color="#DC0000" />
+ <color id="WARNING" color="#FF0000" />
+
+ <progressbar id="DEFAULT" color="#969696" />
+ <progressbar id="HP" color="#ff0000,e28000,c38948,0f6a20" />
+ <progressbar id="MP" color="#1a66e6" />
+ <progressbar id="NO_MP" color="#646464" />
+ <progressbar id="EXP" color="#8fc0d3" />
+ <progressbar id="INVY_SLOTS" color="#e1c819" />
+ <progressbar id="WEIGHT" color="#0000ff,ffff00,ff0000" />
+ <progressbar id="JOB" color="#e187cb" />
+</colors>
diff --git a/data/themes/classic/deepbox.png b/data/themes/classic/deepbox.png
new file mode 100755
index 000000000..084b5f618
--- /dev/null
+++ b/data/themes/classic/deepbox.png
Binary files differ
diff --git a/data/themes/classic/hscroll_left_default.png b/data/themes/classic/hscroll_left_default.png
new file mode 100755
index 000000000..2f763d302
--- /dev/null
+++ b/data/themes/classic/hscroll_left_default.png
Binary files differ
diff --git a/data/themes/classic/hscroll_left_highlight.png b/data/themes/classic/hscroll_left_highlight.png
new file mode 100755
index 000000000..6be5ae259
--- /dev/null
+++ b/data/themes/classic/hscroll_left_highlight.png
Binary files differ
diff --git a/data/themes/classic/hscroll_left_pressed.png b/data/themes/classic/hscroll_left_pressed.png
new file mode 100755
index 000000000..b8ebcb463
--- /dev/null
+++ b/data/themes/classic/hscroll_left_pressed.png
Binary files differ
diff --git a/data/themes/classic/hscroll_right_default.png b/data/themes/classic/hscroll_right_default.png
new file mode 100755
index 000000000..33fdddd0a
--- /dev/null
+++ b/data/themes/classic/hscroll_right_default.png
Binary files differ
diff --git a/data/themes/classic/hscroll_right_highlight.png b/data/themes/classic/hscroll_right_highlight.png
new file mode 100755
index 000000000..e9e633eac
--- /dev/null
+++ b/data/themes/classic/hscroll_right_highlight.png
Binary files differ
diff --git a/data/themes/classic/hscroll_right_pressed.png b/data/themes/classic/hscroll_right_pressed.png
new file mode 100755
index 000000000..53972f2bb
--- /dev/null
+++ b/data/themes/classic/hscroll_right_pressed.png
Binary files differ
diff --git a/data/themes/classic/item_shortcut_bgr.png b/data/themes/classic/item_shortcut_bgr.png
new file mode 100755
index 000000000..0543e38ac
--- /dev/null
+++ b/data/themes/classic/item_shortcut_bgr.png
Binary files differ
diff --git a/data/themes/classic/mouse.png b/data/themes/classic/mouse.png
new file mode 100644
index 000000000..df460e49c
--- /dev/null
+++ b/data/themes/classic/mouse.png
Binary files differ
diff --git a/data/themes/classic/progress-indicator.png b/data/themes/classic/progress-indicator.png
new file mode 100644
index 000000000..907f334eb
--- /dev/null
+++ b/data/themes/classic/progress-indicator.png
Binary files differ
diff --git a/data/themes/classic/radioin.png b/data/themes/classic/radioin.png
new file mode 100755
index 000000000..12e027fec
--- /dev/null
+++ b/data/themes/classic/radioin.png
Binary files differ
diff --git a/data/themes/classic/radioin_highlight.png b/data/themes/classic/radioin_highlight.png
new file mode 100644
index 000000000..b193d3e30
--- /dev/null
+++ b/data/themes/classic/radioin_highlight.png
Binary files differ
diff --git a/data/themes/classic/radioout.png b/data/themes/classic/radioout.png
new file mode 100755
index 000000000..5eb67bd85
--- /dev/null
+++ b/data/themes/classic/radioout.png
Binary files differ
diff --git a/data/themes/classic/radioout_highlight.png b/data/themes/classic/radioout_highlight.png
new file mode 100644
index 000000000..dd31e6e30
--- /dev/null
+++ b/data/themes/classic/radioout_highlight.png
Binary files differ
diff --git a/data/themes/classic/resize.png b/data/themes/classic/resize.png
new file mode 100755
index 000000000..6b31ac64b
--- /dev/null
+++ b/data/themes/classic/resize.png
Binary files differ
diff --git a/data/themes/classic/selection.png b/data/themes/classic/selection.png
new file mode 100644
index 000000000..78827dafa
--- /dev/null
+++ b/data/themes/classic/selection.png
Binary files differ
diff --git a/data/themes/classic/slider.png b/data/themes/classic/slider.png
new file mode 100755
index 000000000..465ad0e88
--- /dev/null
+++ b/data/themes/classic/slider.png
Binary files differ
diff --git a/data/themes/classic/slider_hilight.png b/data/themes/classic/slider_hilight.png
new file mode 100644
index 000000000..37c780cd1
--- /dev/null
+++ b/data/themes/classic/slider_hilight.png
Binary files differ
diff --git a/data/themes/classic/speechbubble.xml b/data/themes/classic/speechbubble.xml
new file mode 100755
index 000000000..84b6557b3
--- /dev/null
+++ b/data/themes/classic/speechbubble.xml
@@ -0,0 +1,18 @@
+<skinset name="SpeechBubble" image="bubble.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="5" height="5" />
+ <part type="top-edge" xpos="5" ypos="0" width="5" height="5" />
+ <part type="top-right-corner" xpos="10" ypos="0" width="5" height="5" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="5" width="5" height="5" />
+ <part type="bg-quad" xpos="5" ypos="5" width="5" height="5" />
+ <part type="right-edge" xpos="10" ypos="5" width="5" height="5" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="10" width="5" height="5" />
+ <part type="bottom-edge" xpos="5" ypos="10" width="5" height="5" />
+ <part type="bottom-right-corner" xpos="10" ypos="10" width="5" height="5" />
+ </widget>
+</skinset>
diff --git a/data/themes/classic/sticky_button.png b/data/themes/classic/sticky_button.png
new file mode 100755
index 000000000..8c5705736
--- /dev/null
+++ b/data/themes/classic/sticky_button.png
Binary files differ
diff --git a/data/themes/classic/tab.png b/data/themes/classic/tab.png
new file mode 100755
index 000000000..91eadf08f
--- /dev/null
+++ b/data/themes/classic/tab.png
Binary files differ
diff --git a/data/themes/classic/tab_hilight.png b/data/themes/classic/tab_hilight.png
new file mode 100644
index 000000000..f6b39942d
--- /dev/null
+++ b/data/themes/classic/tab_hilight.png
Binary files differ
diff --git a/data/themes/classic/tabselected.png b/data/themes/classic/tabselected.png
new file mode 100755
index 000000000..e2983060c
--- /dev/null
+++ b/data/themes/classic/tabselected.png
Binary files differ
diff --git a/data/themes/classic/target-cursor-blue-l.png b/data/themes/classic/target-cursor-blue-l.png
new file mode 100755
index 000000000..77cdf4b6d
--- /dev/null
+++ b/data/themes/classic/target-cursor-blue-l.png
Binary files differ
diff --git a/data/themes/classic/target-cursor-blue-m.png b/data/themes/classic/target-cursor-blue-m.png
new file mode 100755
index 000000000..c0107357a
--- /dev/null
+++ b/data/themes/classic/target-cursor-blue-m.png
Binary files differ
diff --git a/data/themes/classic/target-cursor-blue-s.png b/data/themes/classic/target-cursor-blue-s.png
new file mode 100755
index 000000000..3e81c75de
--- /dev/null
+++ b/data/themes/classic/target-cursor-blue-s.png
Binary files differ
diff --git a/data/themes/classic/target-cursor-red-l.png b/data/themes/classic/target-cursor-red-l.png
new file mode 100755
index 000000000..76d2101b1
--- /dev/null
+++ b/data/themes/classic/target-cursor-red-l.png
Binary files differ
diff --git a/data/themes/classic/target-cursor-red-m.png b/data/themes/classic/target-cursor-red-m.png
new file mode 100755
index 000000000..e2ab79c29
--- /dev/null
+++ b/data/themes/classic/target-cursor-red-m.png
Binary files differ
diff --git a/data/themes/classic/target-cursor-red-s.png b/data/themes/classic/target-cursor-red-s.png
new file mode 100755
index 000000000..09195f440
--- /dev/null
+++ b/data/themes/classic/target-cursor-red-s.png
Binary files differ
diff --git a/data/themes/classic/unknown-item.png b/data/themes/classic/unknown-item.png
new file mode 100755
index 000000000..9201d688e
--- /dev/null
+++ b/data/themes/classic/unknown-item.png
Binary files differ
diff --git a/data/themes/classic/vscroll_down_default.png b/data/themes/classic/vscroll_down_default.png
new file mode 100755
index 000000000..c4292489e
--- /dev/null
+++ b/data/themes/classic/vscroll_down_default.png
Binary files differ
diff --git a/data/themes/classic/vscroll_down_highlight.png b/data/themes/classic/vscroll_down_highlight.png
new file mode 100755
index 000000000..ac88f7c73
--- /dev/null
+++ b/data/themes/classic/vscroll_down_highlight.png
Binary files differ
diff --git a/data/themes/classic/vscroll_down_pressed.png b/data/themes/classic/vscroll_down_pressed.png
new file mode 100755
index 000000000..9dcc89f6f
--- /dev/null
+++ b/data/themes/classic/vscroll_down_pressed.png
Binary files differ
diff --git a/data/themes/classic/vscroll_grey.png b/data/themes/classic/vscroll_grey.png
new file mode 100755
index 000000000..f99da4676
--- /dev/null
+++ b/data/themes/classic/vscroll_grey.png
Binary files differ
diff --git a/data/themes/classic/vscroll_highlight.png b/data/themes/classic/vscroll_highlight.png
new file mode 100644
index 000000000..2e0fcbfc1
--- /dev/null
+++ b/data/themes/classic/vscroll_highlight.png
Binary files differ
diff --git a/data/themes/classic/vscroll_up_default.png b/data/themes/classic/vscroll_up_default.png
new file mode 100755
index 000000000..1cecc3512
--- /dev/null
+++ b/data/themes/classic/vscroll_up_default.png
Binary files differ
diff --git a/data/themes/classic/vscroll_up_highlight.png b/data/themes/classic/vscroll_up_highlight.png
new file mode 100755
index 000000000..7b5009f39
--- /dev/null
+++ b/data/themes/classic/vscroll_up_highlight.png
Binary files differ
diff --git a/data/themes/classic/vscroll_up_pressed.png b/data/themes/classic/vscroll_up_pressed.png
new file mode 100755
index 000000000..2320ec42f
--- /dev/null
+++ b/data/themes/classic/vscroll_up_pressed.png
Binary files differ
diff --git a/data/themes/classic/window.png b/data/themes/classic/window.png
new file mode 100755
index 000000000..f0ef1af4b
--- /dev/null
+++ b/data/themes/classic/window.png
Binary files differ
diff --git a/data/themes/classic/window.xml b/data/themes/classic/window.xml
new file mode 100755
index 000000000..f27dbc7f3
--- /dev/null
+++ b/data/themes/classic/window.xml
@@ -0,0 +1,18 @@
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="4" height="4" />
+ <part type="top-edge" xpos="4" ypos="0" width="32" height="4" />
+ <part type="top-right-corner" xpos="36" ypos="0" width="4" height="4" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="4" width="4" height="216" />
+ <part type="bg-quad" xpos="4" ypos="4" width="32" height="216" />
+ <part type="right-edge" xpos="36" ypos="4" width="4" height="216" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="220" width="4" height="4" />
+ <part type="bottom-edge" xpos="4" ypos="220" width="32" height="4" />
+ <part type="bottom-right-corner" xpos="36" ypos="220" width="4" height="4" />
+ </widget>
+</skinset>
diff --git a/data/themes/enchilado/CMakeLists.txt b/data/themes/enchilado/CMakeLists.txt
new file mode 100644
index 000000000..8b6277eaf
--- /dev/null
+++ b/data/themes/enchilado/CMakeLists.txt
@@ -0,0 +1,14 @@
+SET (FILES
+ button.png
+ button_disabled.png
+ buttonhi.png
+ buttonpress.png
+ colors.xml
+ tab.png
+ tab_hilight.png
+ tabselected.png
+ window.png
+ window.xml
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/themes/enchilado)
diff --git a/data/themes/enchilado/Makefile.am b/data/themes/enchilado/Makefile.am
new file mode 100755
index 000000000..4e09c11f1
--- /dev/null
+++ b/data/themes/enchilado/Makefile.am
@@ -0,0 +1,17 @@
+
+guidir = $(pkgdatadir)/data/themes/enchilado
+
+gui_DATA = \
+ button.png \
+ button_disabled.png \
+ buttonhi.png \
+ buttonpress.png \
+ colors.xml \
+ tab.png \
+ tab_hilight.png \
+ tabselected.png \
+ window.png \
+ window.xml
+
+EXTRA_DIST = \
+ $(gui_DATA)
diff --git a/data/themes/enchilado/button.png b/data/themes/enchilado/button.png
new file mode 100644
index 000000000..f6fdeaa9e
--- /dev/null
+++ b/data/themes/enchilado/button.png
Binary files differ
diff --git a/data/themes/enchilado/button_disabled.png b/data/themes/enchilado/button_disabled.png
new file mode 100644
index 000000000..d570fbad8
--- /dev/null
+++ b/data/themes/enchilado/button_disabled.png
Binary files differ
diff --git a/data/themes/enchilado/buttonhi.png b/data/themes/enchilado/buttonhi.png
new file mode 100644
index 000000000..6e2575c1b
--- /dev/null
+++ b/data/themes/enchilado/buttonhi.png
Binary files differ
diff --git a/data/themes/enchilado/buttonpress.png b/data/themes/enchilado/buttonpress.png
new file mode 100644
index 000000000..03b01d4f2
--- /dev/null
+++ b/data/themes/enchilado/buttonpress.png
Binary files differ
diff --git a/data/themes/enchilado/colors.xml b/data/themes/enchilado/colors.xml
new file mode 100644
index 000000000..026c150a5
--- /dev/null
+++ b/data/themes/enchilado/colors.xml
@@ -0,0 +1,53 @@
+<colors>
+ <color id="TEXT" color="#000000" />
+ <color id="SHADOW" color="#000000" />
+ <color id="OUTLINE" color="#000000" />
+ <color id="PROGRESS_BAR" color="#ffffff" />
+ <color id="BUTTON" color="#000000" />
+ <color id="BUTTON_DISABLED" color="#333333" />
+ <color id="TAB" color="#000000" />
+ <color id="PARTY_CHAT_TAB" color="#f48055" />
+ <color id="PARTY_SOCIAL_TAB" color="#f48055" />
+ <color id="GUILD_CHAT_TAB" color="#f48055" />
+ <color id="GUILD_SOCIAL_TAB" color="#f48055" />
+ <color id="BACKGROUND" color="#ffffff" />
+ <color id="HIGHLIGHT" color="#ebc873" />
+ <color id="TAB_FLASH" color="#ff0000" effect="pulse" />
+ <color id="TAB_PLAYER_FLASH" color="#00ff00" effect="pulse" />
+ <color id="SHOP_WARNING" color="#910000" />
+ <color id="ITEM_EQUIPPED" color="#000091" />
+ <color id="CHAT" color="#000000" />
+ <color id="GM" color="#ff0000" />
+ <color id="PLAYER" color="#009000" />
+ <color id="WHISPER" color="#0000ff" />
+ <color id="WHISPER_OFFLINE" color="#000050" />
+ <color id="IS" color="#705000" />
+ <color id="SERVER" color="#8415e2" />
+ <color id="LOGGER" color="#919191" />
+ <color id="HYPERLINK" color="#e50d0d" />
+ <color id="UNKNOWN_ITEM" color="#000000" />
+ <color id="GENERIC" color="#21a5b1" />
+ <color id="HEAD" color="#527fa4" />
+ <color id="USABLE" color="#268d24" />
+ <color id="TORSO" color="#d12aa4" />
+ <color id="ONEHAND" color="#f42a2a" />
+ <color id="LEGS" color="#699900" />
+ <color id="FEET" color="#aa1d48" />
+ <color id="TWOHAND" color="#f46d0e" />
+ <color id="SHIELD" color="#9c2424" />
+ <color id="RING" color="#0000ff" />
+ <color id="NECKLACE" color="#ff00ff" />
+ <color id="ARMS" color="#9c24e8" />
+ <color id="AMMO" color="#8b6311" />
+ <color id="SERVER_VERSION_NOT_SUPPORTED" color="#DC0000" />
+ <color id="WARNING" color="#FF0000" />
+
+ <progressbar id="DEFAULT" color="#969696" />
+ <progressbar id="HP" color="#ff0000,e28000,c38948,0f6a20" />
+ <progressbar id="MP" color="#1a66e6" />
+ <progressbar id="NO_MP" color="#646464" />
+ <progressbar id="EXP" color="#8fc0d3" />
+ <progressbar id="INVY_SLOTS" color="#e1c819" />
+ <progressbar id="WEIGHT" color="#0000ff,ffff00,ff0000" />
+ <progressbar id="JOB" color="#e187cb" />
+</colors>
diff --git a/data/themes/enchilado/tab.png b/data/themes/enchilado/tab.png
new file mode 100644
index 000000000..3a00d7d12
--- /dev/null
+++ b/data/themes/enchilado/tab.png
Binary files differ
diff --git a/data/themes/enchilado/tab_hilight.png b/data/themes/enchilado/tab_hilight.png
new file mode 100644
index 000000000..67eecc2a5
--- /dev/null
+++ b/data/themes/enchilado/tab_hilight.png
Binary files differ
diff --git a/data/themes/enchilado/tabselected.png b/data/themes/enchilado/tabselected.png
new file mode 100644
index 000000000..259d3d343
--- /dev/null
+++ b/data/themes/enchilado/tabselected.png
Binary files differ
diff --git a/data/themes/enchilado/window.png b/data/themes/enchilado/window.png
new file mode 100644
index 000000000..1d1b5bb34
--- /dev/null
+++ b/data/themes/enchilado/window.png
Binary files differ
diff --git a/data/themes/enchilado/window.xml b/data/themes/enchilado/window.xml
new file mode 100644
index 000000000..015c6ce32
--- /dev/null
+++ b/data/themes/enchilado/window.xml
@@ -0,0 +1,19 @@
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <!-- <option name="padding" value="5" /> -->
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="10" height="10" />
+ <part type="top-edge" xpos="11" ypos="0" width="127" height="10" />
+ <part type="top-right-corner" xpos="139" ypos="0" width="12" height="10" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="11" width="10" height="81" />
+ <part type="bg-quad" xpos="11" ypos="11" width="127" height="81" />
+ <part type="right-edge" xpos="139" ypos="11" width="12" height="81" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="93" width="10" height="12" />
+ <part type="bottom-edge" xpos="11" ypos="93" width="127" height="12" />
+ <part type="bottom-right-corner" xpos="139" ypos="93" width="12" height="12" />
+ </widget>
+</skinset>
diff --git a/data/themes/redandblack/CMakeLists.txt b/data/themes/redandblack/CMakeLists.txt
new file mode 100644
index 000000000..22408ceae
--- /dev/null
+++ b/data/themes/redandblack/CMakeLists.txt
@@ -0,0 +1,53 @@
+SET (FILES
+ bubble.png
+ button.png
+ button_disabled.png
+ buttonhi.png
+ buttonpress.png
+ checkbox.png
+ circle-gray.png
+ circle-green.png
+ close_button.png
+ colors.xml
+ deepbox.png
+ hscroll_left_default.png
+ hscroll_left_highlight.png
+ hscroll_left_pressed.png
+ hscroll_right_default.png
+ hscroll_right_highlight.png
+ hscroll_right_pressed.png
+ item_shortcut_bgr.png
+ mouse.png
+ radioin.png
+ radioin_highlight.png
+ radioout.png
+ radioout_highlight.png
+ resize.png
+ selection.png
+ slider.png
+ slider_hilight.png
+ speechbubble.xml
+ sticky_button.png
+ tab.png
+ tab_hilight.png
+ tabselected.png
+ target-cursor-blue-l.png
+ target-cursor-blue-m.png
+ target-cursor-blue-s.png
+ target-cursor-red-l.png
+ target-cursor-red-m.png
+ target-cursor-red-s.png
+ unknown-item.png
+ vscroll_down_default.png
+ vscroll_down_highlight.png
+ vscroll_down_pressed.png
+ vscroll_grey.png
+ vscroll_highlight.png
+ vscroll_up_default.png
+ vscroll_up_highlight.png
+ vscroll_up_pressed.png
+ window.png
+ window.xml
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/themes/redandblack)
diff --git a/data/themes/redandblack/Makefile.am b/data/themes/redandblack/Makefile.am
new file mode 100755
index 000000000..aa640f8e6
--- /dev/null
+++ b/data/themes/redandblack/Makefile.am
@@ -0,0 +1,56 @@
+
+guidir = $(pkgdatadir)/data/themes/redandblack
+
+gui_DATA = \
+ bubble.png \
+ button.png \
+ button_disabled.png \
+ buttonhi.png \
+ buttonpress.png \
+ checkbox.png \
+ circle-gray.png \
+ circle-green.png \
+ close_button.png \
+ colors.xml \
+ deepbox.png \
+ window.xml \
+ hscroll_left_default.png \
+ hscroll_left_highlight.png \
+ hscroll_left_pressed.png \
+ hscroll_right_default.png \
+ hscroll_right_highlight.png \
+ hscroll_right_pressed.png \
+ item_shortcut_bgr.png \
+ mouse.png \
+ radioin.png \
+ radioin_highlight.png \
+ radioout.png \
+ radioout_highlight.png \
+ resize.png \
+ selection.png \
+ slider.png \
+ slider_hilight.png \
+ speechbubble.xml \
+ sticky_button.png \
+ tab.png \
+ tab_hilight.png \
+ tabselected.png \
+ target-cursor-blue-l.png \
+ target-cursor-blue-m.png \
+ target-cursor-blue-s.png \
+ target-cursor-red-l.png \
+ target-cursor-red-m.png \
+ target-cursor-red-s.png \
+ unknown-item.png \
+ vscroll_down_default.png \
+ vscroll_down_highlight.png \
+ vscroll_down_pressed.png \
+ vscroll_grey.png \
+ vscroll_highlight.png \
+ vscroll_up_default.png \
+ vscroll_up_highlight.png \
+ vscroll_up_pressed.png \
+ window.png
+
+EXTRA_DIST = \
+ $(gui_DATA)
diff --git a/data/themes/redandblack/bubble.png b/data/themes/redandblack/bubble.png
new file mode 100755
index 000000000..69f3a8b11
--- /dev/null
+++ b/data/themes/redandblack/bubble.png
Binary files differ
diff --git a/data/themes/redandblack/button.png b/data/themes/redandblack/button.png
new file mode 100755
index 000000000..ec62fcf28
--- /dev/null
+++ b/data/themes/redandblack/button.png
Binary files differ
diff --git a/data/themes/redandblack/button_disabled.png b/data/themes/redandblack/button_disabled.png
new file mode 100755
index 000000000..f8807e5c0
--- /dev/null
+++ b/data/themes/redandblack/button_disabled.png
Binary files differ
diff --git a/data/themes/redandblack/buttonhi.png b/data/themes/redandblack/buttonhi.png
new file mode 100755
index 000000000..803b1ac40
--- /dev/null
+++ b/data/themes/redandblack/buttonhi.png
Binary files differ
diff --git a/data/themes/redandblack/buttonpress.png b/data/themes/redandblack/buttonpress.png
new file mode 100755
index 000000000..5859e3cb5
--- /dev/null
+++ b/data/themes/redandblack/buttonpress.png
Binary files differ
diff --git a/data/themes/redandblack/checkbox.png b/data/themes/redandblack/checkbox.png
new file mode 100755
index 000000000..f7345e08f
--- /dev/null
+++ b/data/themes/redandblack/checkbox.png
Binary files differ
diff --git a/data/themes/redandblack/circle-gray.png b/data/themes/redandblack/circle-gray.png
new file mode 100755
index 000000000..87df48027
--- /dev/null
+++ b/data/themes/redandblack/circle-gray.png
Binary files differ
diff --git a/data/themes/redandblack/circle-green.png b/data/themes/redandblack/circle-green.png
new file mode 100755
index 000000000..29fa1313a
--- /dev/null
+++ b/data/themes/redandblack/circle-green.png
Binary files differ
diff --git a/data/themes/redandblack/close_button.png b/data/themes/redandblack/close_button.png
new file mode 100755
index 000000000..cae438590
--- /dev/null
+++ b/data/themes/redandblack/close_button.png
Binary files differ
diff --git a/data/themes/redandblack/colors.xml b/data/themes/redandblack/colors.xml
new file mode 100644
index 000000000..cc7efaba7
--- /dev/null
+++ b/data/themes/redandblack/colors.xml
@@ -0,0 +1,53 @@
+<colors>
+ <color id="TEXT" color="#000000" />
+ <color id="SHADOW" color="#000000" />
+ <color id="OUTLINE" color="#000000" />
+ <color id="PROGRESS_BAR" color="#ffffff" />
+ <color id="BUTTON" color="#000000" />
+ <color id="BUTTON_DISABLED" color="#333333" />
+ <color id="TAB" color="#000000" />
+ <color id="PARTY_CHAT_TAB" color="#ff00d8" />
+ <color id="PARTY_SOCIAL_TAB" color="#ff00d8" />
+ <color id="GUILD_CHAT_TAB" color="#ff00d8" />
+ <color id="GUILD_SOCIAL_TAB" color="#ff00d8" />
+ <color id="BACKGROUND" color="#ffffff" />
+ <color id="HIGHLIGHT" color="#c0c0c0" />
+ <color id="TAB_FLASH" color="#ff0000" effect="pulse" />
+ <color id="TAB_PLAYER_FLASH" color="#00ff00" effect="pulse" />
+ <color id="SHOP_WARNING" color="#910000" />
+ <color id="ITEM_EQUIPPED" color="#000091" />
+ <color id="CHAT" color="#000000" />
+ <color id="GM" color="#ff0000" />
+ <color id="PLAYER" color="#1fa052" />
+ <color id="WHISPER" color="#0000ff" />
+ <color id="WHISPER_OFFLINE" color="#000050" />
+ <color id="IS" color="#a08527" />
+ <color id="SERVER" color="#8415e2" />
+ <color id="LOGGER" color="#919191" />
+ <color id="HYPERLINK" color="#e50d0d" />
+ <color id="UNKNOWN_ITEM" color="#000000" />
+ <color id="GENERIC" color="#21a5b1" />
+ <color id="HEAD" color="#527fa4" />
+ <color id="USABLE" color="#268d24" />
+ <color id="TORSO" color="#d12aa4" />
+ <color id="ONEHAND" color="#f42a2a" />
+ <color id="LEGS" color="#699900" />
+ <color id="FEET" color="#aa1d48" />
+ <color id="TWOHAND" color="#f46d0e" />
+ <color id="SHIELD" color="#9c2424" />
+ <color id="RING" color="#0000ff" />
+ <color id="NECKLACE" color="#ff00ff" />
+ <color id="ARMS" color="#9c24e8" />
+ <color id="AMMO" color="#8b6311" />
+ <color id="SERVER_VERSION_NOT_SUPPORTED" color="#DC0000" />
+ <color id="WARNING" color="#0000FF" />
+
+ <progressbar id="DEFAULT" color="#969696" />
+ <progressbar id="HP" color="#ff0000,e28000,c38948,0f6a20" />
+ <progressbar id="MP" color="#1a66e6" />
+ <progressbar id="NO_MP" color="#646464" />
+ <progressbar id="EXP" color="#8fc0d3" />
+ <progressbar id="INVY_SLOTS" color="#e1c819" />
+ <progressbar id="WEIGHT" color="#0000ff,ffff00,ff0000" />
+ <progressbar id="JOB" color="#e187cb" />
+</colors>
diff --git a/data/themes/redandblack/deepbox.png b/data/themes/redandblack/deepbox.png
new file mode 100755
index 000000000..e33f72891
--- /dev/null
+++ b/data/themes/redandblack/deepbox.png
Binary files differ
diff --git a/data/themes/redandblack/hscroll_left_default.png b/data/themes/redandblack/hscroll_left_default.png
new file mode 100755
index 000000000..a66061916
--- /dev/null
+++ b/data/themes/redandblack/hscroll_left_default.png
Binary files differ
diff --git a/data/themes/redandblack/hscroll_left_highlight.png b/data/themes/redandblack/hscroll_left_highlight.png
new file mode 100755
index 000000000..f054bb77b
--- /dev/null
+++ b/data/themes/redandblack/hscroll_left_highlight.png
Binary files differ
diff --git a/data/themes/redandblack/hscroll_left_pressed.png b/data/themes/redandblack/hscroll_left_pressed.png
new file mode 100755
index 000000000..e198f2cfb
--- /dev/null
+++ b/data/themes/redandblack/hscroll_left_pressed.png
Binary files differ
diff --git a/data/themes/redandblack/hscroll_right_default.png b/data/themes/redandblack/hscroll_right_default.png
new file mode 100755
index 000000000..37e79d8da
--- /dev/null
+++ b/data/themes/redandblack/hscroll_right_default.png
Binary files differ
diff --git a/data/themes/redandblack/hscroll_right_highlight.png b/data/themes/redandblack/hscroll_right_highlight.png
new file mode 100755
index 000000000..01f4e4809
--- /dev/null
+++ b/data/themes/redandblack/hscroll_right_highlight.png
Binary files differ
diff --git a/data/themes/redandblack/hscroll_right_pressed.png b/data/themes/redandblack/hscroll_right_pressed.png
new file mode 100755
index 000000000..e21c2843d
--- /dev/null
+++ b/data/themes/redandblack/hscroll_right_pressed.png
Binary files differ
diff --git a/data/themes/redandblack/item_shortcut_bgr.png b/data/themes/redandblack/item_shortcut_bgr.png
new file mode 100755
index 000000000..8cb00f8b8
--- /dev/null
+++ b/data/themes/redandblack/item_shortcut_bgr.png
Binary files differ
diff --git a/data/themes/redandblack/mouse.png b/data/themes/redandblack/mouse.png
new file mode 100755
index 000000000..fcabd41cf
--- /dev/null
+++ b/data/themes/redandblack/mouse.png
Binary files differ
diff --git a/data/themes/redandblack/radioin.png b/data/themes/redandblack/radioin.png
new file mode 100755
index 000000000..f41393f70
--- /dev/null
+++ b/data/themes/redandblack/radioin.png
Binary files differ
diff --git a/data/themes/redandblack/radioin_highlight.png b/data/themes/redandblack/radioin_highlight.png
new file mode 100755
index 000000000..f41393f70
--- /dev/null
+++ b/data/themes/redandblack/radioin_highlight.png
Binary files differ
diff --git a/data/themes/redandblack/radioout.png b/data/themes/redandblack/radioout.png
new file mode 100755
index 000000000..f41393f70
--- /dev/null
+++ b/data/themes/redandblack/radioout.png
Binary files differ
diff --git a/data/themes/redandblack/radioout_highlight.png b/data/themes/redandblack/radioout_highlight.png
new file mode 100755
index 000000000..f41393f70
--- /dev/null
+++ b/data/themes/redandblack/radioout_highlight.png
Binary files differ
diff --git a/data/themes/redandblack/resize.png b/data/themes/redandblack/resize.png
new file mode 100755
index 000000000..2e9b3a75f
--- /dev/null
+++ b/data/themes/redandblack/resize.png
Binary files differ
diff --git a/data/themes/redandblack/selection.png b/data/themes/redandblack/selection.png
new file mode 100755
index 000000000..08b10a8b8
--- /dev/null
+++ b/data/themes/redandblack/selection.png
Binary files differ
diff --git a/data/themes/redandblack/slider.png b/data/themes/redandblack/slider.png
new file mode 100755
index 000000000..604966538
--- /dev/null
+++ b/data/themes/redandblack/slider.png
Binary files differ
diff --git a/data/themes/redandblack/slider_hilight.png b/data/themes/redandblack/slider_hilight.png
new file mode 100755
index 000000000..604966538
--- /dev/null
+++ b/data/themes/redandblack/slider_hilight.png
Binary files differ
diff --git a/data/themes/redandblack/speechbubble.xml b/data/themes/redandblack/speechbubble.xml
new file mode 100755
index 000000000..84b6557b3
--- /dev/null
+++ b/data/themes/redandblack/speechbubble.xml
@@ -0,0 +1,18 @@
+<skinset name="SpeechBubble" image="bubble.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="5" height="5" />
+ <part type="top-edge" xpos="5" ypos="0" width="5" height="5" />
+ <part type="top-right-corner" xpos="10" ypos="0" width="5" height="5" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="5" width="5" height="5" />
+ <part type="bg-quad" xpos="5" ypos="5" width="5" height="5" />
+ <part type="right-edge" xpos="10" ypos="5" width="5" height="5" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="10" width="5" height="5" />
+ <part type="bottom-edge" xpos="5" ypos="10" width="5" height="5" />
+ <part type="bottom-right-corner" xpos="10" ypos="10" width="5" height="5" />
+ </widget>
+</skinset>
diff --git a/data/themes/redandblack/sticky_button.png b/data/themes/redandblack/sticky_button.png
new file mode 100755
index 000000000..3306a1330
--- /dev/null
+++ b/data/themes/redandblack/sticky_button.png
Binary files differ
diff --git a/data/themes/redandblack/tab.png b/data/themes/redandblack/tab.png
new file mode 100755
index 000000000..1f3f7e1b7
--- /dev/null
+++ b/data/themes/redandblack/tab.png
Binary files differ
diff --git a/data/themes/redandblack/tab_hilight.png b/data/themes/redandblack/tab_hilight.png
new file mode 100755
index 000000000..1f3f7e1b7
--- /dev/null
+++ b/data/themes/redandblack/tab_hilight.png
Binary files differ
diff --git a/data/themes/redandblack/tabselected.png b/data/themes/redandblack/tabselected.png
new file mode 100755
index 000000000..8ca142fb9
--- /dev/null
+++ b/data/themes/redandblack/tabselected.png
Binary files differ
diff --git a/data/themes/redandblack/target-cursor-blue-l.png b/data/themes/redandblack/target-cursor-blue-l.png
new file mode 100755
index 000000000..cd6aaa225
--- /dev/null
+++ b/data/themes/redandblack/target-cursor-blue-l.png
Binary files differ
diff --git a/data/themes/redandblack/target-cursor-blue-m.png b/data/themes/redandblack/target-cursor-blue-m.png
new file mode 100755
index 000000000..d961cd363
--- /dev/null
+++ b/data/themes/redandblack/target-cursor-blue-m.png
Binary files differ
diff --git a/data/themes/redandblack/target-cursor-blue-s.png b/data/themes/redandblack/target-cursor-blue-s.png
new file mode 100755
index 000000000..c9edefe48
--- /dev/null
+++ b/data/themes/redandblack/target-cursor-blue-s.png
Binary files differ
diff --git a/data/themes/redandblack/target-cursor-red-l.png b/data/themes/redandblack/target-cursor-red-l.png
new file mode 100755
index 000000000..de9337e6a
--- /dev/null
+++ b/data/themes/redandblack/target-cursor-red-l.png
Binary files differ
diff --git a/data/themes/redandblack/target-cursor-red-m.png b/data/themes/redandblack/target-cursor-red-m.png
new file mode 100755
index 000000000..8e669f6f7
--- /dev/null
+++ b/data/themes/redandblack/target-cursor-red-m.png
Binary files differ
diff --git a/data/themes/redandblack/target-cursor-red-s.png b/data/themes/redandblack/target-cursor-red-s.png
new file mode 100755
index 000000000..0dd1e0d7c
--- /dev/null
+++ b/data/themes/redandblack/target-cursor-red-s.png
Binary files differ
diff --git a/data/themes/redandblack/unknown-item.png b/data/themes/redandblack/unknown-item.png
new file mode 100755
index 000000000..9201d688e
--- /dev/null
+++ b/data/themes/redandblack/unknown-item.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_down_default.png b/data/themes/redandblack/vscroll_down_default.png
new file mode 100755
index 000000000..e6073110f
--- /dev/null
+++ b/data/themes/redandblack/vscroll_down_default.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_down_highlight.png b/data/themes/redandblack/vscroll_down_highlight.png
new file mode 100755
index 000000000..96ec8df07
--- /dev/null
+++ b/data/themes/redandblack/vscroll_down_highlight.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_down_pressed.png b/data/themes/redandblack/vscroll_down_pressed.png
new file mode 100755
index 000000000..17ac2029d
--- /dev/null
+++ b/data/themes/redandblack/vscroll_down_pressed.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_grey.png b/data/themes/redandblack/vscroll_grey.png
new file mode 100755
index 000000000..124a58c14
--- /dev/null
+++ b/data/themes/redandblack/vscroll_grey.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_highlight.png b/data/themes/redandblack/vscroll_highlight.png
new file mode 100755
index 000000000..124a58c14
--- /dev/null
+++ b/data/themes/redandblack/vscroll_highlight.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_up_default.png b/data/themes/redandblack/vscroll_up_default.png
new file mode 100755
index 000000000..bd55e4dd9
--- /dev/null
+++ b/data/themes/redandblack/vscroll_up_default.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_up_highlight.png b/data/themes/redandblack/vscroll_up_highlight.png
new file mode 100755
index 000000000..dc267df3a
--- /dev/null
+++ b/data/themes/redandblack/vscroll_up_highlight.png
Binary files differ
diff --git a/data/themes/redandblack/vscroll_up_pressed.png b/data/themes/redandblack/vscroll_up_pressed.png
new file mode 100755
index 000000000..63c035145
--- /dev/null
+++ b/data/themes/redandblack/vscroll_up_pressed.png
Binary files differ
diff --git a/data/themes/redandblack/window.png b/data/themes/redandblack/window.png
new file mode 100755
index 000000000..81a10cc7c
--- /dev/null
+++ b/data/themes/redandblack/window.png
Binary files differ
diff --git a/data/themes/redandblack/window.xml b/data/themes/redandblack/window.xml
new file mode 100755
index 000000000..f27dbc7f3
--- /dev/null
+++ b/data/themes/redandblack/window.xml
@@ -0,0 +1,18 @@
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="4" height="4" />
+ <part type="top-edge" xpos="4" ypos="0" width="32" height="4" />
+ <part type="top-right-corner" xpos="36" ypos="0" width="4" height="4" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="4" width="4" height="216" />
+ <part type="bg-quad" xpos="4" ypos="4" width="32" height="216" />
+ <part type="right-edge" xpos="36" ypos="4" width="4" height="216" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="220" width="4" height="4" />
+ <part type="bottom-edge" xpos="4" ypos="220" width="32" height="4" />
+ <part type="bottom-right-corner" xpos="36" ypos="220" width="4" height="4" />
+ </widget>
+</skinset>
diff --git a/data/themes/wood/CMakeLists.txt b/data/themes/wood/CMakeLists.txt
new file mode 100644
index 000000000..153e4d04b
--- /dev/null
+++ b/data/themes/wood/CMakeLists.txt
@@ -0,0 +1,53 @@
+SET (FILES
+ bubble.png
+ button.png
+ button_disabled.png
+ buttonhi.png
+ buttonpress.png
+ checkbox.png
+ circle-gray.png
+ circle-green.png
+ close_button.png
+ colors.xml
+ deepbox.png
+ hscroll_left_default.png
+ hscroll_left_highlight.png
+ hscroll_left_pressed.png
+ hscroll_right_default.png
+ hscroll_right_highlight.png
+ hscroll_right_pressed.png
+ item_shortcut_bgr.png
+ mouse.png
+ radioin.png
+ radioin_highlight.png
+ radioout.png
+ radioout_highlight.png
+ resize.png
+ selection.png
+ slider.png
+ slider_hilight.png
+ speechbubble.xml
+ sticky_button.png
+ tab.png
+ tab_hilight.png
+ tabselected.png
+ target-cursor-blue-l.png
+ target-cursor-blue-m.png
+ target-cursor-blue-s.png
+ target-cursor-red-l.png
+ target-cursor-red-m.png
+ target-cursor-red-s.png
+ unknown-item.png
+ vscroll_down_default.png
+ vscroll_down_highlight.png
+ vscroll_down_pressed.png
+ vscroll_grey.png
+ vscroll_highlight.png
+ vscroll_up_default.png
+ vscroll_up_highlight.png
+ vscroll_up_pressed.png
+ window.png
+ window.xml
+ )
+
+INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/themes/wood)
diff --git a/data/themes/wood/Makefile.am b/data/themes/wood/Makefile.am
new file mode 100755
index 000000000..0cc764f06
--- /dev/null
+++ b/data/themes/wood/Makefile.am
@@ -0,0 +1,56 @@
+
+guidir = $(pkgdatadir)/data/themes/wood
+
+gui_DATA = \
+ bubble.png \
+ button.png \
+ button_disabled.png \
+ buttonhi.png \
+ buttonpress.png \
+ checkbox.png \
+ circle-gray.png \
+ circle-green.png \
+ close_button.png \
+ colors.xml \
+ deepbox.png \
+ window.xml \
+ hscroll_left_default.png \
+ hscroll_left_highlight.png \
+ hscroll_left_pressed.png \
+ hscroll_right_default.png \
+ hscroll_right_highlight.png \
+ hscroll_right_pressed.png \
+ item_shortcut_bgr.png \
+ mouse.png \
+ radioin.png \
+ radioin_highlight.png \
+ radioout.png \
+ radioout_highlight.png \
+ resize.png \
+ selection.png \
+ slider.png \
+ slider_hilight.png \
+ speechbubble.xml \
+ sticky_button.png \
+ tab.png \
+ tab_hilight.png \
+ tabselected.png \
+ target-cursor-blue-l.png \
+ target-cursor-blue-m.png \
+ target-cursor-blue-s.png \
+ target-cursor-red-l.png \
+ target-cursor-red-m.png \
+ target-cursor-red-s.png \
+ unknown-item.png \
+ vscroll_down_default.png \
+ vscroll_down_highlight.png \
+ vscroll_down_pressed.png \
+ vscroll_grey.png \
+ vscroll_highlight.png \
+ vscroll_up_default.png \
+ vscroll_up_highlight.png \
+ vscroll_up_pressed.png \
+ window.png
+
+EXTRA_DIST = \
+ $(gui_DATA)
diff --git a/data/themes/wood/bubble.png b/data/themes/wood/bubble.png
new file mode 100755
index 000000000..45322eb2e
--- /dev/null
+++ b/data/themes/wood/bubble.png
Binary files differ
diff --git a/data/themes/wood/button.png b/data/themes/wood/button.png
new file mode 100755
index 000000000..4f6a5a812
--- /dev/null
+++ b/data/themes/wood/button.png
Binary files differ
diff --git a/data/themes/wood/button_disabled.png b/data/themes/wood/button_disabled.png
new file mode 100755
index 000000000..2a8fdf43a
--- /dev/null
+++ b/data/themes/wood/button_disabled.png
Binary files differ
diff --git a/data/themes/wood/buttonhi.png b/data/themes/wood/buttonhi.png
new file mode 100755
index 000000000..24c097180
--- /dev/null
+++ b/data/themes/wood/buttonhi.png
Binary files differ
diff --git a/data/themes/wood/buttonpress.png b/data/themes/wood/buttonpress.png
new file mode 100755
index 000000000..d192534a3
--- /dev/null
+++ b/data/themes/wood/buttonpress.png
Binary files differ
diff --git a/data/themes/wood/checkbox.png b/data/themes/wood/checkbox.png
new file mode 100755
index 000000000..b68893fc2
--- /dev/null
+++ b/data/themes/wood/checkbox.png
Binary files differ
diff --git a/data/themes/wood/circle-gray.png b/data/themes/wood/circle-gray.png
new file mode 100755
index 000000000..3e884f405
--- /dev/null
+++ b/data/themes/wood/circle-gray.png
Binary files differ
diff --git a/data/themes/wood/circle-green.png b/data/themes/wood/circle-green.png
new file mode 100755
index 000000000..2c98e9ef1
--- /dev/null
+++ b/data/themes/wood/circle-green.png
Binary files differ
diff --git a/data/themes/wood/close_button.png b/data/themes/wood/close_button.png
new file mode 100755
index 000000000..a4f802e01
--- /dev/null
+++ b/data/themes/wood/close_button.png
Binary files differ
diff --git a/data/themes/wood/colors.xml b/data/themes/wood/colors.xml
new file mode 100644
index 000000000..5339c3fd2
--- /dev/null
+++ b/data/themes/wood/colors.xml
@@ -0,0 +1,53 @@
+<colors>
+ <color id="TEXT" color="#000000" />
+ <color id="SHADOW" color="#000000" />
+ <color id="OUTLINE" color="#000000" />
+ <color id="PROGRESS_BAR" color="#ffffff" />
+ <color id="BUTTON" color="#000000" />
+ <color id="BUTTON_DISABLED" color="#cccccc" />
+ <color id="TAB" color="#000000" />
+ <color id="PARTY_CHAT_TAB" color="#f48055" />
+ <color id="PARTY_SOCIAL_TAB" color="#f48055" />
+ <color id="GUILD_CHAT_TAB" color="#f48055" />
+ <color id="GUILD_SOCIAL_TAB" color="#f48055" />
+ <color id="BACKGROUND" color="#ffffff" />
+ <color id="HIGHLIGHT" color="#ebc873" />
+ <color id="TAB_FLASH" color="#ff0000" effect="pulse" />
+ <color id="TAB_PLAYER_FLASH" color="#00ff00" effect="pulse" />
+ <color id="SHOP_WARNING" color="#910000" />
+ <color id="ITEM_EQUIPPED" color="#000091" />
+ <color id="CHAT" color="#000000" />
+ <color id="GM" color="#ff0000" />
+ <color id="PLAYER" color="#1fa052" />
+ <color id="WHISPER" color="#00feaf" />
+ <color id="WHISPER_OFFLINE" color="#000a40" />
+ <color id="IS" color="#a08527" />
+ <color id="SERVER" color="#8415e2" />
+ <color id="LOGGER" color="#919191" />
+ <color id="HYPERLINK" color="#e50d0d" />
+ <color id="UNKNOWN_ITEM" color="#000000" />
+ <color id="GENERIC" color="#21a5b1" />
+ <color id="HEAD" color="#527fa4" />
+ <color id="USABLE" color="#268d24" />
+ <color id="TORSO" color="#d12aa4" />
+ <color id="ONEHAND" color="#f42a2a" />
+ <color id="LEGS" color="#699900" />
+ <color id="FEET" color="#aa1d48" />
+ <color id="TWOHAND" color="#f46d0e" />
+ <color id="SHIELD" color="#9c2424" />
+ <color id="RING" color="#0000ff" />
+ <color id="NECKLACE" color="#ff00ff" />
+ <color id="ARMS" color="#9c24e8" />
+ <color id="AMMO" color="#8b6311" />
+ <color id="SERVER_VERSION_NOT_SUPPORTED" color="#DC0000" />
+ <color id="WARNING" color="#FF0000" />
+
+ <progressbar id="DEFAULT" color="#969696" />
+ <progressbar id="HP" color="#ff0000,e28000,c38948,0f6a20" />
+ <progressbar id="MP" color="#1a66e6" />
+ <progressbar id="NO_MP" color="#646464" />
+ <progressbar id="EXP" color="#8fc0d3" />
+ <progressbar id="INVY_SLOTS" color="#e1c819" />
+ <progressbar id="WEIGHT" color="#0000ff,ffff00,ff0000" />
+ <progressbar id="JOB" color="#e187cb" />
+</colors>
diff --git a/data/themes/wood/deepbox.png b/data/themes/wood/deepbox.png
new file mode 100755
index 000000000..6b63168af
--- /dev/null
+++ b/data/themes/wood/deepbox.png
Binary files differ
diff --git a/data/themes/wood/hscroll_left_default.png b/data/themes/wood/hscroll_left_default.png
new file mode 100755
index 000000000..07e5e0780
--- /dev/null
+++ b/data/themes/wood/hscroll_left_default.png
Binary files differ
diff --git a/data/themes/wood/hscroll_left_highlight.png b/data/themes/wood/hscroll_left_highlight.png
new file mode 100755
index 000000000..c77427f82
--- /dev/null
+++ b/data/themes/wood/hscroll_left_highlight.png
Binary files differ
diff --git a/data/themes/wood/hscroll_left_pressed.png b/data/themes/wood/hscroll_left_pressed.png
new file mode 100755
index 000000000..081eaa3a6
--- /dev/null
+++ b/data/themes/wood/hscroll_left_pressed.png
Binary files differ
diff --git a/data/themes/wood/hscroll_right_default.png b/data/themes/wood/hscroll_right_default.png
new file mode 100755
index 000000000..ee74c0715
--- /dev/null
+++ b/data/themes/wood/hscroll_right_default.png
Binary files differ
diff --git a/data/themes/wood/hscroll_right_highlight.png b/data/themes/wood/hscroll_right_highlight.png
new file mode 100755
index 000000000..9f8911e4e
--- /dev/null
+++ b/data/themes/wood/hscroll_right_highlight.png
Binary files differ
diff --git a/data/themes/wood/hscroll_right_pressed.png b/data/themes/wood/hscroll_right_pressed.png
new file mode 100755
index 000000000..6ef987a5b
--- /dev/null
+++ b/data/themes/wood/hscroll_right_pressed.png
Binary files differ
diff --git a/data/themes/wood/item_shortcut_bgr.png b/data/themes/wood/item_shortcut_bgr.png
new file mode 100755
index 000000000..5b3c5e7c1
--- /dev/null
+++ b/data/themes/wood/item_shortcut_bgr.png
Binary files differ
diff --git a/data/themes/wood/mouse.png b/data/themes/wood/mouse.png
new file mode 100755
index 000000000..84dc2ad1f
--- /dev/null
+++ b/data/themes/wood/mouse.png
Binary files differ
diff --git a/data/themes/wood/radioin.png b/data/themes/wood/radioin.png
new file mode 100755
index 000000000..8d0e5f749
--- /dev/null
+++ b/data/themes/wood/radioin.png
Binary files differ
diff --git a/data/themes/wood/radioin_highlight.png b/data/themes/wood/radioin_highlight.png
new file mode 100755
index 000000000..c020f0baa
--- /dev/null
+++ b/data/themes/wood/radioin_highlight.png
Binary files differ
diff --git a/data/themes/wood/radioout.png b/data/themes/wood/radioout.png
new file mode 100755
index 000000000..70a252568
--- /dev/null
+++ b/data/themes/wood/radioout.png
Binary files differ
diff --git a/data/themes/wood/radioout_highlight.png b/data/themes/wood/radioout_highlight.png
new file mode 100755
index 000000000..957a1fa65
--- /dev/null
+++ b/data/themes/wood/radioout_highlight.png
Binary files differ
diff --git a/data/themes/wood/resize.png b/data/themes/wood/resize.png
new file mode 100755
index 000000000..dfe79ebf2
--- /dev/null
+++ b/data/themes/wood/resize.png
Binary files differ
diff --git a/data/themes/wood/selection.png b/data/themes/wood/selection.png
new file mode 100755
index 000000000..a117a78ac
--- /dev/null
+++ b/data/themes/wood/selection.png
Binary files differ
diff --git a/data/themes/wood/slider.png b/data/themes/wood/slider.png
new file mode 100755
index 000000000..df9abe564
--- /dev/null
+++ b/data/themes/wood/slider.png
Binary files differ
diff --git a/data/themes/wood/slider_hilight.png b/data/themes/wood/slider_hilight.png
new file mode 100755
index 000000000..8b7d2be67
--- /dev/null
+++ b/data/themes/wood/slider_hilight.png
Binary files differ
diff --git a/data/themes/wood/speechbubble.xml b/data/themes/wood/speechbubble.xml
new file mode 100755
index 000000000..84b6557b3
--- /dev/null
+++ b/data/themes/wood/speechbubble.xml
@@ -0,0 +1,18 @@
+<skinset name="SpeechBubble" image="bubble.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="5" height="5" />
+ <part type="top-edge" xpos="5" ypos="0" width="5" height="5" />
+ <part type="top-right-corner" xpos="10" ypos="0" width="5" height="5" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="5" width="5" height="5" />
+ <part type="bg-quad" xpos="5" ypos="5" width="5" height="5" />
+ <part type="right-edge" xpos="10" ypos="5" width="5" height="5" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="10" width="5" height="5" />
+ <part type="bottom-edge" xpos="5" ypos="10" width="5" height="5" />
+ <part type="bottom-right-corner" xpos="10" ypos="10" width="5" height="5" />
+ </widget>
+</skinset>
diff --git a/data/themes/wood/sticky_button.png b/data/themes/wood/sticky_button.png
new file mode 100755
index 000000000..2708dd994
--- /dev/null
+++ b/data/themes/wood/sticky_button.png
Binary files differ
diff --git a/data/themes/wood/tab.png b/data/themes/wood/tab.png
new file mode 100755
index 000000000..689981a99
--- /dev/null
+++ b/data/themes/wood/tab.png
Binary files differ
diff --git a/data/themes/wood/tab_hilight.png b/data/themes/wood/tab_hilight.png
new file mode 100755
index 000000000..d0585e8fe
--- /dev/null
+++ b/data/themes/wood/tab_hilight.png
Binary files differ
diff --git a/data/themes/wood/tabselected.png b/data/themes/wood/tabselected.png
new file mode 100755
index 000000000..72a489733
--- /dev/null
+++ b/data/themes/wood/tabselected.png
Binary files differ
diff --git a/data/themes/wood/target-cursor-blue-l.png b/data/themes/wood/target-cursor-blue-l.png
new file mode 100755
index 000000000..77cdf4b6d
--- /dev/null
+++ b/data/themes/wood/target-cursor-blue-l.png
Binary files differ
diff --git a/data/themes/wood/target-cursor-blue-m.png b/data/themes/wood/target-cursor-blue-m.png
new file mode 100755
index 000000000..c0107357a
--- /dev/null
+++ b/data/themes/wood/target-cursor-blue-m.png
Binary files differ
diff --git a/data/themes/wood/target-cursor-blue-s.png b/data/themes/wood/target-cursor-blue-s.png
new file mode 100755
index 000000000..3e81c75de
--- /dev/null
+++ b/data/themes/wood/target-cursor-blue-s.png
Binary files differ
diff --git a/data/themes/wood/target-cursor-red-l.png b/data/themes/wood/target-cursor-red-l.png
new file mode 100755
index 000000000..76d2101b1
--- /dev/null
+++ b/data/themes/wood/target-cursor-red-l.png
Binary files differ
diff --git a/data/themes/wood/target-cursor-red-m.png b/data/themes/wood/target-cursor-red-m.png
new file mode 100755
index 000000000..e2ab79c29
--- /dev/null
+++ b/data/themes/wood/target-cursor-red-m.png
Binary files differ
diff --git a/data/themes/wood/target-cursor-red-s.png b/data/themes/wood/target-cursor-red-s.png
new file mode 100755
index 000000000..09195f440
--- /dev/null
+++ b/data/themes/wood/target-cursor-red-s.png
Binary files differ
diff --git a/data/themes/wood/unknown-item.png b/data/themes/wood/unknown-item.png
new file mode 100755
index 000000000..9201d688e
--- /dev/null
+++ b/data/themes/wood/unknown-item.png
Binary files differ
diff --git a/data/themes/wood/vscroll_down_default.png b/data/themes/wood/vscroll_down_default.png
new file mode 100755
index 000000000..0ec2a3eed
--- /dev/null
+++ b/data/themes/wood/vscroll_down_default.png
Binary files differ
diff --git a/data/themes/wood/vscroll_down_highlight.png b/data/themes/wood/vscroll_down_highlight.png
new file mode 100755
index 000000000..d2934daa2
--- /dev/null
+++ b/data/themes/wood/vscroll_down_highlight.png
Binary files differ
diff --git a/data/themes/wood/vscroll_down_pressed.png b/data/themes/wood/vscroll_down_pressed.png
new file mode 100755
index 000000000..6aa44ba67
--- /dev/null
+++ b/data/themes/wood/vscroll_down_pressed.png
Binary files differ
diff --git a/data/themes/wood/vscroll_grey.png b/data/themes/wood/vscroll_grey.png
new file mode 100755
index 000000000..3f65a8835
--- /dev/null
+++ b/data/themes/wood/vscroll_grey.png
Binary files differ
diff --git a/data/themes/wood/vscroll_highlight.png b/data/themes/wood/vscroll_highlight.png
new file mode 100755
index 000000000..9802044cc
--- /dev/null
+++ b/data/themes/wood/vscroll_highlight.png
Binary files differ
diff --git a/data/themes/wood/vscroll_up_default.png b/data/themes/wood/vscroll_up_default.png
new file mode 100755
index 000000000..73a4266fc
--- /dev/null
+++ b/data/themes/wood/vscroll_up_default.png
Binary files differ
diff --git a/data/themes/wood/vscroll_up_highlight.png b/data/themes/wood/vscroll_up_highlight.png
new file mode 100755
index 000000000..6fc3884df
--- /dev/null
+++ b/data/themes/wood/vscroll_up_highlight.png
Binary files differ
diff --git a/data/themes/wood/vscroll_up_pressed.png b/data/themes/wood/vscroll_up_pressed.png
new file mode 100755
index 000000000..bfa8e175e
--- /dev/null
+++ b/data/themes/wood/vscroll_up_pressed.png
Binary files differ
diff --git a/data/themes/wood/window.png b/data/themes/wood/window.png
new file mode 100755
index 000000000..671b77407
--- /dev/null
+++ b/data/themes/wood/window.png
Binary files differ
diff --git a/data/themes/wood/window.xml b/data/themes/wood/window.xml
new file mode 100755
index 000000000..015c6ce32
--- /dev/null
+++ b/data/themes/wood/window.xml
@@ -0,0 +1,19 @@
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <!-- <option name="padding" value="5" /> -->
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="10" height="10" />
+ <part type="top-edge" xpos="11" ypos="0" width="127" height="10" />
+ <part type="top-right-corner" xpos="139" ypos="0" width="12" height="10" />
+
+ <!-- Middle Row -->
+ <part type="left-edge" xpos="0" ypos="11" width="10" height="81" />
+ <part type="bg-quad" xpos="11" ypos="11" width="127" height="81" />
+ <part type="right-edge" xpos="139" ypos="11" width="12" height="81" />
+
+ <!-- Bottom Row -->
+ <part type="bottom-left-corner" xpos="0" ypos="93" width="10" height="12" />
+ <part type="bottom-edge" xpos="11" ypos="93" width="127" height="12" />
+ <part type="bottom-right-corner" xpos="139" ypos="93" width="12" height="12" />
+ </widget>
+</skinset>
diff --git a/docs/FAQ.txt b/docs/FAQ.txt
new file mode 100644
index 000000000..178608365
--- /dev/null
+++ b/docs/FAQ.txt
@@ -0,0 +1,88 @@
+F.A.Q.
+------
+
+HELP
+
+Q: How to get help?
+
+A: The fastest way is to come on our IRC channel. There you can find a lot of
+ nice people that will help you until you solve your problem.
+
+ Server: irc.freenode.net Channel: #themanaworld.
+
+ If you don't like IRC just come to our forums:
+
+ http://forums.themanaworld.org.
+
+ Ok, do you think forums are evil? Don't worry, send us an e-mail at
+ themanaworld-devel@lists.sourceforge.net and you're done. That's not enough?
+ No, we don't share our phone numbers! ;P
+
+
+GAME
+
+Q: I always get "Unregistered ID" error message, why?
+
+A: Is the first time you login? Have you registered an account? If not use the
+ "Register" button. If you already succesfully connected before, but now
+ you're getting this message, please get in touch (see "How to get help").
+
+Q: I always get "Wrong password" but I'm sure I typed it right, why?
+
+A: If is the first time you login be sure you're not adding _M at the end of
+ your username. Otherwise just get in touch (see "How to get help").
+
+Q: How can I talk to NPCs?
+
+A: Did you read README? Are you really sure? If not go read it and you'll find
+ all the known commands. Or just press F1 in game. If you notice the
+ README/ingame help is not up to date/wrong, please report it to the
+ developers.
+
+Q: I can't recover HP anymore.
+
+A: Check your inventory, if you've got lots of stuff probably you're
+ overweight, try to give away some of them. You get overweight when you're
+ carrying 50% of your maximum weight.
+
+
+Git
+
+Q: What's Git?
+
+A: It's a system where is stored the latest development version. It's not
+ assured that it's stable, but surely it has the latest updates. (Git version
+ is updated quite frequently). If you want to check it out, read this guide
+
+ http://wiki.themanaworld.org/index.php/Git
+
+
+DEVELOPMENT
+
+Q: When will the next version be released?
+
+A: We don't have scheduled releases, but usually a new release is available
+ every few months. Check http://themanaworld.org/ for further info.
+
+
+Q: How can I contribute?
+
+A: There are a lot of ways:
+
+ - If you're a programmer, an artist or just willing to help in any way, you
+ can become part of the development team. Join our irc channel:
+
+ #themanaworld @ irc.freenode.net.
+
+ There's also a wiki page about how to get involved:
+
+ http://wiki.themanaworld.org/index.php/Joining_the_project
+
+ - You can donate money. Follow the link on the project page:
+
+ http://sourceforge.net/projects/themanaworld/
+
+ - You can be a beta tester. Just play The Mana World and report every
+ error to the bug tracker or on the forum.
+
+ - Play with The Mana World: more players, more fun! Simple as that! ;-)
diff --git a/docs/HACKING.txt b/docs/HACKING.txt
new file mode 100644
index 000000000..ad2f341bb
--- /dev/null
+++ b/docs/HACKING.txt
@@ -0,0 +1,137 @@
+----------------------------
+Mana Hacking Guide
+----------------------------
+
+This guide is also available at http://gitorious.org/mana/pages/Hacking
+including more tips about C++ programming in general.
+
+With multiple coders working on the same source files, there needs to be a
+standard specifying how code is written down. Not doing so can cause quite some
+annoyance for certain coders and easily creates more version conflicts than
+necessary.
+
+* Indentation:
+ Code is indented using 4 spaces, no tabs.
+
+* Line length:
+ Should not exceed 79 characters.
+
+ One reason for this is to keep code readable. In such cases it would often be
+ better to spread the line over multiple lines or use some extra temporary
+ variables. Another reason is that some of us are using editors that default
+ to an 80 character wide screen, and often put two instances next to
+ eachother. 79 character wide lines leave just a spot for the cursor at the
+ end of the line.
+
+* Control constructs like this:
+
+ Good:
+
+ if (condition)
+ {
+ }
+ else
+ {
+ }
+
+ for (init; condition; step)
+ {
+ }
+
+ while (condition)
+ {
+ }
+
+ /**
+ * Documentation about behaviour
+ * ...
+ *
+ * @param param1 the first argument
+ * @param param2 the second argument
+ */
+ void function(param1, param2)
+ {
+ }
+
+ class TheClass : public TheSubclass
+ {
+ };
+
+ When there is only one statement you may leave out the braces, but don't
+ place the statement on the same line as the condition:
+
+ Good:
+
+ if (condition)
+ statement;
+
+ Bad:
+
+ if (condition) statement;
+
+* Includes:
+ Source files should include their header first, to make sure the headers are
+ self-contained. After that follow other project includes, grouped by
+ directory and alphabetically ordered. System includes come last. All project
+ includes are done relative from the 'src' directory.
+
+ Good (subdirectory/source.cpp):
+
+ #include "subdirectory/header.h"
+
+ #include "somesub/bar.h"
+ #include "somesub/zaro.h"
+
+ #include <systemlib.h>
+
+* Comments:
+ Single line C++ style comments are indented the same as the previous line.
+
+ Good:
+ // comment
+
+ Multiple line C style comments are initially indented like previous line
+ except every new line of the comment begins with a asterisk ('*') which lines
+ up with the initial asterisk of the comment opening (1 space indent). The
+ comment is closed also with the asterisk lining up. Comment text is only
+ placed on a line starting with a asterisk.
+
+ Good:
+ /*
+ * Some comment
+ * additional comment material
+ */
+
+ Bad:
+ /* text
+ comment
+ */
+
+ Note that for documenting functions, methods and other things that can use
+ documentation, you should use Doxygen style as in the function example above.
+ For details see the manual at http://www.doxygen.org/.
+
+* Whitespace examples:
+
+ Good:
+ x = ((5 + 4) * 3) / 1.5;
+ afunction(12, 3, (1 + 1));
+
+ Bad:
+ x = ( ( 5 + 4 ) * 3 ) / 1.5;
+ afunction(12,3,(1+1));
+
+* Method, class, member and constant naming is based on the
+ generally accepted way Java code is written.
+
+ Class: CapitalizedWords
+ Method: camelCase
+ Member: mCamelCase
+ Constant/enum: UPPERCASE_UNDERSCORES
+
+ To denote global variables and functions the lowercase_underscores style may
+ be used. Hungarian style should be avoided.
+
+* Whenever you add a new source file somewhere in ./src do not forget to add
+ them in ./src/Makefile.am as well!
+
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644
index 000000000..9ea3cbafc
--- /dev/null
+++ b/docs/Makefile.am
@@ -0,0 +1,9 @@
+man6_MANS = manaplus.6
+
+EXTRA_DIST = $(man6_MANS) \
+ packages.txt \
+ FAQ.txt \
+ HACKING.txt \
+ SOURCE/Doxyfile \
+ items.txt \
+ progression.txt
diff --git a/docs/SOURCE/Doxyfile b/docs/SOURCE/Doxyfile
new file mode 100644
index 000000000..5b5f30f94
--- /dev/null
+++ b/docs/SOURCE/Doxyfile
@@ -0,0 +1,1153 @@
+# Doxyfile 1.3.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "Mana"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of source
+# files, where putting all generated files in the same directory would otherwise
+# cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is used
+# as the annotated text. Otherwise, the brief description is used as-is. If left
+# blank, the following values are used ("$name" is automatically replaced with the
+# name of the entity): "The $name class" "The $name widget" "The $name file"
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = "warnings.log"
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = "../../src"
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE = mana.chm
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS = NO
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = NO
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = YES
diff --git a/docs/clientupdates.txt b/docs/clientupdates.txt
new file mode 100644
index 000000000..c5e38d8b8
--- /dev/null
+++ b/docs/clientupdates.txt
@@ -0,0 +1,46 @@
+--------------------
+CLIENT AUTO-UPDATING
+--------------------
+
+UPDATING CLIENT DATA
+
+For future clients we need to develop a way in which they can automatically
+update to new data like for example new images, maps or item, being and skill
+definitions. Here is described the sequence of actions that could implement
+this functionality:
+
+ 1. Client loads initial core data for login screen (always included with
+ release)
+ 2. Client logs on
+ 3. Server sends client list of required packages (maybe with versions)
+ 4. Client notices he doesn't have a certain package yet or is out of date
+ 5. Client requests from server .torrent files (or maybe at first just URL)
+ from where to get the the missing packages
+ 6. Client downloads them and puts them in "data" directory (~/.mana/data on
+ Linux, cause that's writable)
+ 7. Client loads the list of files server mentioned in PhysFS virtual
+ filesystem
+ 8. Client tells server that it is up to date
+ 9. Client could load some common data like item definitions here
+10. Server sends client player position and so on, game starts, client loads
+ and unloads additional data like maps, tilesets, sprites, etc. on demand.
+
+
+UPDATING THE CLIENT BINARY
+
+Updates to the actual client binary are also being considered, especially on
+the Windows operating system. While the plan is to move any specific game data
+outside of the binary, sometimes an update to the binary will be required for
+being able to play the game. Also especially Windows users are used to
+automatic update checks for many applications (possibly because of the lack of
+such a feature system-wide).
+
+On Linux this would require either installing a statically linked binary
+(which could still have some issues) or automatically compiling/installing
+from source. Neither are very attractive options, and I (Hammerbear) would
+prefer not to deal with automatic binary updates on Linux.
+
+On Windows a binary can't be replaced while it is running, so probably a
+separate update tool would need to be written that is run before the client
+to check for updates to the client and possibly replaces the client before
+running it.
diff --git a/docs/example.mana b/docs/example.mana
new file mode 100644
index 000000000..9173efb01
--- /dev/null
+++ b/docs/example.mana
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+
+<!--
+Example branding file
+
+With a branding file you can customize the appearance and various
+other default settings. To use a branding file just pass its
+filename / path as a command line parameter
+-->
+
+<configuration>
+ <option name="appName" value="Mana"/>
+ <option name="appShort" value="mana"/>
+ <option name="appIcon" value="icons/mana.png"/>
+ <option name="loginMusic" value="Magick - Real.ogg"/>
+ <option name="onlineServerList" value="http://manasource.org/serverlist.xml"/>
+ <option name="defaultServer" value="testing.manasource.org"/>
+ <option name="defaultPort" value="9601"/>
+ <option name="defaultServerType" value="manaserv"/>
+ <option name="defaultUpdateHost" value="http://updates.themanaworld.org"/>
+ <option name="font" value="fonts/dejavusans.ttf" />
+ <option name="boldFont" value="fonts/dejavusans-bold.ttf" />
+ <option name="theme" value="wood" />
+</configuration>
diff --git a/docs/items.txt b/docs/items.txt
new file mode 100644
index 000000000..19c6b10cc
--- /dev/null
+++ b/docs/items.txt
@@ -0,0 +1,198 @@
+-------------------------------
+THE MANA WORLD INVENTORY SYSTEM
+-------------------------------
+
+1. INTRODUCTION
+2. DATABASE
+3. INVENTORY
+4. EQUIPMENT
+5. IMPLEMENTATION
+6. SPECIAL ITEMS
+7. PROTOCOL
+
+An item will have the following properties:
+
+C means info is used only by the client
+S means info is used only by the server
+C&S means info is used by both
+
+- id (C&S) -> unsigned int
+
+ a positive integer uniquely identifying an item.
+
+- image (C) -> unsigned int
+
+ used if same images are used for different items.
+ Maybe we need more image ids to tell which image (bigger one) to show in
+ equipment window or when equipping items in weapon slot.
+
+- name (C) -> char[30]
+
+ to be shown in inventory.
+
+- description (C) -> char[100]
+
+ a brief description shown in shops, or in the inventory
+
+- type (S) -> unsigned char
+
+ server uses it to check if is an item or an equipment and send the
+ appropriate packet.
+
+ * USABLE_ITEM (food, potions, ...)
+ * EQUIPMENT_ITEM (weapons, armors, ...)
+ * SLOT_ITEM (cards, materias, summoned beings, ...)
+ * SLOTTED_ITEM (bags, small chests, ...)
+
+- identify (S) -> unsigned char
+
+ The server will check this flag if the items can be identified by the
+ player.
+
+ * IDENTIFIED no need to identify the item
+ * IDENTIFY_ITEM you can identify it by using a special item
+ * IDENTIFY_MAGIC you can identify it by using a particular spell
+ * BLACKSMITH needs a blacksmith to be identified
+ * WIZARD needs a wizard to be identified (enchanted items)
+ * ANCIENT_BLACKSMITH
+ * ANCIENT_WIZARD
+ * NOT_IDENTIFIABLE reserved for future use
+
+- weight (C&S) -> unsigned short
+
+ Used by server to calculate if the being can carry more items. The client
+ uses it to display the information to the player.
+
+- # of slots (C&S) -> unsigned char
+
+ If this field is greater than 0 it means this one is a slotted item.
+ (Probably we can remove SLOTTED_ITEM from the type enumeration)
+ For example a bag will have 4 slots, while a chest about 10.
+
+- script (S) -> probably a file name to reference the script file
+ or class or name of class object
+
+ Script to be executed when item is used/equipped. Events include:
+
+ onPickup(Being b) The item is picked up by being b
+ onDrop(Being b) The item is dropped by being b
+ onUse(Being b) The item is used by being b
+ onUseWith(Being b, Object o) The item is used with object o by being b
+ onEquip(Being b) The item is equipped by being b
+
+
+3. INVENTORY
+
+Inventory will contain any kind of weapons including non equipped items and
+slotted items. Every being will have a variable number of slots to store items.
+For example a maggot won't have any slot, while players could have a number of
+slots depending on his strength. A pet could have one slot used to add a bag and
+help the player carrying items.
+
+Hammerbear says: I think here we should go all the way with weight approach and
+not have a slot limit. The same could be used for container items, that simply
+have a contents that can hold a certain total weight. Places where slots are
+then used is for equipment, where each slot maps onto a certain body part, and
+possibly certain slotted items that have slots that can only hold a certain
+type of item.
+
+
+4. EQUIPMENT
+
+Every being will have a variable number of slots to equip items. For a human
+player we will have the following slots:
+
+* 0 body
+* 1 hair
+ 2 head (hat, helmet, etc.)
+ 3 neck (necklace)
+ 4 torso (body armour)
+ 5 right hand (weapons)
+ 6 left hand (shield, only available with no or one-handed weapon)
+ (ammunition, only available with certain weapons)
+ 7 left ring finger
+ 8 right ring finger
+ 9 legs (pants)
+ 10 feet (shoes)
+
+These slots will composite to form the character graphic. The order of the
+composition is not the same in each direction and some slots do not contribute
+to the final graphic. Draw order for each direction:
+
+ left 0, 1, 2, 10, 9, 5, 4, 6
+ right 0, 1, 2, 10, 9, 6, 4, 5
+ up 0, 1, 2, 10, 9, 5, 6, 4
+ down 0, 1, 2, 10, 9, 4, 6, 5
+
+*) These slots are not under player control, but are merely used by the engine
+so be able to change this as part of the same system.
+
+
+5. IMPLEMENTATION
+
+Since both client and server will only need to store item ids, inventory and
+equipment can be easily coded as unsigned int arrays. The only problem is
+about slotted items. They for sure can't store another slotted item, but it's
+hard to represent them as an int. Probably a more complex structure is needed.
+
+struct ITEM_HOLDER {
+ int id;
+ int quantity;
+ ITEM_HOLDER *item;
+}
+
+ITEM_HOLDER inventory[number_of_slots];
+ITEM_HOLDER equipment[number_of_slots];
+
+If item is not NULL it will reference an array of items stored in the slotted
+item.
+
+How to limit the quantity of items? We could have a fixed number of slots in the
+inventory. In one slot you can store only items with the same id (except slotted
+items which need separate slots). When you pick up/receive a new item, total
+weigth you can carry is checked if the item can be stored.
+
+
+6. SPECIAL ITEMS
+
+A special case is represented by arrow holder. Possible solutions:
+
+ - Equipment will have a special slot where you can equip only arrows
+ (or stones)
+
+ - Item with one slot
+
+ - Arrows can be simply stored in inventory
+
+ - Arrow holder has special slot for items of type "arrow" that can hold up
+ to a certain maximum number of arrows.
+
+Weapons can store a limited number of items in their slots. In this kind of
+slots you can store materia, demons or arrows. Some examples, with XML test
+cases based on 4th solution above.
+
+ * Arrow holder = max 100 arrows (1 slot)
+
+ <item name="Medium quiver" ...>
+ <slot type="arrow" max="100"/>
+ </item>
+
+ * Sword of chaos = max 1 materia + 2 demons (2 slot)
+
+ <item name="Sword of chaos" ...>
+ <slot type="materia" max="1"/>
+ <slot type="demon" max="2"/>
+ </item>
+
+ * Bag that can hold 5 kg of arbitrary stuff (container).
+
+ <item name="Leather bag" weight="1" ... capacity="5"/>
+
+ The rationale of being able to carry 5 kg of stuff at the cost of only
+ 1 kg is that the bag helps you carry the stuff by providing a convenient
+ way to hold it.
+
+
+7. PROTOCOL
+
+To be defined.
diff --git a/docs/manaplus.6 b/docs/manaplus.6
new file mode 100644
index 000000000..dbde16d49
--- /dev/null
+++ b/docs/manaplus.6
@@ -0,0 +1,104 @@
+.TH "ManaPlus" "6"
+.SH "NAME"
+mana \- ManaPlus: A 2D MMORPG client
+.SH "SYNOPSIS"
+\fBmanaplus\fR
+.SH "DESCRIPTION"
+This manual page documents briefly the
+\fBmanaplus\fR ingame
+commands.
+\fBmanaplus\fR is a great online game based upon the Seiken Densetsu Serie.
+It has its own universe, and and its own character management system, which will
+give you the opportunity to play in a 2D heroic-fantasy world forever.
+.SH "BINARY PARAMETERS"
+This program follows the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-l, \-\-log\-file
+Log file to use
+.TP
+.B \-L, \-\-chat\-log\-dir
+Chat log dir to use
+.TP
+.B \-v, \-\-version
+Show version of the program.
+.TP
+.B \-h, \-\-help
+Show summary of options.
+.TP
+.B \-C, \-\-config\-dir
+Configuration directory to use.
+.TP
+.B \-U, \-\-username
+Login with this username.
+.TP
+.B \-P, \-\-password
+Login with this password.
+.TP
+.B \-c, \-\-character
+Login with this character.
+.TP
+.B \-s, \-\-server
+Login server name or IP.
+.TP
+.B \-p, \-\-port
+Login server port.
+.TP
+.B \-\-update\-host
+Use this update host.
+.TP
+.B \-D, \-\-default
+Choose default character server and character.
+.TP
+.B \-u, \-\-skip\-update
+Skip the update process.
+.TP
+.B \-d, \-\-data
+Directory to load game data from.
+.TP
+.B \-L, \-\-local\-data\-dir
+Directory to use as local data directory.
+.TP
+.B \-\-screenshot\-dir
+Directory to store screenshots.
+.TP
+.B \-\-safemode
+Start game in safe mode.
+.TP
+.B \-\-no-opengl
+Disable OpenGL for this session.
+.SH "COMMON KEYS"
+.TP
+.B Arrow Keys:
+Move your character around.
+.TP
+.B Left Ctrl:
+Make your character attack.
+.TP
+.B Key A:
+Target nearest monster.
+.TP
+.B Key G:
+Get items on the ground or in a chest.
+.TP
+.B Alt + 1...9:
+Shows an emoticon above your character.
+.TP
+.B Alt + I:
+Shows / Hide inventory window.
+.TP
+.B Alt + K:
+Shows / Hide skills window.
+.TP
+.B Alt + E:
+Shows / Hide equipment window.
+.TP
+.B Alt + C:
+Shows configuration window.
+.SH "AUTHOR"
+This manual page was written by Patrick Matth\[:a]i <patrick.matthaei@web.de>
+for the Mana project.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License, Version 2 any
+later version published by the Free Software Foundation.
diff --git a/docs/packages.txt b/docs/packages.txt
new file mode 100644
index 000000000..b46502414
--- /dev/null
+++ b/docs/packages.txt
@@ -0,0 +1,250 @@
+-----------------------------
+MANA PACKAGE SYSTEM
+-----------------------------
+
+1. INTRODUCTION
+2. LOCATION OF DATA
+3. CONTENTS OF DATA PACKAGE
+4. TYPES OF DATA
+5. INITIALIZING PACKAGE MANAGEMENT
+6. LOADING A REQUESTED RESOURCE
+7. RESOURCE MANAGEMENT DETAILS
+
+
+1. INTRODUCTION
+
+Mana is expected to grow continuously with updates to the game world
+occurring relatively frequently. More often so than for example new releases
+of the game client. To make sure players don't have to update their data
+manually all the time, by for example downloading the latest from the website,
+the Mana client should be able to automatically obtain new data packages from
+the server.
+
+ Note: To reduce the load on the server (which isn't expected to have huge
+ free uploading resources), the idea is that the server will only send a
+ torrent file to the client and that the file is subsequently downloaded from
+ several locations that have volunteered to spread Mana data files. Ultimately
+ a simple option on the client will even allow players to contribute their
+ excess bandwidth to help other players get the updates faster.
+
+
+2. LOCATION OF DATA
+
+There are two locations where Mana can look for game data. The install data
+directory and the data directory in the user's home directory. The latter one
+doesn't have to be used for Windows users, but is required for dynamic updates
+for UNIX users, who generally won't have write permissions to the install
+data directory. So for UNIX the two locations are:
+
+ /usr/local/share/manaworld/data/*
+
+ ~/.manaworld/data/*
+
+While for Windows all the data will be located at:
+
+ C:\Program Files\Mana\data\*
+
+In the UNIX case it doesn't matter in which order the data directories are
+examined.
+
+
+3. CONTENTS OF DATA PACKAGE
+
+The contents of the data packages are strictly categorized and all packages
+share a single root, similar to the paths on a UNIX system. The name of the
+package is irrelevant. An example of the contents is given by:
+
+ /graphics/sprites/forest/pinetree.png
+ /graphics/sprites/furniture/bed.png
+ /graphics/tiles/dark_forest.png
+ /graphics/tiles/city.png
+ /music/eagles_are_watching.xm
+ /music/silent_rose.xm
+ /sound/battle/sword1.ogg
+ /sound/battle/sword2.ogg
+ /maps/deep_desert.tmx
+ /maps/desert_town.tmx
+ /tilesets/dark_forest.tsx
+ /tilesets/city.tsx
+ /scripts/Portal.rb
+ /scripts/PawnShop.rb
+ /scripts/Fountain.rb
+
+
+4. TYPES OF DATA
+
+ png - The preferred format for images
+ xm - The preferred format for music (or other kinds of module formats)
+ ogg - The preferred format for sound effects
+ tmx - The map format (to be implemented)
+ tsx - The tile set format (to be implemented)
+ rb - A Ruby script file (application to be discussed)
+
+
+5. INITIALIZING PACKAGE MANAGEMENT
+
+When Mana starts it will scan its data directories for both packages (archives)
+and directories. When a directory is found with the same name as a package, the
+directory is the preferred location to load data from as it is assumed to be
+more up to date.
+
+Each package will have an ID and a file listing associated with it. Having made
+a list of all packages they are processed in the order of their IDs. A mapping
+is made from file to package, as follows:
+
+ /music/eagles_are_watching.xm -> /usr/local/share/manaworld/data/musicpack
+ /music/silent_rose.xm -> /usr/local/share/manaworld/data/musicpack
+ /sound/battle/sword1.ogg -> ~/.manaworld/data/patch1
+ /sound/battle/sword2.ogg -> ~/.manaworld/data/patch1
+ ...
+
+Because the packages are loaded in the order of their IDs, it is made sure that
+each file will always point to the package in which is was last updated. The
+package IDs make sure that there is an absolute ordering of the packages.
+
+To allow the client to get rid of old packages, a package can declare an
+arbitrary amount of packages with a lower ID than itself as obsolete. These
+packages will then be ignored by the client, and optionally they can be
+automatically deleted.
+
+
+6. LOADING A REQUESTED RESOURCE
+
+When the game starts and during the game, resources will continuously be asked
+for. A resource manager will take care that each resource is only loaded once.
+It also makes sure that the resources are loaded from the right package using
+the constructed mapping.
+
+As noted above, the resource manager makes sure directories are preferred
+to package files when resources are loaded. The presence of directories is
+only expected in the case of developers that will relatively frequently update
+the data while working on the next package to be released.
+
+
+7. RESOURCE MANAGEMENT DETAILS
+
+The resource management technique is critical to the overall success of the
+package management system as a whole. Resources are loaded at runtime as they
+are needed, and unloaded as they become unused. In order to ensure the
+autonomous functioning of this process reference counting is the agreed upon
+technique for managing loaded resources in Mana.
+
+For those unfamiliar with the practice of reference counting, it involves
+every resource object having a variable containing the number of references to
+the object. When a reference is added the function addRef() is called and when
+it is removed the function release() is called. When the reference count
+reaches zero the object will automatically delete itself, thus handling the
+cleanup of resources.
+
+Reference counting will form the core of the resource management system. Each
+resource object will have the functionality of a reference counted object. The
+resource manager will hold ResourceEntry objects. The resource entry object
+contains a pointer to the resource as well as the location of the path of the
+file the resource was loaded from. This would look something like:
+
+ /**
+ * A generic reference counted resource object.
+ */
+ class Resource {
+ public:
+ /**
+ * Loads the resource from the specified path.
+ * @param filePath The path to the file to be loaded.
+ * @return <code>true</code> if loaded <code>false</code> otherwise.
+ */
+ virtual bool Load(std::string filePath) = 0;
+ ...
+ /**
+ * Increments the reference counted of this object.
+ */
+ void addRef() { ++referenceCount; }
+
+ /**
+ * Decrements the reference count and deletes the object
+ * if no references are left.
+ * @return <code>true</code> if the object was deleted
+ * <code>false</code> otherwise.
+ */
+ void release() {
+ --referenceCount;
+
+ if (!referenceCount)
+ {
+ delete this;
+ return true;
+ }
+
+ return false;
+ }
+ private:
+ unsigned int referenceCount;
+ };
+ ...
+ /**
+ * A resource entry descriptor.
+ */
+ struct ResourceEntry {
+ Resource* resource;
+ std::string filePath;
+ };
+ ...
+
+The resource manager would then hold a mapping containing the resource entry as
+well as the string defining its resource identification path. The resource
+manager would thus look something like this:
+
+ /**
+ * A class for loading and managing resources.
+ */
+ class ResourceManager {
+ public:
+ ...
+ private:
+ std::map<std::string, ResourceEntry> resources;
+ };
+ ...
+
+This will allow the game to load resources with little awareness of the actual
+path from which they were loaded. The resource manager will also act as a
+resource object factory. A factory object is an object that creates an
+instance of an object derived from a common base class. In this case it will
+create Resource objects. This would make the ResourceManager object look like
+this:
+
+ /**
+ * A class for loading and managing resources.
+ */
+ class ResourceManager {
+ public:
+ enum E_RESOURCE_TYPE
+ {
+ MAP,
+ MUSIC,
+ IMAGE,
+ SCRIPT,
+ TILESET,
+ SOUND_EFFECT
+ };
+
+ /**
+ * Creates a resource and adds it to the resource map.
+ * The idPath is converted into the appropriate path
+ * for the current operating system and the resource
+ * is loaded.
+ * @param type The type of resource to load.
+ * @param idPath The resource identifier path.
+ * @return A valid resource or <code>NULL</code> if
+ * the resource could not be loaded.
+ */
+ Resource* Create(const E_RESOURCE_TYPE& type,
+ std::string idPath);
+ ...
+ private:
+ std::map<std::string, ResourceEntry> resources;
+ };
+ ...
+
+Loading a resource would then look something like:
+
+ Image* img = (Image*) ResourceManager.Create(ResourceManager::IMAGE,
+ "/graphics/tiles/dark_forest.png");
diff --git a/docs/progression.txt b/docs/progression.txt
new file mode 100644
index 000000000..a25cf11fd
--- /dev/null
+++ b/docs/progression.txt
@@ -0,0 +1,129 @@
+-----------------------------------
+THE MANA WORLD PLAYER'S PROGRESSION
+-----------------------------------
+
+1. PLAYER'S STATS
+2. PLAYER'S STATUS
+3. AN ATTACK PROCESS
+4. LEVELS
+
+1. PLAYER'S STATS
+
+Strength : The Strength determines how much a player will physically damage
+ an enemy.
+
+Vitality : The Vitality deals with the player's HP, and damage resistance.
+
+Agility : The Agility determines the attacks frequency of a player, and
+ the ability to escape attacks from an encounter.
+
+Intelligence : The Intelligence determines how many MP a player can have, how
+ many abilities he can master, and how strong his magic attacks
+ can be.
+
+Spirit : The Spirit deals with the player's magic resistance, and also
+ with magic effectiveness.
+
+Luck : The Player's Luck determines the player's evades, how he can
+ deals critical attacks, and a little bit with the hit
+ percentage.
+
+A Player has got 11 points to distribute to each stat before beginning at
+level 1. A Stat must have at least 1 point given to it. The Player earns 1
+point for each level he reaches.
+
+
+2. PLAYER'S STATUS
+
+HP : Hit Points. How much a player can be hit before dying.
+ HP = (3 * Vitality) + Strength + Level
+
+MP : Magic Points. Used by Spells, or Special Skills.
+ MP = 2 * Intelligence + Spirit
+
+Attack : The Attack tells how much exactly the player will reduce the
+ opponent's HP, minus its defense and extra protection.
+ Attack = 3 * Strength + Luck
+
+Defense : The Defense will reduce the HP damage taken by an opponent.
+ Defense = 2 * Vitality + Agility + Luck
+
+Magic Attack : Same but for the might of your spells.
+ Magic Attack = 3 * Intelligence + Spirit
+
+Magic Defense : Same but for the defense against magic skills and spells.
+ Magic Defense = 3 * Spirit + Luck
+
+Hit (%) : Indicate the chance a player has to hit an opponent. The Score
+ is in percentage.
+ Hit = ((3 * Luck + 2 * Agility + Intelligence) / 6) * 10
+ (Max : 125 %)
+
+Evade (%) : Indicate the chance a player has to evade an opponent's hit.
+ The score is in percentage.
+ Evade = ((3 * Luck + Spirit + Vitality )/5) (Max : 75 %)
+
+
+3. AN ATTACK PROCESS
+
+An attack process is quite simple :
+The Hit(%) of the attacker is taken, minus the evade of the opponent.
+A random score is taken by the server and if it's less than the Attacker's Hit
+modified, the attacker actually hits the opponent.
+N.B. : A magic attack never miss if it isn't based on status changing.
+For instance, a fire ball always touches the opponent.
+
+Then, the attack plus the its modifiers (weapons attack upgrade, items bonus,
+...) minus the opponent defense (plus bonus) is taken to reduce the opponent
+HP.
+
+
+4. LEVELS
+
+The XP-For-The-Next-Level of a player is calculated with his/her class number.
+Cf. Class Number for more information. Higher is the class, higher is the class
+number.
+
+Minimum XP For This Level = Level^3 + ClassNumber * Level.
+XP For Next Level = (Level + 1)^3 + ClassNumber * (Niveau + 1).
+
+To be of a level, a player must have an actual XP which is between minimum and
+xp for next level.
+N.B. : A player earns 1 stat point for each level he reaches.
+
+
+5. JOB POINTS
+
+Job Points are used to get skill points, that can be used to learned and
+reinforce special skills, which can be acquired by being of certain classes.
+
+Job points are obtained by job leveling.
+!! : Changing the class of a character reset to the job level of the character
+ the last time he was of that class. It can be zero if the player has never
+ been of this class!
+
+Job level : 20 + 2^Level + Level.
+
+6. CLASSES
+
+A player can be one of mutiple classes ; A wizard is different from a archer,
+and can't held the same weapons, armors, etc... A score is associated with each
+class defining how hard it is to level for a player. Also, special skills can
+be learned from each classes, by giving them skill points, earned by gaining
+job points.
+
+Classes --- Class Nr -- Skill Associated ------------------- Conditions -------
+
+Beginner 16 Sitting (JobLvl : 4)
+Apprentice 17 Fire Ball, Ice Needles (JobLvl : 4) Beginner Lvl:10
+Archer 17 Hard Shot, Line Shot (JL:5) Beginner Lvl:10
+Peon 17 Double Hit, Hard Hit(JL:5) Beginner Lvl:10
+...
+
+
+7. NOTES
+
+Every of these notes have to be discussed, if you have any feedback,
+suggestions, updates, commit or tell them at:
+
+address: irc://irc.freenode.net channel: #themanaworld
diff --git a/docs/sounddev.txt b/docs/sounddev.txt
new file mode 100644
index 000000000..149150bab
--- /dev/null
+++ b/docs/sounddev.txt
@@ -0,0 +1,38 @@
+--------------------------------
+THE MANA WORLD SOUND DEVELOPMENT
+--------------------------------
+
+1. INTRODUCTION
+2. SPECS
+3. DATA REQUIRED
+4. SUGGESTION
+
+1. INTRODUCTION
+
+In The Mana World we plan to have both background music and sound effects
+linked to beings actions.
+
+2. SPECS
+
+The preferred file format is Ogg mastered at 22.050 Hz. Quality factor 3.0
+should be enough.
+We strongly recomend to not convert the file from a previous format to avoid
+loss of quality. 22 Khz is not the best quality we can have, that's why is
+really important to have the sound digitally recorded and without noise at
+all.
+
+3. DATA REQUIRED
+
+- Login BGM (need to be remastered to improve quality, tempo and remove noise)
+- Amzeroth (or whatever it's the name) BGM
+- South field BGM
+- Level up SFX
+- Sword slash SFX
+- Bow shot SFX
+- Monsters attack SFX
+- Monsters death SFX
+- Potion SFX (used for every recovery item)
+
+4. SUGGESTIONS
+
+As placeholders we could use Wesnoth SFX/BGM to test the sound engine. \ No newline at end of file
diff --git a/makecheck1 b/makecheck1
new file mode 100755
index 000000000..2758b123d
--- /dev/null
+++ b/makecheck1
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+cppcheck --enable=all --force -j 5 -v . 1>makecheck.txt 2>makecheck_err.txt
diff --git a/makecheck2 b/makecheck2
new file mode 100755
index 000000000..566b60005
--- /dev/null
+++ b/makecheck2
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+../nsiqcppstyle/nsiqcppstyle/nsiqcppstyle --show-url ./src >make_nsiqcppstyle.txt
diff --git a/makeflawfinder b/makeflawfinder
new file mode 100755
index 000000000..13d7dde19
--- /dev/null
+++ b/makeflawfinder
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+flawfinder ./src 1> makeflawfinder.log
+rats ./src 1> makerats.log
diff --git a/makegprof b/makegprof
new file mode 100755
index 000000000..8cb63744c
--- /dev/null
+++ b/makegprof
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+mv run/gmon.out .
+gprof run/bin/manaplus >gprof.txt
+cat gprof.txt | gprof2dot.py | dot -Tpng -o gprof.png
diff --git a/mana.cbp b/mana.cbp
new file mode 100644
index 000000000..7a511c3eb
--- /dev/null
+++ b/mana.cbp
@@ -0,0 +1,659 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="ManaPlus Client" />
+ <Option pch_mode="0" />
+ <Option compiler="gcc" />
+ <Build>
+ <Target title="Windows">
+ <Option output="manaplus.exe" prefix_auto="0" extension_auto="0" />
+ <Option object_output=".objs\" />
+ <Option type="0" />
+ <Option compiler="gcc" />
+ <Option parameters="-u -d C:\mana\data" />
+ <Option projectResourceIncludeDirsRelation="0" />
+ <Compiler>
+ <Add option="-O3" />
+ <Add option="-Wall" />
+ <Add option="-DUSE_OPENGL" />
+ <Add option="-DNOGDI" />
+ <Add option="-DENABLE_NLS" />
+ <Add option="-DEATHENA_SUPPORT" />
+ </Compiler>
+ <Linker>
+ <Add option="-enable-auto-import" />
+ <Add library="guichan" />
+ <Add library="guichan_sdl" />
+ <Add library="guichan_opengl" />
+ <Add library="wsock32" />
+ <Add library="SDL_image" />
+ <Add library="SDL_mixer" />
+ <Add library="SDL_net" />
+ <Add library="SDL_ttf" />
+ <Add library="SDL_gfx" />
+ <Add library="mingw32" />
+ <Add library="SDLmain" />
+ <Add library="SDL.dll" />
+ <Add library="xml2.dll" />
+ <Add library="opengl32" />
+ <Add library="png12.dll" />
+ <Add library="z.dll" />
+ <Add library="physfs" />
+ <Add library="curl.dll" />
+ <Add library="intl" />
+ <Add library="enet" />
+ <Add library="ws2_32" />
+ <Add library="winmm" />
+ <Add directory="E:\Programme\CodeBlocks\include\SDL" />
+ </Linker>
+ </Target>
+ <Target title="Unix">
+ <Option platforms="Unix;" />
+ <Option output="mana" prefix_auto="1" extension_auto="1" />
+ <Option type="0" />
+ <Option compiler="gcc" />
+ <Option parameters='-u -d &quot;../manadata&quot;' />
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-g" />
+ <Add option="`sdl-config --cflags`" />
+ <Add option="-DMANASERV_SUPPORT" />
+ <Add option="-DUSE_OPENGL" />
+ <Add directory="\usr\local\include\libxml2" />
+ </Compiler>
+ <Linker>
+ <Add option="`sdl-config --libs`" />
+ <Add library="guichan" />
+ <Add library="guichan_sdl" />
+ <Add library="guichan_opengl" />
+ <Add library="GL" />
+ <Add library="physfs" />
+ <Add library="curl" />
+ <Add library="xml2" />
+ <Add library="SDL_mixer" />
+ <Add library="SDL_net" />
+ <Add library="SDL_image" />
+ <Add library="SDL_ttf" />
+ <Add library="SDL_gfx" />
+ <Add library="png" />
+ <Add library="enet" />
+ </Linker>
+ </Target>
+ </Build>
+ <VirtualTargets>
+ <Add alias="All" targets="Windows;" />
+ </VirtualTargets>
+ <Compiler>
+ <Add directory="src\" />
+ <Add directory="include" />
+ <Add directory="include\libxml2" />
+ <Add directory="include\SDL" />
+ </Compiler>
+ <Linker>
+ <Add directory="lib" />
+ </Linker>
+ <Unit filename="src\SDLMain.h" />
+ <Unit filename="src\SDLMain.m" />
+ <Unit filename="src\actor.cpp" />
+ <Unit filename="src\actor.h" />
+ <Unit filename="src\actorsprite.cpp" />
+ <Unit filename="src\actorsprite.h" />
+ <Unit filename="src\actorspritelistener.h" />
+ <Unit filename="src\actorspritemanager.cpp" />
+ <Unit filename="src\actorspritemanager.h" />
+ <Unit filename="src\animatedsprite.cpp" />
+ <Unit filename="src\animatedsprite.h" />
+ <Unit filename="src\animationparticle.cpp" />
+ <Unit filename="src\animationparticle.h" />
+ <Unit filename="src\avatar.cpp" />
+ <Unit filename="src\avatar.h" />
+ <Unit filename="src\being.cpp" />
+ <Unit filename="src\being.h" />
+ <Unit filename="src\channel.cpp" />
+ <Unit filename="src\channel.h" />
+ <Unit filename="src\channelmanager.cpp" />
+ <Unit filename="src\channelmanager.h" />
+ <Unit filename="src\chatlog.cpp" />
+ <Unit filename="src\chatlog.h" />
+ <Unit filename="src\client.cpp" />
+ <Unit filename="src\client.h" />
+ <Unit filename="src\commandhandler.cpp" />
+ <Unit filename="src\commandhandler.h" />
+ <Unit filename="src\compoundsprite.cpp" />
+ <Unit filename="src\compoundsprite.h" />
+ <Unit filename="src\configlistener.h" />
+ <Unit filename="src\configuration.cpp" />
+ <Unit filename="src\configuration.h" />
+<<<<<<< HEAD
+ <Unit filename="src\dropshortcut.cpp" />
+ <Unit filename="src\dropshortcut.h" />
+=======
+ <Unit filename="src\defaults.cpp" />
+ <Unit filename="src\defaults.h" />
+>>>>>>> master
+ <Unit filename="src\effectmanager.cpp" />
+ <Unit filename="src\effectmanager.h" />
+ <Unit filename="src\emoteshortcut.cpp" />
+ <Unit filename="src\emoteshortcut.h" />
+ <Unit filename="src\equipment.h" />
+ <Unit filename="src\event.cpp" />
+ <Unit filename="src\event.h" />
+ <Unit filename="src\eventmanager.cpp" />
+ <Unit filename="src\eventmanager.h" />
+ <Unit filename="src\flooritem.cpp" />
+ <Unit filename="src\flooritem.h" />
+ <Unit filename="src\game.cpp" />
+ <Unit filename="src\game.h" />
+ <Unit filename="src\graphics.cpp" />
+ <Unit filename="src\graphics.h" />
+ <Unit filename="src\gui\beingpopup.cpp" />
+ <Unit filename="src\gui\beingpopup.h" />
+ <Unit filename="src\gui\botcheckerwindow.cpp" />
+ <Unit filename="src\gui\botcheckerwindow.h" />
+ <Unit filename="src\gui\buy.cpp" />
+ <Unit filename="src\gui\buy.h" />
+ <Unit filename="src\gui\buysell.cpp" />
+ <Unit filename="src\gui\buysell.h" />
+ <Unit filename="src\gui\changeemaildialog.cpp" />
+ <Unit filename="src\gui\changeemaildialog.h" />
+ <Unit filename="src\gui\changepassworddialog.cpp" />
+ <Unit filename="src\gui\changepassworddialog.h" />
+ <Unit filename="src\gui\charcreatedialog.cpp" />
+ <Unit filename="src\gui\charcreatedialog.h" />
+ <Unit filename="src\gui\charselectdialog.cpp" />
+ <Unit filename="src\gui\charselectdialog.h" />
+ <Unit filename="src\gui\chat.cpp" />
+ <Unit filename="src\gui\chat.h" />
+ <Unit filename="src\gui\confirmdialog.cpp" />
+ <Unit filename="src\gui\confirmdialog.h" />
+ <Unit filename="src\gui\connectiondialog.cpp" />
+ <Unit filename="src\gui\connectiondialog.h" />
+ <Unit filename="src\gui\debugwindow.cpp" />
+ <Unit filename="src\gui\debugwindow.h" />
+ <Unit filename="src\gui\editdialog.cpp" />
+ <Unit filename="src\gui\editdialog.h" />
+ <Unit filename="src\gui\emotepopup.cpp" />
+ <Unit filename="src\gui\emotepopup.h" />
+ <Unit filename="src\gui\equipmentwindow.cpp" />
+ <Unit filename="src\gui\equipmentwindow.h" />
+ <Unit filename="src\gui\focushandler.cpp" />
+ <Unit filename="src\gui\focushandler.h" />
+ <Unit filename="src\gui\gui.cpp" />
+ <Unit filename="src\gui\gui.h" />
+ <Unit filename="src\gui\help.cpp" />
+ <Unit filename="src\gui\help.h" />
+ <Unit filename="src\gui\inventorywindow.cpp" />
+ <Unit filename="src\gui\inventorywindow.h" />
+ <Unit filename="src\gui\itemamount.cpp" />
+ <Unit filename="src\gui\itemamount.h" />
+ <Unit filename="src\gui\itempopup.cpp" />
+ <Unit filename="src\gui\itempopup.h" />
+ <Unit filename="src\gui\killstats.cpp" />
+ <Unit filename="src\gui\killstats.h" />
+ <Unit filename="src\gui\login.cpp" />
+ <Unit filename="src\gui\login.h" />
+ <Unit filename="src\gui\minimap.cpp" />
+ <Unit filename="src\gui\minimap.h" />
+ <Unit filename="src\gui\ministatus.cpp" />
+ <Unit filename="src\gui\ministatus.h" />
+ <Unit filename="src\gui\npcdialog.cpp" />
+ <Unit filename="src\gui\npcdialog.h" />
+ <Unit filename="src\gui\npcpostdialog.cpp" />
+ <Unit filename="src\gui\npcpostdialog.h" />
+ <Unit filename="src\gui\okdialog.cpp" />
+ <Unit filename="src\gui\okdialog.h" />
+ <Unit filename="src\gui\outfitwindow.cpp" />
+ <Unit filename="src\gui\outfitwindow.h" />
+ <Unit filename="src\gui\palette.cpp" />
+ <Unit filename="src\gui\palette.h" />
+ <Unit filename="src\gui\popupmenu.cpp" />
+ <Unit filename="src\gui\popupmenu.h" />
+ <Unit filename="src\gui\quitdialog.cpp" />
+ <Unit filename="src\gui\quitdialog.h" />
+ <Unit filename="src\gui\register.cpp" />
+ <Unit filename="src\gui\register.h" />
+ <Unit filename="src\gui\sdlinput.cpp" />
+ <Unit filename="src\gui\sdlinput.h" />
+ <Unit filename="src\gui\sell.cpp" />
+ <Unit filename="src\gui\sell.h" />
+ <Unit filename="src\gui\serverdialog.cpp" />
+ <Unit filename="src\gui\serverdialog.h" />
+ <Unit filename="src\gui\setup.cpp" />
+ <Unit filename="src\gui\setup.h" />
+ <Unit filename="src\gui\setup_audio.cpp" />
+ <Unit filename="src\gui\setup_audio.h" />
+ <Unit filename="src\gui\setup_chat.cpp" />
+ <Unit filename="src\gui\setup_chat.h" />
+ <Unit filename="src\gui\setup_colors.cpp" />
+ <Unit filename="src\gui\setup_colors.h" />
+ <Unit filename="src\gui\setup_joystick.cpp" />
+ <Unit filename="src\gui\setup_joystick.h" />
+ <Unit filename="src\gui\setup_keyboard.cpp" />
+ <Unit filename="src\gui\setup_keyboard.h" />
+ <Unit filename="src\gui\setup_other.cpp" />
+ <Unit filename="src\gui\setup_other.h" />
+ <Unit filename="src\gui\setup_players.cpp" />
+ <Unit filename="src\gui\setup_players.h" />
+ <Unit filename="src\gui\setup_theme.cpp" />
+ <Unit filename="src\gui\setup_theme.h" />
+ <Unit filename="src\gui\setup_video.cpp" />
+ <Unit filename="src\gui\setup_video.h" />
+ <Unit filename="src\gui\shopwindow.cpp" />
+ <Unit filename="src\gui\shopwindow.h" />
+ <Unit filename="src\gui\shortcutwindow.cpp" />
+ <Unit filename="src\gui\shortcutwindow.h" />
+ <Unit filename="src\gui\skilldialog.cpp" />
+ <Unit filename="src\gui\skilldialog.h" />
+ <Unit filename="src\gui\socialwindow.cpp" />
+ <Unit filename="src\gui\socialwindow.h" />
+ <Unit filename="src\gui\specialswindow.cpp" />
+ <Unit filename="src\gui\specialswindow.h" />
+ <Unit filename="src\gui\speechbubble.cpp" />
+ <Unit filename="src\gui\speechbubble.h" />
+ <Unit filename="src\gui\spellpopup.cpp" />
+ <Unit filename="src\gui\spellpopup.h" />
+ <Unit filename="src\gui\statuspopup.cpp" />
+ <Unit filename="src\gui\statuspopup.h" />
+ <Unit filename="src\gui\statuswindow.cpp" />
+ <Unit filename="src\gui\statuswindow.h" />
+ <Unit filename="src\gui\textcommandeditor.cpp" />
+ <Unit filename="src\gui\textcommandeditor.h" />
+ <Unit filename="src\gui\textdialog.cpp" />
+ <Unit filename="src\gui\textdialog.h" />
+ <Unit filename="src\gui\textpopup.cpp" />
+ <Unit filename="src\gui\textpopup.h" />
+ <Unit filename="src\gui\theme.cpp" />
+ <Unit filename="src\gui\theme.h" />
+ <Unit filename="src\gui\trade.cpp" />
+ <Unit filename="src\gui\trade.h" />
+ <Unit filename="src\gui\truetypefont.cpp" />
+ <Unit filename="src\gui\truetypefont.h" />
+ <Unit filename="src\gui\unregisterdialog.cpp" />
+ <Unit filename="src\gui\unregisterdialog.h" />
+ <Unit filename="src\gui\updatewindow.cpp" />
+ <Unit filename="src\gui\updatewindow.h" />
+ <Unit filename="src\gui\userpalette.cpp" />
+ <Unit filename="src\gui\userpalette.h" />
+ <Unit filename="src\gui\viewport.cpp" />
+ <Unit filename="src\gui\viewport.h" />
+ <Unit filename="src\gui\whoisonline.cpp" />
+ <Unit filename="src\gui\whoisonline.h" />
+ <Unit filename="src\gui\widgets\avatarlistbox.cpp" />
+ <Unit filename="src\gui\widgets\avatarlistbox.h" />
+ <Unit filename="src\gui\widgets\browserbox.cpp" />
+ <Unit filename="src\gui\widgets\browserbox.h" />
+ <Unit filename="src\gui\widgets\button.cpp" />
+ <Unit filename="src\gui\widgets\button.h" />
+ <Unit filename="src\gui\widgets\channeltab.cpp" />
+ <Unit filename="src\gui\widgets\channeltab.h" />
+ <Unit filename="src\gui\widgets\chattab.cpp" />
+ <Unit filename="src\gui\widgets\chattab.h" />
+ <Unit filename="src\gui\widgets\checkbox.cpp" />
+ <Unit filename="src\gui\widgets\checkbox.h" />
+ <Unit filename="src\gui\widgets\container.cpp" />
+ <Unit filename="src\gui\widgets\container.h" />
+ <Unit filename="src\gui\widgets\desktop.cpp" />
+ <Unit filename="src\gui\widgets\desktop.h" />
+ <Unit filename="src\gui\widgets\dropdown.cpp" />
+ <Unit filename="src\gui\widgets\dropdown.h" />
+ <Unit filename="src\gui\widgets\dropshortcutcontainer.cpp" />
+ <Unit filename="src\gui\widgets\dropshortcutcontainer.h" />
+ <Unit filename="src\gui\widgets\emoteshortcutcontainer.cpp" />
+ <Unit filename="src\gui\widgets\emoteshortcutcontainer.h" />
+ <Unit filename="src\gui\widgets\flowcontainer.cpp" />
+ <Unit filename="src\gui\widgets\flowcontainer.h" />
+ <Unit filename="src\gui\widgets\icon.cpp" />
+ <Unit filename="src\gui\widgets\icon.h" />
+ <Unit filename="src\gui\widgets\inttextfield.cpp" />
+ <Unit filename="src\gui\widgets\inttextfield.h" />
+ <Unit filename="src\gui\widgets\itemcontainer.cpp" />
+ <Unit filename="src\gui\widgets\itemcontainer.h" />
+ <Unit filename="src\gui\widgets\itemlinkhandler.cpp" />
+ <Unit filename="src\gui\widgets\itemlinkhandler.h" />
+ <Unit filename="src\gui\widgets\itemshortcutcontainer.cpp" />
+ <Unit filename="src\gui\widgets\itemshortcutcontainer.h" />
+ <Unit filename="src\gui\widgets\label.cpp" />
+ <Unit filename="src\gui\widgets\label.h" />
+ <Unit filename="src\gui\widgets\layout.cpp" />
+ <Unit filename="src\gui\widgets\layout.h" />
+ <Unit filename="src\gui\widgets\layouthelper.cpp" />
+ <Unit filename="src\gui\widgets\layouthelper.h" />
+ <Unit filename="src\gui\widgets\linkhandler.h" />
+ <Unit filename="src\gui\widgets\listbox.cpp" />
+ <Unit filename="src\gui\widgets\listbox.h" />
+ <Unit filename="src\gui\widgets\passwordfield.cpp" />
+ <Unit filename="src\gui\widgets\passwordfield.h" />
+ <Unit filename="src\gui\widgets\playerbox.cpp" />
+ <Unit filename="src\gui\widgets\playerbox.h" />
+ <Unit filename="src\gui\widgets\popup.cpp" />
+ <Unit filename="src\gui\widgets\popup.h" />
+ <Unit filename="src\gui\widgets\progressbar.cpp" />
+ <Unit filename="src\gui\widgets\progressbar.h" />
+ <Unit filename="src\gui\widgets\progressindicator.cpp" />
+ <Unit filename="src\gui\widgets\progressindicator.h" />
+ <Unit filename="src\gui\widgets\radiobutton.cpp" />
+ <Unit filename="src\gui\widgets\radiobutton.h" />
+ <Unit filename="src\gui\widgets\resizegrip.cpp" />
+ <Unit filename="src\gui\widgets\resizegrip.h" />
+ <Unit filename="src\gui\widgets\scrollarea.cpp" />
+ <Unit filename="src\gui\widgets\scrollarea.h" />
+ <Unit filename="src\gui\widgets\setuptab.cpp" />
+ <Unit filename="src\gui\widgets\setuptab.h" />
+ <Unit filename="src\gui\widgets\shopitems.cpp" />
+ <Unit filename="src\gui\widgets\shopitems.h" />
+ <Unit filename="src\gui\widgets\shoplistbox.cpp" />
+ <Unit filename="src\gui\widgets\shoplistbox.h" />
+ <Unit filename="src\gui\widgets\shortcutcontainer.cpp" />
+ <Unit filename="src\gui\widgets\shortcutcontainer.h" />
+ <Unit filename="src\gui\widgets\slider.cpp" />
+ <Unit filename="src\gui\widgets\slider.h" />
+ <Unit filename="src\gui\widgets\spellshortcutcontainer.cpp" />
+ <Unit filename="src\gui\widgets\spellshortcutcontainer.h" />
+ <Unit filename="src\gui\widgets\tab.cpp" />
+ <Unit filename="src\gui\widgets\tab.h" />
+ <Unit filename="src\gui\widgets\tabbedarea.cpp" />
+ <Unit filename="src\gui\widgets\tabbedarea.h" />
+ <Unit filename="src\gui\widgets\table.cpp" />
+ <Unit filename="src\gui\widgets\table.h" />
+ <Unit filename="src\gui\widgets\tablemodel.cpp" />
+ <Unit filename="src\gui\widgets\tablemodel.h" />
+ <Unit filename="src\gui\widgets\textbox.cpp" />
+ <Unit filename="src\gui\widgets\textbox.h" />
+ <Unit filename="src\gui\widgets\textfield.cpp" />
+ <Unit filename="src\gui\widgets\textfield.h" />
+ <Unit filename="src\gui\widgets\textpreview.cpp" />
+ <Unit filename="src\gui\widgets\textpreview.h" />
+ <Unit filename="src\gui\widgets\tradetab.cpp" />
+ <Unit filename="src\gui\widgets\tradetab.h" />
+ <Unit filename="src\gui\widgets\vertcontainer.cpp" />
+ <Unit filename="src\gui\widgets\vertcontainer.h" />
+ <Unit filename="src\gui\widgets\whispertab.cpp" />
+ <Unit filename="src\gui\widgets\whispertab.h" />
+ <Unit filename="src\gui\widgets\window.cpp" />
+ <Unit filename="src\gui\widgets\window.h" />
+ <Unit filename="src\gui\widgets\windowcontainer.cpp" />
+ <Unit filename="src\gui\widgets\windowcontainer.h" />
+ <Unit filename="src\gui\windowmenu.cpp" />
+ <Unit filename="src\gui\windowmenu.h" />
+ <Unit filename="src\gui\worldselectdialog.cpp" />
+ <Unit filename="src\gui\worldselectdialog.h" />
+ <Unit filename="src\guichanfwd.h" />
+ <Unit filename="src\guild.cpp" />
+ <Unit filename="src\guild.h" />
+ <Unit filename="src\imageparticle.cpp" />
+ <Unit filename="src\imageparticle.h" />
+ <Unit filename="src\imagesprite.cpp" />
+ <Unit filename="src\imagesprite.h" />
+ <Unit filename="src\inventory.cpp" />
+ <Unit filename="src\inventory.h" />
+ <Unit filename="src\item.cpp" />
+ <Unit filename="src\item.h" />
+ <Unit filename="src\itemshortcut.cpp" />
+ <Unit filename="src\itemshortcut.h" />
+ <Unit filename="src\joystick.cpp" />
+ <Unit filename="src\joystick.h" />
+ <Unit filename="src\keyboardconfig.cpp" />
+ <Unit filename="src\keyboardconfig.h" />
+ <Unit filename="src\listener.cpp" />
+ <Unit filename="src\listener.h" />
+ <Unit filename="src\localplayer.cpp" />
+ <Unit filename="src\localplayer.h" />
+ <Unit filename="src\log.cpp" />
+ <Unit filename="src\log.h" />
+ <Unit filename="src\main.cpp" />
+ <Unit filename="src\main.h" />
+ <Unit filename="src\mana.rc">
+ <Option compilerVar="WINDRES" />
+ </Unit>
+ <Unit filename="src\map.cpp" />
+ <Unit filename="src\map.h" />
+ <Unit filename="src\mumblemanager.cpp" />
+ <Unit filename="src\mumblemanager.h" />
+ <Unit filename="src\net\adminhandler.h" />
+ <Unit filename="src\net\charhandler.cpp" />
+ <Unit filename="src\net\charhandler.h" />
+ <Unit filename="src\net\chathandler.h" />
+ <Unit filename="src\net\download.cpp" />
+ <Unit filename="src\net\download.h" />
+ <Unit filename="src\net\gamehandler.h" />
+ <Unit filename="src\net\generalhandler.h" />
+ <Unit filename="src\net\guildhandler.h" />
+ <Unit filename="src\net\inventoryhandler.h" />
+ <Unit filename="src\net\logindata.h" />
+ <Unit filename="src\net\loginhandler.h" />
+ <Unit filename="src\net\manaserv\adminhandler.cpp" />
+ <Unit filename="src\net\manaserv\adminhandler.h" />
+ <Unit filename="src\net\manaserv\beinghandler.cpp" />
+ <Unit filename="src\net\manaserv\beinghandler.h" />
+ <Unit filename="src\net\manaserv\buysellhandler.cpp" />
+ <Unit filename="src\net\manaserv\buysellhandler.h" />
+ <Unit filename="src\net\manaserv\charhandler.cpp" />
+ <Unit filename="src\net\manaserv\charhandler.h" />
+ <Unit filename="src\net\manaserv\chathandler.cpp" />
+ <Unit filename="src\net\manaserv\chathandler.h" />
+ <Unit filename="src\net\manaserv\connection.cpp" />
+ <Unit filename="src\net\manaserv\connection.h" />
+ <Unit filename="src\net\manaserv\defines.h" />
+ <Unit filename="src\net\manaserv\effecthandler.cpp" />
+ <Unit filename="src\net\manaserv\effecthandler.h" />
+ <Unit filename="src\net\manaserv\gamehandler.cpp" />
+ <Unit filename="src\net\manaserv\gamehandler.h" />
+ <Unit filename="src\net\manaserv\generalhandler.cpp" />
+ <Unit filename="src\net\manaserv\generalhandler.h" />
+ <Unit filename="src\net\manaserv\guildhandler.cpp" />
+ <Unit filename="src\net\manaserv\guildhandler.h" />
+ <Unit filename="src\net\manaserv\internal.cpp" />
+ <Unit filename="src\net\manaserv\internal.h" />
+ <Unit filename="src\net\manaserv\inventoryhandler.cpp" />
+ <Unit filename="src\net\manaserv\inventoryhandler.h" />
+ <Unit filename="src\net\manaserv\itemhandler.cpp" />
+ <Unit filename="src\net\manaserv\itemhandler.h" />
+ <Unit filename="src\net\manaserv\loginhandler.cpp" />
+ <Unit filename="src\net\manaserv\loginhandler.h" />
+ <Unit filename="src\net\manaserv\messagehandler.cpp" />
+ <Unit filename="src\net\manaserv\messagehandler.h" />
+ <Unit filename="src\net\manaserv\messagein.cpp" />
+ <Unit filename="src\net\manaserv\messagein.h" />
+ <Unit filename="src\net\manaserv\messageout.cpp" />
+ <Unit filename="src\net\manaserv\messageout.h" />
+ <Unit filename="src\net\manaserv\network.cpp" />
+ <Unit filename="src\net\manaserv\network.h" />
+ <Unit filename="src\net\manaserv\npchandler.cpp" />
+ <Unit filename="src\net\manaserv\npchandler.h" />
+ <Unit filename="src\net\manaserv\partyhandler.cpp" />
+ <Unit filename="src\net\manaserv\partyhandler.h" />
+ <Unit filename="src\net\manaserv\playerhandler.cpp" />
+ <Unit filename="src\net\manaserv\playerhandler.h" />
+ <Unit filename="src\net\manaserv\protocol.h" />
+ <Unit filename="src\net\manaserv\specialhandler.cpp" />
+ <Unit filename="src\net\manaserv\specialhandler.h" />
+ <Unit filename="src\net\manaserv\stats.cpp" />
+ <Unit filename="src\net\manaserv\stats.h" />
+ <Unit filename="src\net\manaserv\tradehandler.cpp" />
+ <Unit filename="src\net\manaserv\tradehandler.h" />
+ <Unit filename="src\net\messagehandler.h" />
+ <Unit filename="src\net\messagein.cpp" />
+ <Unit filename="src\net\messagein.h" />
+ <Unit filename="src\net\messageout.cpp" />
+ <Unit filename="src\net\messageout.h" />
+ <Unit filename="src\net\net.cpp" />
+ <Unit filename="src\net\net.h" />
+ <Unit filename="src\net\npchandler.h" />
+ <Unit filename="src\net\packetcounters.cpp" />
+ <Unit filename="src\net\packetcounters.h" />
+ <Unit filename="src\net\partyhandler.h" />
+ <Unit filename="src\net\playerhandler.h" />
+ <Unit filename="src\net\serverinfo.h" />
+ <Unit filename="src\net\specialhandler.h" />
+ <Unit filename="src\net\tmwa\adminhandler.cpp" />
+ <Unit filename="src\net\tmwa\adminhandler.h" />
+ <Unit filename="src\net\tmwa\beinghandler.cpp" />
+ <Unit filename="src\net\tmwa\beinghandler.h" />
+ <Unit filename="src\net\tmwa\buysellhandler.cpp" />
+ <Unit filename="src\net\tmwa\buysellhandler.h" />
+ <Unit filename="src\net\tmwa\charserverhandler.cpp" />
+ <Unit filename="src\net\tmwa\charserverhandler.h" />
+ <Unit filename="src\net\tmwa\chathandler.cpp" />
+ <Unit filename="src\net\tmwa\chathandler.h" />
+ <Unit filename="src\net\tmwa\gamehandler.cpp" />
+ <Unit filename="src\net\tmwa\gamehandler.h" />
+ <Unit filename="src\net\tmwa\generalhandler.cpp" />
+ <Unit filename="src\net\tmwa\generalhandler.h" />
+ <Unit filename="src\net\tmwa\gui\guildtab.cpp" />
+ <Unit filename="src\net\tmwa\gui\guildtab.h" />
+ <Unit filename="src\net\tmwa\gui\partytab.cpp" />
+ <Unit filename="src\net\tmwa\gui\partytab.h" />
+ <Unit filename="src\net\tmwa\guildhandler.cpp" />
+ <Unit filename="src\net\tmwa\guildhandler.h" />
+ <Unit filename="src\net\tmwa\inventoryhandler.cpp" />
+ <Unit filename="src\net\tmwa\inventoryhandler.h" />
+ <Unit filename="src\net\tmwa\itemhandler.cpp" />
+ <Unit filename="src\net\tmwa\itemhandler.h" />
+ <Unit filename="src\net\tmwa\loginhandler.cpp" />
+ <Unit filename="src\net\tmwa\loginhandler.h" />
+ <Unit filename="src\net\tmwa\messagehandler.cpp" />
+ <Unit filename="src\net\tmwa\messagehandler.h" />
+ <Unit filename="src\net\tmwa\messagein.cpp" />
+ <Unit filename="src\net\tmwa\messagein.h" />
+ <Unit filename="src\net\tmwa\messageout.cpp" />
+ <Unit filename="src\net\tmwa\messageout.h" />
+ <Unit filename="src\net\tmwa\network.cpp" />
+ <Unit filename="src\net\tmwa\network.h" />
+ <Unit filename="src\net\tmwa\npchandler.cpp" />
+ <Unit filename="src\net\tmwa\npchandler.h" />
+ <Unit filename="src\net\tmwa\partyhandler.cpp" />
+ <Unit filename="src\net\tmwa\partyhandler.h" />
+ <Unit filename="src\net\tmwa\playerhandler.cpp" />
+ <Unit filename="src\net\tmwa\playerhandler.h" />
+ <Unit filename="src\net\tmwa\protocol.h" />
+ <Unit filename="src\net\tmwa\specialhandler.cpp" />
+ <Unit filename="src\net\tmwa\specialhandler.h" />
+ <Unit filename="src\net\tmwa\token.h" />
+ <Unit filename="src\net\tmwa\tradehandler.cpp" />
+ <Unit filename="src\net\tmwa\tradehandler.h" />
+ <Unit filename="src\net\tradehandler.h" />
+ <Unit filename="src\net\worldinfo.h" />
+ <Unit filename="src\openglgraphics.cpp" />
+ <Unit filename="src\openglgraphics.h" />
+ <Unit filename="src\particle.cpp" />
+ <Unit filename="src\particle.h" />
+ <Unit filename="src\particlecontainer.cpp" />
+ <Unit filename="src\particlecontainer.h" />
+ <Unit filename="src\particleemitter.cpp" />
+ <Unit filename="src\particleemitter.h" />
+ <Unit filename="src\particleemitterprop.h" />
+ <Unit filename="src\party.cpp" />
+ <Unit filename="src\party.h" />
+ <Unit filename="src\playerinfo.cpp" />
+ <Unit filename="src\playerinfo.h" />
+ <Unit filename="src\playerrelations.cpp" />
+ <Unit filename="src\playerrelations.h" />
+ <Unit filename="src\position.cpp" />
+ <Unit filename="src\position.h" />
+ <Unit filename="src\properties.h" />
+ <Unit filename="src\resources\action.cpp" />
+ <Unit filename="src\resources\action.h" />
+ <Unit filename="src\resources\ambientlayer.cpp" />
+ <Unit filename="src\resources\ambientlayer.h" />
+ <Unit filename="src\resources\ambientoverlay.cpp" />
+ <Unit filename="src\resources\ambientoverlay.h" />
+ <Unit filename="src\resources\animation.cpp" />
+ <Unit filename="src\resources\animation.h" />
+ <Unit filename="src\resources\beinginfo.cpp" />
+ <Unit filename="src\resources\beinginfo.h" />
+ <Unit filename="src\resources\colordb.cpp" />
+ <Unit filename="src\resources\colordb.h" />
+ <Unit filename="src\resources\dye.cpp" />
+ <Unit filename="src\resources\dye.h" />
+ <Unit filename="src\resources\emotedb.cpp" />
+ <Unit filename="src\resources\emotedb.h" />
+ <Unit filename="src\resources\image.cpp" />
+ <Unit filename="src\resources\image.h" />
+ <Unit filename="src\resources\imageloader.cpp" />
+ <Unit filename="src\resources\imageloader.h" />
+ <Unit filename="src\resources\imageset.cpp" />
+ <Unit filename="src\resources\imageset.h" />
+ <Unit filename="src\resources\imagewriter.cpp" />
+ <Unit filename="src\resources\imagewriter.h" />
+ <Unit filename="src\resources\itemdb.cpp" />
+ <Unit filename="src\resources\itemdb.h" />
+ <Unit filename="src\resources\iteminfo.cpp" />
+ <Unit filename="src\resources\iteminfo.h" />
+ <Unit filename="src\resources\mapreader.cpp" />
+ <Unit filename="src\resources\mapreader.h" />
+ <Unit filename="src\resources\monsterdb.cpp" />
+ <Unit filename="src\resources\monsterdb.h" />
+ <Unit filename="src\resources\music.cpp" />
+ <Unit filename="src\resources\music.h" />
+ <Unit filename="src\resources\npcdb.cpp" />
+ <Unit filename="src\resources\npcdb.h" />
+ <Unit filename="src\resources\resource.cpp" />
+ <Unit filename="src\resources\resource.h" />
+ <Unit filename="src\resources\resourcemanager.cpp" />
+ <Unit filename="src\resources\resourcemanager.h" />
+ <Unit filename="src\resources\soundeffect.cpp" />
+ <Unit filename="src\resources\soundeffect.h" />
+ <Unit filename="src\resources\specialdb.cpp" />
+ <Unit filename="src\resources\specialdb.h" />
+ <Unit filename="src\resources\spritedef.cpp" />
+ <Unit filename="src\resources\spritedef.h" />
+ <Unit filename="src\resources\wallpaper.cpp" />
+ <Unit filename="src\resources\wallpaper.h" />
+ <Unit filename="src\rotationalparticle.cpp" />
+ <Unit filename="src\rotationalparticle.h" />
+ <Unit filename="src\shopitem.cpp" />
+ <Unit filename="src\shopitem.h" />
+ <Unit filename="src\simpleanimation.cpp" />
+ <Unit filename="src\simpleanimation.h" />
+ <Unit filename="src\sound.cpp" />
+ <Unit filename="src\sound.h" />
+ <Unit filename="src\spellmanager.cpp" />
+ <Unit filename="src\spellmanager.h" />
+ <Unit filename="src\spellshortcut.cpp" />
+ <Unit filename="src\spellshortcut.h" />
+ <Unit filename="src\sprite.h" />
+ <Unit filename="src\statuseffect.cpp" />
+ <Unit filename="src\statuseffect.h" />
+ <Unit filename="src\text.cpp" />
+ <Unit filename="src\text.h" />
+ <Unit filename="src\textcommand.cpp" />
+ <Unit filename="src\textcommand.h" />
+ <Unit filename="src\textmanager.cpp" />
+ <Unit filename="src\textmanager.h" />
+ <Unit filename="src\textparticle.cpp" />
+ <Unit filename="src\textparticle.h" />
+ <Unit filename="src\textrenderer.h" />
+ <Unit filename="src\tileset.h" />
+ <Unit filename="src\units.cpp" />
+ <Unit filename="src\units.h" />
+ <Unit filename="src\utils\base64.cpp" />
+ <Unit filename="src\utils\base64.h" />
+ <Unit filename="src\utils\copynpaste.cpp" />
+ <Unit filename="src\utils\copynpaste.h" />
+ <Unit filename="src\utils\dtor.h" />
+ <Unit filename="src\utils\gettext.h" />
+ <Unit filename="src\utils\mathutils.h" />
+ <Unit filename="src\utils\mkdir.cpp" />
+ <Unit filename="src\utils\mkdir.h" />
+ <Unit filename="src\utils\mutex.h" />
+ <Unit filename="src\utils\sha256.cpp" />
+ <Unit filename="src\utils\sha256.h" />
+ <Unit filename="src\utils\specialfolder.cpp" />
+ <Unit filename="src\utils\specialfolder.h" />
+ <Unit filename="src\utils\stringutils.cpp" />
+ <Unit filename="src\utils\stringutils.h" />
+ <Unit filename="src\utils\xml.cpp" />
+ <Unit filename="src\utils\xml.h" />
+ <Unit filename="src\variabledata.h" />
+ <Unit filename="src\vector.cpp" />
+ <Unit filename="src\vector.h" />
+ <Unit filename="src\winver.h" />
+ <Unit filename="src\winver.h.in" />
+ <Extensions>
+ <code_completion />
+ <envvars />
+ <debugger />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/mana.config b/mana.config
new file mode 100644
index 000000000..f97325b78
--- /dev/null
+++ b/mana.config
@@ -0,0 +1 @@
+#include "../config.h"
diff --git a/mana.creator b/mana.creator
new file mode 100644
index 000000000..e94cbbd30
--- /dev/null
+++ b/mana.creator
@@ -0,0 +1 @@
+[General]
diff --git a/mana.files b/mana.files
new file mode 100644
index 000000000..4bd0ddcba
--- /dev/null
+++ b/mana.files
@@ -0,0 +1,754 @@
+./CMakeCache.txt
+./CMakeFiles/CMakeRuleHashes.txt
+./CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp
+./CMakeFiles/TargetDirectories.txt
+./CMakeLists.txt
+./config.h
+./data/CMakeLists.txt
+./data/fonts/CMakeLists.txt
+./data/fonts/Makefile.am
+./data/graphics/CMakeLists.txt
+./data/graphics/gui/CMakeLists.txt
+./data/graphics/gui/colors.xml
+./data/graphics/gui/Makefile.am
+./data/graphics/gui/speechbubble.xml
+./data/graphics/gui/window.xml
+./data/graphics/images/CMakeLists.txt
+./data/graphics/images/Makefile.am
+./data/graphics/Makefile.am
+./data/graphics/sprites/CMakeLists.txt
+./data/graphics/sprites/error.xml
+./data/graphics/sprites/Makefile.am
+./data/help/about.txt
+./data/help/changes.txt
+./data/help/CMakeLists.txt
+./data/help/commands.txt
+./data/help/header.txt
+./data/help/index.txt
+./data/help/Makefile.am
+./data/help/skills.txt
+./data/help/support.txt
+./data/help/team.txt
+./data/help/windows.txt
+./data/icons/CMakeLists.txt
+./data/icons/Makefile.am
+./data/Makefile.am
+./data/themes/classic/CMakeLists.txt
+./data/themes/classic/colors.xml
+./data/themes/classic/Makefile.am
+./data/themes/classic/speechbubble.xml
+./data/themes/classic/window.xml
+./data/themes/CMakeLists.txt
+./data/themes/enchilado/CMakeLists.txt
+./data/themes/enchilado/colors.xml
+./data/themes/enchilado/Makefile.am
+./data/themes/enchilado/window.xml
+./data/themes/Makefile.am
+./data/themes/redandblack/CMakeLists.txt
+./data/themes/redandblack/colors.xml
+./data/themes/redandblack/Makefile.am
+./data/themes/redandblack/speechbubble.xml
+./data/themes/redandblack/window.xml
+./data/themes/wood/CMakeLists.txt
+./data/themes/wood/colors.xml
+./data/themes/wood/Makefile.am
+./data/themes/wood/speechbubble.xml
+./data/themes/wood/window.xml
+./docs/clientupdates.txt
+./docs/example.mana
+./docs/FAQ.txt
+./docs/HACKING.txt
+./docs/items.txt
+./docs/Makefile.am
+./docs/packages.txt
+./docs/progression.txt
+./docs/sounddev.txt
+./gprof.txt
+./install_manifest.txt
+./Makefile.am
+./my/bugs.txt
+./my/install.txt
+./my/mana_pack/data/branding.xml
+./my/mana_pack/data/CMakeLists.txt
+./my/mana_pack/data/fonts/CMakeLists.txt
+./my/mana_pack/data/fonts/Makefile.am
+./my/mana_pack/data/graphics/CMakeLists.txt
+./my/mana_pack/data/graphics/gui/CMakeLists.txt
+./my/mana_pack/data/graphics/gui/gui.xml
+./my/mana_pack/data/graphics/gui/Makefile.am
+./my/mana_pack/data/graphics/gui/speechbubble.xml
+./my/mana_pack/data/graphics/images/CMakeLists.txt
+./my/mana_pack/data/graphics/images/Makefile.am
+./my/mana_pack/data/graphics/Makefile.am
+./my/mana_pack/data/help/about.txt
+./my/mana_pack/data/help/changes.txt
+./my/mana_pack/data/help/CMakeLists.txt
+./my/mana_pack/data/help/commands.txt
+./my/mana_pack/data/help/header.txt
+./my/mana_pack/data/help/index.txt
+./my/mana_pack/data/help/Makefile.am
+./my/mana_pack/data/help/skills.txt
+./my/mana_pack/data/help/support.txt
+./my/mana_pack/data/help/team.txt
+./my/mana_pack/data/help/windows.txt
+./my/mana_pack/data/icons/CMakeLists.txt
+./my/mana_pack/data/icons/Makefile.am
+./my/mana_pack/data/Makefile.am
+./my/mana_pack/docs/Makefile.am
+./my/mana_pack/Makefile.am
+./my/mana_pack_themes/data/Makefile.am
+./my/mana_pack_themes/data/themes/classic/graphics/gui/gui.xml
+./my/mana_pack_themes/data/themes/classic/graphics/gui/Makefile.am
+./my/mana_pack_themes/data/themes/classic/graphics/gui/speechbubble.xml
+./my/mana_pack_themes/data/themes/classic/graphics/images/Makefile.am
+./my/mana_pack_themes/data/themes/classic/graphics/Makefile.am
+./my/mana_pack_themes/data/themes/classic/Makefile.am
+./my/mana_pack_themes/data/themes/Makefile.am
+./my/mana_pack_themes/data/themes/redandblack/graphics/gui/gui.xml
+./my/mana_pack_themes/data/themes/redandblack/graphics/gui/Makefile.am
+./my/mana_pack_themes/data/themes/redandblack/graphics/gui/speechbubble.xml
+./my/mana_pack_themes/data/themes/redandblack/graphics/images/Makefile.am
+./my/mana_pack_themes/data/themes/redandblack/graphics/Makefile.am
+./my/mana_pack_themes/data/themes/redandblack/Makefile.am
+./my/mana_pack_themes/data/themes/wood/graphics/gui/gui.xml
+./my/mana_pack_themes/data/themes/wood/graphics/gui/Makefile.am
+./my/mana_pack_themes/data/themes/wood/graphics/gui/speechbubble.xml
+./my/mana_pack_themes/data/themes/wood/graphics/images/Makefile.am
+./my/mana_pack_themes/data/themes/wood/graphics/Makefile.am
+./my/mana_pack_themes/data/themes/wood/Makefile.am
+./my/plans.txt
+./my/porting.txt
+./my/synaptic.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/graphics/gui/gui.xml
+./my/tmp/debian/tmp/usr/share/games/tmw/data/graphics/gui/speechbubble.xml
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/about.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/changes.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/commands.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/header.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/index.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/skills.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/support.txt
+./my/tmp/debian/tmp/usr/share/games/tmw/data/help/team.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/graphics/gui/gui.xml
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/graphics/gui/speechbubble.xml
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/about.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/changes.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/commands.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/header.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/index.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/skills.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/support.txt
+./my/tmp/debian/tmw-data/usr/share/games/tmw/data/help/team.txt
+./my/tmp/debian/tmw/usr/share/doc/tmw/FAQ.txt
+./my/trade.txt
+./my/win_src_update/data/graphics/gui/gui.xml
+./my/win_src_update/data/graphics/gui/speechbubble.xml
+./my/win_src_update/data/help/about.txt
+./my/win_src_update/data/help/changes.txt
+./my/win_src_update/data/help/commands.txt
+./my/win_src_update/data/help/header.txt
+./my/win_src_update/data/help/index.txt
+./my/win_src_update/data/help/skills.txt
+./my/win_src_update/data/help/support.txt
+./my/win_src_update/data/help/team.txt
+./my/win_src_update/data/help/windows.txt
+./my/win_src_update/docs/clientupdates.txt
+./my/win_src_update/docs/FAQ.txt
+./my/win_src_update/docs/HACKING.txt
+./my/win_src_update/docs/items.txt
+./my/win_src_update/docs/Makefile.am
+./my/win_src_update/docs/packages.txt
+./my/win_src_update/docs/progression.txt
+./my/win_src_update/docs/sounddev.txt
+./my/win_src_update/packaging/windows/readme.txt
+./my/win_src_update/po/CMakeLists.txt
+./my/win_src_update/tools/dyecmd/src/dyecmd.cpp
+./my/win_src_update/tools/dyecmd/src/dye.cpp
+./my/win_src_update/tools/dyecmd/src/dye.h
+./my/win_src_update/tools/dyecmd/src/imagewriter.cpp
+./my/win_src_update/tools/dyecmd/src/imagewriter.h
+./my/win_src_update/tools/tmxcopy/base64.cpp
+./my/win_src_update/tools/tmxcopy/base64.h
+./my/win_src_update/tools/tmxcopy/map.cpp
+./my/win_src_update/tools/tmxcopy/readme.txt
+./my/win_src_update/tools/tmxcopy/tmxcollide.cpp
+./my/win_src_update/tools/tmxcopy/tmxcopy.cpp
+./my/win_src_update/tools/tmxcopy/tmx_random_fill.cpp
+./my/win_src_update/tools/tmxcopy/tostring.h
+./my/win_src_update/tools/tmxcopy/xmlutils.cpp
+./my/win_src_update/tools/tmxcopy/xmlutils.h
+./my/win_src_update/tools/tmxcopy/zlibutils.cpp
+./my/win_src_update/tools/tmxcopy/zlibutils.h
+./packaging/windows/readme.txt
+./po/1/CMakeLists.txt
+./po/CMakeLists.txt
+./src/actor.cpp
+./src/actor.h
+./src/actorsprite.cpp
+./src/actorsprite.h
+./src/actorspritelistener.h
+./src/actorspritemanager.cpp
+./src/actorspritemanager.h
+./src/animatedsprite.cpp
+./src/animatedsprite.h
+./src/animationparticle.cpp
+./src/animationparticle.h
+./src/avatar.cpp
+./src/avatar.h
+./src/being.cpp
+./src/being.h
+./src/channel.cpp
+./src/channel.h
+./src/channelmanager.cpp
+./src/channelmanager.h
+./src/chatlog.cpp
+./src/chatlog.h
+./src/client.cpp
+./src/client.h
+./src/CMakeFiles/mana.dir/link.txt
+./src/CMakeFiles/manaplus.dir/link.txt
+./src/CMakeLists.txt
+./src/commandhandler.cpp
+./src/commandhandler.h
+./src/compoundsprite.cpp
+./src/compoundsprite.h
+./src/configlistener.h
+./src/configuration.cpp
+./src/configuration.h
+./src/dropshortcut.cpp
+./src/dropshortcut.h
+./src/effectmanager.cpp
+./src/effectmanager.h
+./src/emoteshortcut.cpp
+./src/emoteshortcut.h
+./src/equipment.h
+./src/event.cpp
+./src/event.h
+./src/eventmanager.cpp
+./src/eventmanager.h
+./src/flooritem.cpp
+./src/flooritem.h
+./src/game.cpp
+./src/game.h
+./src/graphics.cpp
+./src/graphics.h
+./src/gui/beingpopup.cpp
+./src/gui/beingpopup.h
+./src/gui/botcheckerwindow.cpp
+./src/gui/botcheckerwindow.h
+./src/gui/buy.cpp
+./src/gui/buy.h
+./src/gui/buysell.cpp
+./src/gui/buysell.h
+./src/guichanfwd.h
+./src/gui/changeemaildialog.cpp
+./src/gui/changeemaildialog.h
+./src/gui/changepassworddialog.cpp
+./src/gui/changepassworddialog.h
+./src/gui/charcreatedialog.cpp
+./src/gui/charcreatedialog.h
+./src/gui/charselectdialog.cpp
+./src/gui/charselectdialog.h
+./src/gui/chat.cpp
+./src/gui/chat.h
+./src/gui/confirmdialog.cpp
+./src/gui/confirmdialog.h
+./src/gui/connectiondialog.cpp
+./src/gui/connectiondialog.h
+./src/gui/debugwindow.cpp
+./src/gui/debugwindow.h
+./src/gui/editdialog.cpp
+./src/gui/editdialog.h
+./src/gui/emotepopup.cpp
+./src/gui/emotepopup.h
+./src/gui/equipmentwindow.cpp
+./src/gui/equipmentwindow.h
+./src/gui/focushandler.cpp
+./src/gui/focushandler.h
+./src/gui/gui.cpp
+./src/gui/gui.h
+./src/gui/help.cpp
+./src/gui/help.h
+./src/gui/inventorywindow.cpp
+./src/gui/inventorywindow.h
+./src/gui/itemamount.cpp
+./src/gui/itemamount.h
+./src/gui/itempopup.cpp
+./src/gui/itempopup.h
+./src/gui/killstats.cpp
+./src/gui/killstats.h
+./src/guild.cpp
+./src/guild.h
+./src/gui/login.cpp
+./src/gui/login.h
+./src/gui/minimap.cpp
+./src/gui/minimap.h
+./src/gui/ministatus.cpp
+./src/gui/ministatus.h
+./src/gui/npcdialog.cpp
+./src/gui/npcdialog.h
+./src/gui/npcpostdialog.cpp
+./src/gui/npcpostdialog.h
+./src/gui/okdialog.cpp
+./src/gui/okdialog.h
+./src/gui/outfitwindow.cpp
+./src/gui/outfitwindow.h
+./src/gui/palette.cpp
+./src/gui/palette.h
+./src/gui/popupmenu.cpp
+./src/gui/popupmenu.h
+./src/gui/quitdialog.cpp
+./src/gui/quitdialog.h
+./src/gui/register.cpp
+./src/gui/register.h
+./src/gui/sdlinput.cpp
+./src/gui/sdlinput.h
+./src/gui/sell.cpp
+./src/gui/sell.h
+./src/gui/serverdialog.cpp
+./src/gui/serverdialog.h
+./src/gui/setup_audio.cpp
+./src/gui/setup_audio.h
+./src/gui/setup_chat.cpp
+./src/gui/setup_chat.h
+./src/gui/setup_colors.cpp
+./src/gui/setup_colors.h
+./src/gui/setup.cpp
+./src/gui/setup.h
+./src/gui/setup_joystick.cpp
+./src/gui/setup_joystick.h
+./src/gui/setup_keyboard.cpp
+./src/gui/setup_keyboard.h
+./src/gui/setup_other.cpp
+./src/gui/setup_other.h
+./src/gui/setup_players.cpp
+./src/gui/setup_players.h
+./src/gui/setup_theme.cpp
+./src/gui/setup_theme.h
+./src/gui/setup_video.cpp
+./src/gui/setup_video.h
+./src/gui/shopwindow.cpp
+./src/gui/shopwindow.h
+./src/gui/shortcutwindow.cpp
+./src/gui/shortcutwindow.h
+./src/gui/skilldialog.cpp
+./src/gui/skilldialog.h
+./src/gui/socialwindow.cpp
+./src/gui/socialwindow.h
+./src/gui/specialswindow.cpp
+./src/gui/specialswindow.h
+./src/gui/speechbubble.cpp
+./src/gui/speechbubble.h
+./src/gui/spellpopup.cpp
+./src/gui/spellpopup.h
+./src/gui/statuspopup.cpp
+./src/gui/statuspopup.h
+./src/gui/statuswindow.cpp
+./src/gui/statuswindow.h
+./src/gui/textcommandeditor.cpp
+./src/gui/textcommandeditor.h
+./src/gui/textdialog.cpp
+./src/gui/textdialog.h
+./src/gui/textpopup.cpp
+./src/gui/textpopup.h
+./src/gui/theme.cpp
+./src/gui/theme.h
+./src/gui/trade.cpp
+./src/gui/trade.h
+./src/gui/truetypefont.cpp
+./src/gui/truetypefont.h
+./src/gui/unregisterdialog.cpp
+./src/gui/unregisterdialog.h
+./src/gui/updatewindow.cpp
+./src/gui/updatewindow.h
+./src/gui/userpalette.cpp
+./src/gui/userpalette.h
+./src/gui/viewport.cpp
+./src/gui/viewport.h
+./src/gui/whoisonline.cpp
+./src/gui/whoisonline.h
+./src/gui/widgets/avatarlistbox.cpp
+./src/gui/widgets/avatarlistbox.h
+./src/gui/widgets/browserbox.cpp
+./src/gui/widgets/browserbox.h
+./src/gui/widgets/button.cpp
+./src/gui/widgets/button.h
+./src/gui/widgets/channeltab.cpp
+./src/gui/widgets/channeltab.h
+./src/gui/widgets/chattab.cpp
+./src/gui/widgets/chattab.h
+./src/gui/widgets/checkbox.cpp
+./src/gui/widgets/checkbox.h
+./src/gui/widgets/container.cpp
+./src/gui/widgets/container.h
+./src/gui/widgets/desktop.cpp
+./src/gui/widgets/desktop.h
+./src/gui/widgets/dropdown.cpp
+./src/gui/widgets/dropdown.h
+./src/gui/widgets/dropshortcutcontainer.cpp
+./src/gui/widgets/dropshortcutcontainer.h
+./src/gui/widgets/emoteshortcutcontainer.cpp
+./src/gui/widgets/emoteshortcutcontainer.h
+./src/gui/widgets/flowcontainer.cpp
+./src/gui/widgets/flowcontainer.h
+./src/gui/widgets/icon.cpp
+./src/gui/widgets/icon.h
+./src/gui/widgets/inttextfield.cpp
+./src/gui/widgets/inttextfield.h
+./src/gui/widgets/itemcontainer.cpp
+./src/gui/widgets/itemcontainer.h
+./src/gui/widgets/itemlinkhandler.cpp
+./src/gui/widgets/itemlinkhandler.h
+./src/gui/widgets/itemshortcutcontainer.cpp
+./src/gui/widgets/itemshortcutcontainer.h
+./src/gui/widgets/label.cpp
+./src/gui/widgets/label.h
+./src/gui/widgets/layout.cpp
+./src/gui/widgets/layout.h
+./src/gui/widgets/layouthelper.cpp
+./src/gui/widgets/layouthelper.h
+./src/gui/widgets/linkhandler.h
+./src/gui/widgets/listbox.cpp
+./src/gui/widgets/listbox.h
+./src/gui/widgets/passwordfield.cpp
+./src/gui/widgets/passwordfield.h
+./src/gui/widgets/playerbox.cpp
+./src/gui/widgets/playerbox.h
+./src/gui/widgets/popup.cpp
+./src/gui/widgets/popup.h
+./src/gui/widgets/progressbar.cpp
+./src/gui/widgets/progressbar.h
+./src/gui/widgets/progressindicator.cpp
+./src/gui/widgets/progressindicator.h
+./src/gui/widgets/radiobutton.cpp
+./src/gui/widgets/radiobutton.h
+./src/gui/widgets/resizegrip.cpp
+./src/gui/widgets/resizegrip.h
+./src/gui/widgets/scrollarea.cpp
+./src/gui/widgets/scrollarea.h
+./src/gui/widgets/setuptab.cpp
+./src/gui/widgets/setuptab.h
+./src/gui/widgets/shopitems.cpp
+./src/gui/widgets/shopitems.h
+./src/gui/widgets/shoplistbox.cpp
+./src/gui/widgets/shoplistbox.h
+./src/gui/widgets/shortcutcontainer.cpp
+./src/gui/widgets/shortcutcontainer.h
+./src/gui/widgets/slider.cpp
+./src/gui/widgets/slider.h
+./src/gui/widgets/spellshortcutcontainer.cpp
+./src/gui/widgets/spellshortcutcontainer.h
+./src/gui/widgets/tabbedarea.cpp
+./src/gui/widgets/tabbedarea.h
+./src/gui/widgets/tab.cpp
+./src/gui/widgets/tab.h
+./src/gui/widgets/table.cpp
+./src/gui/widgets/table.h
+./src/gui/widgets/tablemodel.cpp
+./src/gui/widgets/tablemodel.h
+./src/gui/widgets/textbox.cpp
+./src/gui/widgets/textbox.h
+./src/gui/widgets/textfield.cpp
+./src/gui/widgets/textfield.h
+./src/gui/widgets/textpreview.cpp
+./src/gui/widgets/textpreview.h
+./src/gui/widgets/tradetab.cpp
+./src/gui/widgets/tradetab.h
+./src/gui/widgets/vertcontainer.cpp
+./src/gui/widgets/vertcontainer.h
+./src/gui/widgets/whispertab.cpp
+./src/gui/widgets/whispertab.h
+./src/gui/widgets/windowcontainer.cpp
+./src/gui/widgets/windowcontainer.h
+./src/gui/widgets/window.cpp
+./src/gui/widgets/window.h
+./src/gui/windowmenu.cpp
+./src/gui/windowmenu.h
+./src/gui/worldselectdialog.cpp
+./src/gui/worldselectdialog.h
+./src/imageparticle.cpp
+./src/imageparticle.h
+./src/imagesprite.cpp
+./src/imagesprite.h
+./src/inventory.cpp
+./src/inventory.h
+./src/item.cpp
+./src/item.h
+./src/itemshortcut.cpp
+./src/itemshortcut.h
+./src/joystick.cpp
+./src/joystick.h
+./src/keyboardconfig.cpp
+./src/keyboardconfig.h
+./src/listener.cpp
+./src/listener.h
+./src/localplayer.cpp
+./src/localplayer.h
+./src/log.cpp
+./src/log.h
+./src/main.cpp
+./src/main.h
+./src/Makefile.am
+./src/map.cpp
+./src/map.h
+./src/net/adminhandler.h
+./src/net/beinghandler.h
+./src/net/buysellhandler.h
+./src/net/charhandler.cpp
+./src/net/charhandler.h
+./src/net/chathandler.h
+./src/net/download.cpp
+./src/net/download.h
+./src/net/gamehandler.h
+./src/net/generalhandler.h
+./src/net/guildhandler.h
+./src/net/inventoryhandler.h
+./src/net/logindata.h
+./src/net/loginhandler.h
+./src/net/manaserv/adminhandler.cpp
+./src/net/manaserv/adminhandler.h
+./src/net/manaserv/beinghandler.cpp
+./src/net/manaserv/beinghandler.h
+./src/net/manaserv/buysellhandler.cpp
+./src/net/manaserv/buysellhandler.h
+./src/net/manaserv/charhandler.cpp
+./src/net/manaserv/charhandler.h
+./src/net/manaserv/chathandler.cpp
+./src/net/manaserv/chathandler.h
+./src/net/manaserv/connection.cpp
+./src/net/manaserv/connection.h
+./src/net/manaserv/defines.h
+./src/net/manaserv/effecthandler.cpp
+./src/net/manaserv/effecthandler.h
+./src/net/manaserv/gamehandler.cpp
+./src/net/manaserv/gamehandler.h
+./src/net/manaserv/generalhandler.cpp
+./src/net/manaserv/generalhandler.h
+./src/net/manaserv/guildhandler.cpp
+./src/net/manaserv/guildhandler.h
+./src/net/manaserv/internal.cpp
+./src/net/manaserv/internal.h
+./src/net/manaserv/inventoryhandler.cpp
+./src/net/manaserv/inventoryhandler.h
+./src/net/manaserv/itemhandler.cpp
+./src/net/manaserv/itemhandler.h
+./src/net/manaserv/loginhandler.cpp
+./src/net/manaserv/loginhandler.h
+./src/net/manaserv/messagehandler.cpp
+./src/net/manaserv/messagehandler.h
+./src/net/manaserv/messagein.cpp
+./src/net/manaserv/messagein.h
+./src/net/manaserv/messageout.cpp
+./src/net/manaserv/messageout.h
+./src/net/manaserv/network.cpp
+./src/net/manaserv/network.h
+./src/net/manaserv/npchandler.cpp
+./src/net/manaserv/npchandler.h
+./src/net/manaserv/partyhandler.cpp
+./src/net/manaserv/partyhandler.h
+./src/net/manaserv/playerhandler.cpp
+./src/net/manaserv/playerhandler.h
+./src/net/manaserv/protocol.h
+./src/net/manaserv/specialhandler.cpp
+./src/net/manaserv/specialhandler.h
+./src/net/manaserv/stats.cpp
+./src/net/manaserv/stats.h
+./src/net/manaserv/tradehandler.cpp
+./src/net/manaserv/tradehandler.h
+./src/net/messagehandler.h
+./src/net/messagein.cpp
+./src/net/messagein.h
+./src/net/messageout.cpp
+./src/net/messageout.h
+./src/net/net.cpp
+./src/net/net.h
+./src/net/npchandler.h
+./src/net/packetcounters.cpp
+./src/net/packetcounters.h
+./src/net/partyhandler.h
+./src/net/playerhandler.h
+./src/net/serverinfo.h
+./src/net/specialhandler.h
+./src/net/tmwa/adminhandler.cpp
+./src/net/tmwa/adminhandler.h
+./src/net/tmwa/beinghandler.cpp
+./src/net/tmwa/beinghandler.h
+./src/net/tmwa/buysellhandler.cpp
+./src/net/tmwa/buysellhandler.h
+./src/net/tmwa/charserverhandler.cpp
+./src/net/tmwa/charserverhandler.h
+./src/net/tmwa/chathandler.cpp
+./src/net/tmwa/chathandler.h
+./src/net/tmwa/gamehandler.cpp
+./src/net/tmwa/gamehandler.h
+./src/net/tmwa/generalhandler.cpp
+./src/net/tmwa/generalhandler.h
+./src/net/tmwa/gui/guildtab.cpp
+./src/net/tmwa/gui/guildtab.h
+./src/net/tmwa/guildhandler.cpp
+./src/net/tmwa/guildhandler.h
+./src/net/tmwa/gui/partytab.cpp
+./src/net/tmwa/gui/partytab.h
+./src/net/tmwa/inventoryhandler.cpp
+./src/net/tmwa/inventoryhandler.h
+./src/net/tmwa/itemhandler.cpp
+./src/net/tmwa/itemhandler.h
+./src/net/tmwa/loginhandler.cpp
+./src/net/tmwa/loginhandler.h
+./src/net/tmwa/messagehandler.cpp
+./src/net/tmwa/messagehandler.h
+./src/net/tmwa/messagein.cpp
+./src/net/tmwa/messagein.h
+./src/net/tmwa/messageout.cpp
+./src/net/tmwa/messageout.h
+./src/net/tmwa/network.cpp
+./src/net/tmwa/network.h
+./src/net/tmwa/npchandler.cpp
+./src/net/tmwa/npchandler.h
+./src/net/tmwa/partyhandler.cpp
+./src/net/tmwa/partyhandler.h
+./src/net/tmwa/playerhandler.cpp
+./src/net/tmwa/playerhandler.h
+./src/net/tmwa/protocol.h
+./src/net/tmwa/specialhandler.cpp
+./src/net/tmwa/specialhandler.h
+./src/net/tmwa/token.h
+./src/net/tmwa/tradehandler.cpp
+./src/net/tmwa/tradehandler.h
+./src/net/tradehandler.h
+./src/net/worldinfo.h
+./src/openglgraphics.cpp
+./src/openglgraphics.h
+./src/particlecontainer.cpp
+./src/particlecontainer.h
+./src/particle.cpp
+./src/particleemitter.cpp
+./src/particleemitter.h
+./src/particleemitterprop.h
+./src/particle.h
+./src/party.cpp
+./src/party.h
+./src/playerinfo.cpp
+./src/playerinfo.h
+./src/playerrelations.cpp
+./src/playerrelations.h
+./src/position.cpp
+./src/position.h
+./src/properties.h
+./src/resources/action.cpp
+./src/resources/action.h
+./src/resources/ambientlayer.cpp
+./src/resources/ambientlayer.h
+./src/resources/ambientoverlay.cpp
+./src/resources/ambientoverlay.h
+./src/resources/animation.cpp
+./src/resources/animation.h
+./src/resources/beinginfo.cpp
+./src/resources/beinginfo.h
+./src/resources/colordb.cpp
+./src/resources/colordb.h
+./src/resources/dye.cpp
+./src/resources/dye.h
+./src/resources/emotedb.cpp
+./src/resources/emotedb.h
+./src/resources/image.cpp
+./src/resources/image.h
+./src/resources/imageloader.cpp
+./src/resources/imageloader.h
+./src/resources/imageset.cpp
+./src/resources/imageset.h
+./src/resources/imagewriter.cpp
+./src/resources/imagewriter.h
+./src/resources/itemdb.cpp
+./src/resources/itemdb.h
+./src/resources/iteminfo.cpp
+./src/resources/iteminfo.h
+./src/resources/mapreader.cpp
+./src/resources/mapreader.h
+./src/resources/monsterdb.cpp
+./src/resources/monsterdb.h
+./src/resources/music.cpp
+./src/resources/music.h
+./src/resources/npcdb.cpp
+./src/resources/npcdb.h
+./src/resources/resource.cpp
+./src/resources/resource.h
+./src/resources/resourcemanager.cpp
+./src/resources/resourcemanager.h
+./src/resources/soundeffect.cpp
+./src/resources/soundeffect.h
+./src/resources/specialdb.cpp
+./src/resources/specialdb.h
+./src/resources/spritedef.cpp
+./src/resources/spritedef.h
+./src/resources/wallpaper.cpp
+./src/resources/wallpaper.h
+./src/rotationalparticle.cpp
+./src/rotationalparticle.h
+./src/SDLMain.h
+./src/shopitem.cpp
+./src/shopitem.h
+./src/simpleanimation.cpp
+./src/simpleanimation.h
+./src/sound.cpp
+./src/sound.h
+./src/spellmanager.cpp
+./src/spellmanager.h
+./src/spellshortcut.cpp
+./src/spellshortcut.h
+./src/sprite.h
+./src/statuseffect.cpp
+./src/statuseffect.h
+./src/textcommand.cpp
+./src/textcommand.h
+./src/text.cpp
+./src/text.h
+./src/textmanager.cpp
+./src/textmanager.h
+./src/textparticle.cpp
+./src/textparticle.h
+./src/textrenderer.h
+./src/tileset.h
+./src/units.cpp
+./src/units.h
+./src/utils/base64.cpp
+./src/utils/base64.h
+./src/utils/copynpaste.cpp
+./src/utils/copynpaste.h
+./src/utils/dtor.h
+./src/utils/gettext.h
+./src/utils/mathutils.h
+./src/utils/mkdir.cpp
+./src/utils/mkdir.h
+./src/utils/mutex.h
+./src/utils/sha256.cpp
+./src/utils/sha256.h
+./src/utils/specialfolder.cpp
+./src/utils/specialfolder.h
+./src/utils/stringutils.cpp
+./src/utils/stringutils.h
+./src/utils/xml.cpp
+./src/utils/xml.h
+./src/variabledata.h
+./src/vector.cpp
+./src/vector.h
+./src/winver.h
+./tools/dyecmd/CMakeLists.txt
+./tools/dyecmd/src/CMakeLists.txt
+./tools/dyecmd/src/dyecmd.cpp
+./tools/dyecmd/src/dye.cpp
+./tools/dyecmd/src/dye.h
+./tools/dyecmd/src/imagewriter.cpp
+./tools/dyecmd/src/imagewriter.h
+./tools/tmxcopy/base64.cpp
+./tools/tmxcopy/base64.h
+./tools/tmxcopy/map.cpp
+./tools/tmxcopy/readme.txt
+./tools/tmxcopy/tmxcollide.cpp
+./tools/tmxcopy/tmxcopy.cpp
+./tools/tmxcopy/tmx_random_fill.cpp
+./tools/tmxcopy/tostring.h
+./tools/tmxcopy/xmlutils.cpp
+./tools/tmxcopy/xmlutils.h
+./tools/tmxcopy/zlibutils.cpp
+./tools/tmxcopy/zlibutils.h
diff --git a/mana.includes b/mana.includes
new file mode 100644
index 000000000..4f1d412a8
--- /dev/null
+++ b/mana.includes
@@ -0,0 +1,4 @@
+src
+/usr/include/libxml2
+/usr/include/SDL
+libs/enet/include
diff --git a/mana.xcodeproj/garfield.mode1 b/mana.xcodeproj/garfield.mode1
new file mode 100644
index 000000000..debfe4734
--- /dev/null
+++ b/mana.xcodeproj/garfield.mode1
@@ -0,0 +1,1329 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXRunSessionModule</string>
+ <key>Name</key>
+ <string>Run Log</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ </array>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>92BC40BF0BAEE965000DAB7F</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1</string>
+ <key>MajorVersion</key>
+ <integer>31</integer>
+ <key>MinorVersion</key>
+ <integer>1</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-target-popup</string>
+ <string>action</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>buildOrClean</string>
+ <string>build-and-runOrDebug</string>
+ <string>debug</string>
+ <string>clean-target</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>get-info</string>
+ <string>toggle-editor</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>com.apple.pbx.toolbar.searchfield</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>20286C29FDCF999611CA2CEA</string>
+ <string>20286C2AFDCF999611CA2CEA</string>
+ <string>20286C32FDCF999611CA2CEA</string>
+ <string>1C37FBAC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>78</integer>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 1010}, {186, 520}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 538}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>372 210 780 579 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>203pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>MyNewFile14.java</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>MyNewFile14.java</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {572, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>372 210 780 579 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 5}, {572, 533}}</string>
+ <key>RubberWindowFrame</key>
+ <string>372 210 780 579 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>533pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>572pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>924A47AB0D1069F5004FEA83</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>924A47AC0D1069F5004FEA83</string>
+ <string>1CE0B20306471E060097A5F4</string>
+ <string>1CE0B20506471E060097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default</string>
+ </dict>
+ <dict>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.morph</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 337}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>1</integer>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 355}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>373 269 690 397 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Morph</string>
+ <key>PreferredWidth</key>
+ <integer>300</integer>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default.short</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <false/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>SourceDescription</key>
+ <string>file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarDisplayMode</key>
+ <integer>1</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>92BC40B30BAEE8C1000DAB7F</string>
+ <string>/Users/garfield/programming/themanaworld/tmw/branches/0.0/themanaworld.xcodeproj</string>
+ </array>
+ <key>WindowString</key>
+ <string>372 210 780 579 0 0 1280 832 </string>
+ <key>WindowTools</key>
+ <array>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {553, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>316 222 553 548 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBuildLogShowsTranscriptDefaultKey</key>
+ <string>{{0, 5}, {553, 497}}</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 5}, {553, 502}}</string>
+ <key>RubberWindowFrame</key>
+ <string>316 222 553 548 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>502pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>507pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>92BC40B30BAEE8C1000DAB7F</string>
+ <string>924A47B10D107075004FEA83</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.build</string>
+ <key>WindowString</key>
+ <string>316 222 553 548 0 0 1280 832 </string>
+ <key>WindowToolGUID</key>
+ <string>92BC40B30BAEE8C1000DAB7F</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {317, 164}}</string>
+ <string>{{317, 0}, {377, 164}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {694, 164}}</string>
+ <string>{{0, 164}, {694, 216}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleDrawerSize</key>
+ <string>{100, 120}</string>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {694, 380}}</string>
+ <key>RubberWindowFrame</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>1C0AD2AB069F1E9B00FABCE6</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>1C0AD2AC069F1E9B00FABCE6</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debug</string>
+ <key>WindowString</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>playerhandler.cpp</string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {781, 212}}</string>
+ <key>RubberWindowFrame</key>
+ <string>212 362 781 470 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>781pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>212pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528E0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 217}, {781, 212}}</string>
+ <key>RubberWindowFrame</key>
+ <string>212 362 781 470 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Proportion</key>
+ <string>212pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>429pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Find</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXProjectFindModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <string>92E427510C1EB4AC000361B7</string>
+ <string>92E427520C1EB4AC000361B7</string>
+ <string>1CDD528C0622207200134675</string>
+ <string>1CD0528E0623707200166675</string>
+ </array>
+ <key>WindowString</key>
+ <string>212 362 781 470 0 0 1280 832 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>MENUSEPARATOR</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debuggerConsole</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAAC065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {440, 358}}</string>
+ <key>RubberWindowFrame</key>
+ <string>650 41 440 400 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>358pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>358pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger Console</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugCLIModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAAD065D492600B07095</string>
+ <string>1C78EAAE065D492600B07095</string>
+ <string>1C78EAAC065D492600B07095</string>
+ </array>
+ <key>WindowString</key>
+ <string>650 41 440 400 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.run</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>LauncherConfigVersion</key>
+ <string>3</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528B0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Run</string>
+ <key>Runner</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {493, 167}}</string>
+ <string>{{0, 176}, {493, 267}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {405, 443}}</string>
+ <string>{{414, 0}, {514, 443}}</string>
+ </array>
+ </dict>
+ </dict>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {459, 159}}</string>
+ <key>RubberWindowFrame</key>
+ <string>316 570 459 200 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXRunSessionModule</string>
+ <key>Proportion</key>
+ <string>159pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>159pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Run Log</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXRunSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2B3069F1EA900FABCE6</string>
+ <string>92AA62E70C21BDEA007FAAD0</string>
+ <string>1CD0528B0623707200166675</string>
+ <string>92AA62E80C21BDEA007FAAD0</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.run</string>
+ <key>WindowString</key>
+ <string>316 570 459 200 0 0 1280 832 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2B3069F1EA900FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.scm</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB2065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>&lt;No Editor&gt;</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB3065D492600B07095</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {452, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052920623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ConsoleFrame</key>
+ <string>{{0, 259}, {452, 0}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {452, 259}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ <key>TableConfiguration</key>
+ <array>
+ <string>Status</string>
+ <real>30</real>
+ <string>FileName</string>
+ <real>199</real>
+ <string>Path</string>
+ <real>197.09500122070312</real>
+ </array>
+ <key>TableFrame</key>
+ <string>{{0, 0}, {452, 250}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Proportion</key>
+ <string>262pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>266pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>SCM</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXCVSModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAB4065D492600B07095</string>
+ <string>1C78EAB5065D492600B07095</string>
+ <string>1C78EAB2065D492600B07095</string>
+ <string>1CD052920623707200166675</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.scm</string>
+ <key>WindowString</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.breakpoints</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>no</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>168</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {168, 350}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>0</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {185, 368}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>168</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>185pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA1AED706398EBD00589147</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{190, 0}, {554, 368}}</string>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>554pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>368pt</string>
+ </dict>
+ </array>
+ <key>MajorVersion</key>
+ <integer>2</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Breakpoints</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <string>1CDDB66907F98D9800BB5817</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CA1AED706398EBD00589147</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.breakpoints</string>
+ <key>WindowString</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <key>WindowToolIsVisible</key>
+ <integer>1</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugAnimator</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug Visualizer</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugAnimator</string>
+ <key>WindowString</key>
+ <string>100 100 700 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.bookmarks</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Bookmarks</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBookmarksModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowString</key>
+ <string>538 42 401 187 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.classBrowser</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>OptionsSetName</key>
+ <string>Hierarchy, all classes</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA6456E063B45B4001379D8</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Class Browser - NSObject</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ClassesFrame</key>
+ <string>{{0, 0}, {374, 96}}</string>
+ <key>ClassesTreeTableConfiguration</key>
+ <array>
+ <string>PBXClassNameColumnIdentifier</string>
+ <real>208</real>
+ <string>PBXClassBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>Frame</key>
+ <string>{{0, 0}, {630, 331}}</string>
+ <key>MembersFrame</key>
+ <string>{{0, 105}, {374, 395}}</string>
+ <key>MembersTreeTableConfiguration</key>
+ <array>
+ <string>PBXMemberTypeIconColumnIdentifier</string>
+ <real>22</real>
+ <string>PBXMemberNameColumnIdentifier</string>
+ <real>216</real>
+ <string>PBXMemberTypeColumnIdentifier</string>
+ <real>97</real>
+ <string>PBXMemberBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <integer>1</integer>
+ <key>RubberWindowFrame</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Class Browser</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXClassBrowserModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <string>1C0AD2B0069F1E9B00FABCE6</string>
+ <string>1CA6456E063B45B4001379D8</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.classbrowser</string>
+ <key>WindowString</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/mana.xcodeproj/garfield.mode1v3 b/mana.xcodeproj/garfield.mode1v3
new file mode 100644
index 000000000..238c1fa3e
--- /dev/null
+++ b/mana.xcodeproj/garfield.mode1v3
@@ -0,0 +1,1409 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Name</key>
+ <string>Project Format Conflicts List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Name</key>
+ <string>Snapshots Tool</string>
+ </dict>
+ </array>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1v3</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>92A4CC870D1C46A000CA28FB</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1v3</string>
+ <key>MajorVersion</key>
+ <integer>33</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-combo-popup</string>
+ <string>action</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>debugger-enable-breakpoints</string>
+ <string>build</string>
+ <string>build-and-go</string>
+ <string>clean</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>get-info</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>com.apple.pbx.toolbar.searchfield</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>158</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>20286C29FDCF999611CA2CEA</string>
+ <string>1C37FBAC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>8</integer>
+ <integer>7</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {158, 599}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {175, 617}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>158</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>235 191 933 658 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>175pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {753, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>235 191 933 658 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 5}, {753, 612}}</string>
+ <key>RubberWindowFrame</key>
+ <string>235 191 933 658 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>612pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>753pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>9228959611F662A300AE53BB</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>9228959711F662A300AE53BB</string>
+ <string>1CE0B20306471E060097A5F4</string>
+ <string>1CE0B20506471E060097A5F4</string>
+ </array>
+ <key>ToolbarConfigUserDefaultsMinorVersion</key>
+ <string>2</string>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.defaultV3</string>
+ </dict>
+ <dict>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.morph</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 337}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>1</integer>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 355}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>373 269 690 397 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Morph</string>
+ <key>PreferredWidth</key>
+ <integer>300</integer>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default.shortV3</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <false/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarDisplayMode</key>
+ <integer>1</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>92A4CC8A0D1C5F1E00CA28FB</string>
+ <string>/Users/garfield/Programming/mana/mana.xcodeproj</string>
+ </array>
+ <key>WindowString</key>
+ <string>235 191 933 658 0 0 1440 878 </string>
+ <key>WindowToolsV3</key>
+ <array>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {553, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>107 258 553 548 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build Results</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 5}, {553, 502}}</string>
+ <key>RubberWindowFrame</key>
+ <string>107 258 553 548 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>502pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>507pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>92A4CC8A0D1C5F1E00CA28FB</string>
+ <string>9228959811F662A300AE53BB</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.buildV3</string>
+ <key>WindowString</key>
+ <string>107 258 553 548 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>92A4CC8A0D1C5F1E00CA28FB</string>
+ <key>WindowToolIsVisible</key>
+ <true/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {316, 203}}</string>
+ <string>{{316, 0}, {378, 203}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {694, 203}}</string>
+ <string>{{0, 203}, {694, 178}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {694, 381}}</string>
+ <key>PBXDebugSessionStackFrameViewKey</key>
+ <dict>
+ <key>DebugVariablesTableConfiguration</key>
+ <array>
+ <string>Name</string>
+ <real>140</real>
+ <string>Value</string>
+ <real>85</real>
+ <string>Summary</string>
+ <real>986</real>
+ </array>
+ <key>Frame</key>
+ <string>{{316, 0}, {378, 203}}</string>
+ <key>RubberWindowFrame</key>
+ <string>241 397 694 422 0 0 1440 878 </string>
+ </dict>
+ <key>RubberWindowFrame</key>
+ <string>241 397 694 422 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>381pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>381pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>9228959911F662A300AE53BB</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>9228959A11F662A300AE53BB</string>
+ <string>9228959B11F662A300AE53BB</string>
+ <string>9228959C11F662A300AE53BB</string>
+ <string>9228959D11F662A300AE53BB</string>
+ <string>9228959E11F662A300AE53BB</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugV3</string>
+ <key>WindowString</key>
+ <string>241 397 694 422 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <true/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>connection.cpp</string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {781, 212}}</string>
+ <key>RubberWindowFrame</key>
+ <string>468 332 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>781pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>212pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528E0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 217}, {781, 212}}</string>
+ <key>RubberWindowFrame</key>
+ <string>468 332 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Proportion</key>
+ <string>212pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>429pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Find</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXProjectFindModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <string>9268580611F15D8C00A28C33</string>
+ <string>9268580711F15D8C00A28C33</string>
+ <string>1CDD528C0622207200134675</string>
+ <string>1CD0528E0623707200166675</string>
+ </array>
+ <key>WindowString</key>
+ <string>468 332 781 470 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>MENUSEPARATOR</string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debuggerConsole</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAAC065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {440, 359}}</string>
+ <key>RubberWindowFrame</key>
+ <string>529 224 440 400 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>359pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>359pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger Console</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugCLIModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAAD065D492600B07095</string>
+ <string>92C85D7311F2998B00AB20CA</string>
+ <string>1C78EAAC065D492600B07095</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.consoleV3</string>
+ <key>WindowString</key>
+ <string>529 224 440 400 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C78EAAD065D492600B07095</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.snapshots</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Snapshots</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCSnapshotModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <string>Yes</string>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.snapshots</string>
+ <key>WindowString</key>
+ <string>315 824 300 550 0 0 1440 878 </string>
+ <key>WindowToolIsVisible</key>
+ <string>Yes</string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.scm</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB2065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>&lt;No Editor&gt;</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB3065D492600B07095</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {452, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052920623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ConsoleFrame</key>
+ <string>{{0, 259}, {452, 0}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {452, 259}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ <key>TableConfiguration</key>
+ <array>
+ <string>Status</string>
+ <real>30</real>
+ <string>FileName</string>
+ <real>199</real>
+ <string>Path</string>
+ <real>197.09500122070312</real>
+ </array>
+ <key>TableFrame</key>
+ <string>{{0, 0}, {452, 250}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Proportion</key>
+ <string>262pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>266pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>SCM</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXCVSModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAB4065D492600B07095</string>
+ <string>1C78EAB5065D492600B07095</string>
+ <string>1C78EAB2065D492600B07095</string>
+ <string>1CD052920623707200166675</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.scm</string>
+ <key>WindowString</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.breakpoints</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>no</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>168</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {168, 350}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <false/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {185, 368}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>168</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>243 383 744 409 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>185pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA1AED706398EBD00589147</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{190, 0}, {554, 368}}</string>
+ <key>RubberWindowFrame</key>
+ <string>243 383 744 409 0 0 1280 832 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>554pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>368pt</string>
+ </dict>
+ </array>
+ <key>MajorVersion</key>
+ <integer>3</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Breakpoints</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>92EE9EF30D2E0CA400DDE300</string>
+ <string>92EE9EF40D2E0CA400DDE300</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CA1AED706398EBD00589147</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.breakpointsV3</string>
+ <key>WindowString</key>
+ <string>243 383 744 409 0 0 1280 832 </string>
+ <key>WindowToolGUID</key>
+ <string>92EE9EF30D2E0CA400DDE300</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debugAnimator</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug Visualizer</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugAnimatorV3</string>
+ <key>WindowString</key>
+ <string>100 100 700 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.bookmarks</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Bookmarks</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBookmarksModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <false/>
+ <key>WindowString</key>
+ <string>538 42 401 187 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.projectFormatConflicts</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>9268589711F174B900A28C33</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {472, 302}}</string>
+ <key>RubberWindowFrame</key>
+ <string>128 461 472 322 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Proportion</key>
+ <string>302pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>302pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Format Conflicts</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCProjectFormatConflictsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <false/>
+ <key>TableOfContents</key>
+ <array>
+ <string>9268589811F174B900A28C33</string>
+ <string>9268589911F174B900A28C33</string>
+ <string>9268589711F174B900A28C33</string>
+ </array>
+ <key>WindowContentMinSize</key>
+ <string>450 300</string>
+ <key>WindowString</key>
+ <string>128 461 472 322 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>9268589811F174B900A28C33</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.classBrowser</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>OptionsSetName</key>
+ <string>Hierarchy, all classes</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA6456E063B45B4001379D8</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Class Browser - NSObject</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ClassesFrame</key>
+ <string>{{0, 0}, {374, 96}}</string>
+ <key>ClassesTreeTableConfiguration</key>
+ <array>
+ <string>PBXClassNameColumnIdentifier</string>
+ <real>208</real>
+ <string>PBXClassBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>Frame</key>
+ <string>{{0, 0}, {630, 331}}</string>
+ <key>MembersFrame</key>
+ <string>{{0, 105}, {374, 395}}</string>
+ <key>MembersTreeTableConfiguration</key>
+ <array>
+ <string>PBXMemberTypeIconColumnIdentifier</string>
+ <real>22</real>
+ <string>PBXMemberNameColumnIdentifier</string>
+ <real>216</real>
+ <string>PBXMemberTypeColumnIdentifier</string>
+ <real>97</real>
+ <string>PBXMemberBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <integer>1</integer>
+ <key>RubberWindowFrame</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Class Browser</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXClassBrowserModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <false/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <string>1C0AD2B0069F1E9B00FABCE6</string>
+ <string>1CA6456E063B45B4001379D8</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.classbrowser</string>
+ <key>WindowString</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.refactoring</string>
+ <key>IncludeInToolsMenu</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{0, 0}, {500, 335}</string>
+ <key>RubberWindowFrame</key>
+ <string>{0, 0}, {500, 335}</string>
+ </dict>
+ <key>Module</key>
+ <string>XCRefactoringModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Refactoring</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCRefactoringModule</string>
+ </array>
+ <key>WindowString</key>
+ <string>200 200 500 356 0 0 1920 1200 </string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/mana.xcodeproj/project.pbxproj b/mana.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..bab73682b
--- /dev/null
+++ b/mana.xcodeproj/project.pbxproj
@@ -0,0 +1,2339 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 44;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
+ 92024D2F0CF1BD9E006B55CB /* keyboardconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92024D2A0CF1BD9E006B55CB /* keyboardconfig.cpp */; };
+ 92024D3D0CF1BDF7006B55CB /* setup_keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92024D360CF1BDF7006B55CB /* setup_keyboard.cpp */; };
+ 92024E760CF1DCF6006B55CB /* imageloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92024E740CF1DCF6006B55CB /* imageloader.cpp */; };
+ 92037A1F0ED2037300D3712D /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92037A1B0ED2037300D3712D /* text.cpp */; };
+ 92037A200ED2037300D3712D /* textmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92037A1D0ED2037300D3712D /* textmanager.cpp */; };
+ 920C631F0F37D0EF001DD274 /* SDL_ttf.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 926A29790F23C155005D6466 /* SDL_ttf.framework */; };
+ 922895B711F665A200AE53BB /* libintl.8.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 922895B411F665A200AE53BB /* libintl.8.dylib */; };
+ 922895B811F665A200AE53BB /* libphysfs.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 922895B511F665A200AE53BB /* libphysfs.1.dylib */; };
+ 922895B911F665A200AE53BB /* libSDL_gfx.13.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 922895B611F665A200AE53BB /* libSDL_gfx.13.dylib */; };
+ 922895BA11F665A700AE53BB /* libintl.8.dylib in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 922895B411F665A200AE53BB /* libintl.8.dylib */; };
+ 922895BB11F665AB00AE53BB /* libphysfs.1.dylib in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 922895B511F665A200AE53BB /* libphysfs.1.dylib */; };
+ 922895BC11F665AF00AE53BB /* libSDL_gfx.13.dylib in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 922895B611F665A200AE53BB /* libSDL_gfx.13.dylib */; };
+ 922895C111F6678300AE53BB /* libiconv.2.dylib in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 922895BF11F6677F00AE53BB /* libiconv.2.dylib */; };
+ 922895C211F6678700AE53BB /* libSDL-1.2.0.dylib in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 922895C011F6677F00AE53BB /* libSDL-1.2.0.dylib */; };
+ 922CD9580E3D00900074C50E /* npcdb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 922CD9560E3D00900074C50E /* npcdb.cpp */; };
+ 922CD95F0E3D01080074C50E /* shopitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 922CD95D0E3D01080074C50E /* shopitem.cpp */; };
+ 924A39F20C0784280066885E /* animationparticle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 924A39E80C0784280066885E /* animationparticle.cpp */; };
+ 924A39F30C0784280066885E /* imageparticle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 924A39EA0C0784280066885E /* imageparticle.cpp */; };
+ 924A39F40C0784280066885E /* particle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 924A39EC0C0784280066885E /* particle.cpp */; };
+ 924A39F50C0784280066885E /* particleemitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 924A39EE0C0784280066885E /* particleemitter.cpp */; };
+ 924A39F60C0784280066885E /* textparticle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 924A39F00C0784280066885E /* textparticle.cpp */; };
+ 924A3A120C07A60B0066885E /* resizegrip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 924A3A100C07A60B0066885E /* resizegrip.cpp */; };
+ 924A40570C085EF50066885E /* items.xsd in Copy Data Files */ = {isa = PBXBuildFile; fileRef = 924A401C0C085ED80066885E /* items.xsd */; };
+ 924A408B0C0860120066885E /* login_wallpaper.png in Copy Image Files */ = {isa = PBXBuildFile; fileRef = 924A3E9A0C085ED70066885E /* login_wallpaper.png */; };
+ 924A42020C0861EC0066885E /* about.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A400A0C085ED80066885E /* about.txt */; };
+ 924A42030C0861EC0066885E /* changes.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A400B0C085ED80066885E /* changes.txt */; };
+ 924A42040C0861EC0066885E /* commands.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A400D0C085ED80066885E /* commands.txt */; };
+ 924A42050C0861EC0066885E /* header.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A400E0C085ED80066885E /* header.txt */; };
+ 924A42060C0861EC0066885E /* index.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A400F0C085ED80066885E /* index.txt */; };
+ 924A42070C0861EC0066885E /* skills.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A40110C085ED80066885E /* skills.txt */; };
+ 924A42080C0861EC0066885E /* support.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A40120C085ED80066885E /* support.txt */; };
+ 924A42090C0861EC0066885E /* team.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 924A40130C085ED80066885E /* team.txt */; };
+ 925350030BC12A3200115FD5 /* imageset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 925350010BC12A3200115FD5 /* imageset.cpp */; };
+ 9268560011F141FD00A28C33 /* mana.icns in Resources */ = {isa = PBXBuildFile; fileRef = 926855FF11F141FD00A28C33 /* mana.icns */; };
+ 9268560211F142A000A28C33 /* colors.xml in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855E711F141D500A28C33 /* colors.xml */; };
+ 9268560311F142A000A28C33 /* progress-indicator.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855E811F141D500A28C33 /* progress-indicator.png */; };
+ 9268560411F142A000A28C33 /* radioin_highlight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855E911F141D500A28C33 /* radioin_highlight.png */; };
+ 9268560511F142A000A28C33 /* radioout_highlight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855EA11F141D500A28C33 /* radioout_highlight.png */; };
+ 9268560611F142A000A28C33 /* slider_hilight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855EB11F141D500A28C33 /* slider_hilight.png */; };
+ 9268560711F142A000A28C33 /* tab_hilight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855EC11F141D500A28C33 /* tab_hilight.png */; };
+ 9268560811F142A000A28C33 /* vscroll_highlight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855ED11F141D500A28C33 /* vscroll_highlight.png */; };
+ 9268560911F142A000A28C33 /* window.xml in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926855EE11F141D500A28C33 /* window.xml */; };
+ 9268560A11F142A000A28C33 /* window.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92C637800FC574B500EE8D8D /* window.png */; };
+ 9268560B11F142A000A28C33 /* circle-gray.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92C116010F8EC0590048CA8D /* circle-gray.png */; };
+ 9268560C11F142A000A28C33 /* circle-green.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92C116020F8EC0590048CA8D /* circle-green.png */; };
+ 9268560D11F142A000A28C33 /* speechbubble.xml in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92C116070F8EC0590048CA8D /* speechbubble.xml */; };
+ 9268560E11F142A000A28C33 /* sticky_button.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92C116080F8EC0590048CA8D /* sticky_button.png */; };
+ 9268560F11F142A000A28C33 /* bubble.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 928B50E40F2FB5430011C755 /* bubble.png */; };
+ 9268561011F142A000A28C33 /* tab.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926A297E0F23C18E005D6466 /* tab.png */; };
+ 9268561111F142A000A28C33 /* tabselected.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 926A297F0F23C18E005D6466 /* tabselected.png */; };
+ 9268561211F142A000A28C33 /* close_button.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92024D5B0CF1BE5C006B55CB /* close_button.png */; };
+ 9268561311F142A000A28C33 /* unknown-item.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92024D5D0CF1BE5C006B55CB /* unknown-item.png */; };
+ 9268561411F142A000A28C33 /* item_shortcut_bgr.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 92024D5C0CF1BE5C006B55CB /* item_shortcut_bgr.png */; };
+ 9268561511F142A000A28C33 /* button.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E620C085ED70066885E /* button.png */; };
+ 9268561611F142A000A28C33 /* button_disabled.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E630C085ED70066885E /* button_disabled.png */; };
+ 9268561711F142A000A28C33 /* buttonhi.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E640C085ED70066885E /* buttonhi.png */; };
+ 9268561811F142A000A28C33 /* buttonpress.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E650C085ED70066885E /* buttonpress.png */; };
+ 9268561911F142A000A28C33 /* checkbox.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E660C085ED70066885E /* checkbox.png */; };
+ 9268561A11F142A000A28C33 /* deepbox.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E680C085ED70066885E /* deepbox.png */; };
+ 9268561B11F142A000A28C33 /* hscroll_left_default.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E6D0C085ED70066885E /* hscroll_left_default.png */; };
+ 9268561C11F142A000A28C33 /* hscroll_left_highlight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E6E0C085ED70066885E /* hscroll_left_highlight.png */; };
+ 9268561D11F142A000A28C33 /* hscroll_left_pressed.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E6F0C085ED70066885E /* hscroll_left_pressed.png */; };
+ 9268561E11F142A000A28C33 /* hscroll_right_default.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E700C085ED70066885E /* hscroll_right_default.png */; };
+ 9268561F11F142A000A28C33 /* hscroll_right_highlight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E710C085ED70066885E /* hscroll_right_highlight.png */; };
+ 9268562011F142A000A28C33 /* hscroll_right_pressed.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E720C085ED70066885E /* hscroll_right_pressed.png */; };
+ 9268562111F142A000A28C33 /* mouse.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E780C085ED70066885E /* mouse.png */; };
+ 9268562211F142A000A28C33 /* radioin.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E790C085ED70066885E /* radioin.png */; };
+ 9268562311F142A000A28C33 /* radioout.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E7A0C085ED70066885E /* radioout.png */; };
+ 9268562411F142A000A28C33 /* resize.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E7B0C085ED70066885E /* resize.png */; };
+ 9268562511F142A000A28C33 /* selection.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E7E0C085ED70066885E /* selection.png */; };
+ 9268562611F142A000A28C33 /* slider.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E7F0C085ED70066885E /* slider.png */; };
+ 9268562711F142A000A28C33 /* target-cursor-blue-l.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E800C085ED70066885E /* target-cursor-blue-l.png */; };
+ 9268562811F142A000A28C33 /* target-cursor-blue-m.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E810C085ED70066885E /* target-cursor-blue-m.png */; };
+ 9268562911F142A000A28C33 /* target-cursor-blue-s.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E820C085ED70066885E /* target-cursor-blue-s.png */; };
+ 9268562A11F142A000A28C33 /* target-cursor-red-l.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E830C085ED70066885E /* target-cursor-red-l.png */; };
+ 9268562B11F142A000A28C33 /* target-cursor-red-m.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E840C085ED70066885E /* target-cursor-red-m.png */; };
+ 9268562C11F142A000A28C33 /* target-cursor-red-s.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E850C085ED70066885E /* target-cursor-red-s.png */; };
+ 9268562D11F142A000A28C33 /* vscroll_down_default.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E880C085ED70066885E /* vscroll_down_default.png */; };
+ 9268562E11F142A000A28C33 /* vscroll_down_highlight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E890C085ED70066885E /* vscroll_down_highlight.png */; };
+ 9268562F11F142A000A28C33 /* vscroll_down_pressed.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E8A0C085ED70066885E /* vscroll_down_pressed.png */; };
+ 9268563011F142A000A28C33 /* vscroll_grey.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E8B0C085ED70066885E /* vscroll_grey.png */; };
+ 9268563111F142A000A28C33 /* vscroll_up_default.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E8D0C085ED70066885E /* vscroll_up_default.png */; };
+ 9268563211F142A000A28C33 /* vscroll_up_highlight.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E8E0C085ED70066885E /* vscroll_up_highlight.png */; };
+ 9268563311F142A000A28C33 /* vscroll_up_pressed.png in Copy GUI Files */ = {isa = PBXBuildFile; fileRef = 924A3E8F0C085ED70066885E /* vscroll_up_pressed.png */; };
+ 9268565211F142D500A28C33 /* avatar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268564B11F142D500A28C33 /* avatar.cpp */; };
+ 9268565311F142D500A28C33 /* client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268564D11F142D500A28C33 /* client.cpp */; };
+ 9268565411F142D500A28C33 /* party.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268564F11F142D500A28C33 /* party.cpp */; };
+ 9268566811F142F100A28C33 /* beingpopup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268565811F142F100A28C33 /* beingpopup.cpp */; };
+ 9268566911F142F100A28C33 /* connectiondialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268565A11F142F100A28C33 /* connectiondialog.cpp */; };
+ 9268566A11F142F100A28C33 /* socialwindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268565C11F142F100A28C33 /* socialwindow.cpp */; };
+ 9268566B11F142F100A28C33 /* specialswindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268565E11F142F100A28C33 /* specialswindow.cpp */; };
+ 9268566C11F142F100A28C33 /* textpopup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268566011F142F100A28C33 /* textpopup.cpp */; };
+ 9268566D11F142F100A28C33 /* theme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268566211F142F100A28C33 /* theme.cpp */; };
+ 9268566E11F142F100A28C33 /* userpalette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268566411F142F100A28C33 /* userpalette.cpp */; };
+ 9268566F11F142F100A28C33 /* worldselectdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268566611F142F100A28C33 /* worldselectdialog.cpp */; };
+ 9268569711F1431300A28C33 /* avatarlistbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268567811F1431300A28C33 /* avatarlistbox.cpp */; };
+ 9268569811F1431300A28C33 /* emoteshortcutcontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268567A11F1431300A28C33 /* emoteshortcutcontainer.cpp */; };
+ 9268569911F1431300A28C33 /* flowcontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268567C11F1431300A28C33 /* flowcontainer.cpp */; };
+ 9268569A11F1431300A28C33 /* itemcontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268567E11F1431300A28C33 /* itemcontainer.cpp */; };
+ 9268569B11F1431300A28C33 /* itemlinkhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568011F1431300A28C33 /* itemlinkhandler.cpp */; };
+ 9268569C11F1431300A28C33 /* itemshortcutcontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568211F1431300A28C33 /* itemshortcutcontainer.cpp */; };
+ 9268569D11F1431300A28C33 /* playerbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568511F1431300A28C33 /* playerbox.cpp */; };
+ 9268569E11F1431300A28C33 /* progressindicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568711F1431300A28C33 /* progressindicator.cpp */; };
+ 9268569F11F1431300A28C33 /* setuptab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568911F1431300A28C33 /* setuptab.cpp */; };
+ 926856A011F1431300A28C33 /* shopitems.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568B11F1431300A28C33 /* shopitems.cpp */; };
+ 926856A111F1431300A28C33 /* shoplistbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568D11F1431300A28C33 /* shoplistbox.cpp */; };
+ 926856A211F1431300A28C33 /* shortcutcontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268568F11F1431300A28C33 /* shortcutcontainer.cpp */; };
+ 926856A311F1431300A28C33 /* table.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268569111F1431300A28C33 /* table.cpp */; };
+ 926856A411F1431300A28C33 /* tablemodel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268569311F1431300A28C33 /* tablemodel.cpp */; };
+ 926856A511F1431300A28C33 /* vertcontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268569511F1431300A28C33 /* vertcontainer.cpp */; };
+ 926856BB11F1433300A28C33 /* charhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856B511F1433300A28C33 /* charhandler.cpp */; };
+ 926856BC11F1433300A28C33 /* download.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856B611F1433300A28C33 /* download.cpp */; };
+ 9268573911F1433F00A28C33 /* adminhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856F211F1433E00A28C33 /* adminhandler.cpp */; };
+ 9268573A11F1433F00A28C33 /* beinghandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856F411F1433E00A28C33 /* beinghandler.cpp */; };
+ 9268573B11F1433F00A28C33 /* buysellhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856F611F1433E00A28C33 /* buysellhandler.cpp */; };
+ 9268573C11F1433F00A28C33 /* charserverhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856F811F1433E00A28C33 /* charserverhandler.cpp */; };
+ 9268573D11F1433F00A28C33 /* chathandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856FA11F1433F00A28C33 /* chathandler.cpp */; };
+ 9268573E11F1433F00A28C33 /* gamehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856FC11F1433F00A28C33 /* gamehandler.cpp */; };
+ 9268573F11F1433F00A28C33 /* generalhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856FE11F1433F00A28C33 /* generalhandler.cpp */; };
+ 9268574011F1433F00A28C33 /* guildtab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570111F1433F00A28C33 /* guildtab.cpp */; };
+ 9268574111F1433F00A28C33 /* partytab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570311F1433F00A28C33 /* partytab.cpp */; };
+ 9268574211F1433F00A28C33 /* guildhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570511F1433F00A28C33 /* guildhandler.cpp */; };
+ 9268574311F1433F00A28C33 /* inventoryhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570711F1433F00A28C33 /* inventoryhandler.cpp */; };
+ 9268574411F1433F00A28C33 /* itemhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570911F1433F00A28C33 /* itemhandler.cpp */; };
+ 9268574511F1433F00A28C33 /* loginhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570B11F1433F00A28C33 /* loginhandler.cpp */; };
+ 9268574611F1433F00A28C33 /* messagehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570D11F1433F00A28C33 /* messagehandler.cpp */; };
+ 9268574711F1433F00A28C33 /* messagein.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268570F11F1433F00A28C33 /* messagein.cpp */; };
+ 9268574811F1433F00A28C33 /* messageout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268571111F1433F00A28C33 /* messageout.cpp */; };
+ 9268574911F1433F00A28C33 /* network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268571311F1433F00A28C33 /* network.cpp */; };
+ 9268574A11F1433F00A28C33 /* npchandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268571511F1433F00A28C33 /* npchandler.cpp */; };
+ 9268574B11F1433F00A28C33 /* partyhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268571711F1433F00A28C33 /* partyhandler.cpp */; };
+ 9268574C11F1433F00A28C33 /* playerhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268571911F1433F00A28C33 /* playerhandler.cpp */; };
+ 9268574D11F1433F00A28C33 /* specialhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268571C11F1433F00A28C33 /* specialhandler.cpp */; };
+ 9268574E11F1433F00A28C33 /* tradehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268571F11F1433F00A28C33 /* tradehandler.cpp */; };
+ 9268577F11F1435200A28C33 /* ambientlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268577D11F1435200A28C33 /* ambientlayer.cpp */; };
+ 9268578711F1435F00A28C33 /* copynpaste.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268578111F1435F00A28C33 /* copynpaste.cpp */; };
+ 9268578811F1435F00A28C33 /* mkdir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268578311F1435F00A28C33 /* mkdir.cpp */; };
+ 9268578911F1435F00A28C33 /* specialfolder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9268578511F1435F00A28C33 /* specialfolder.cpp */; };
+ 926857AC11F15A9300A28C33 /* guichan.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 926857AB11F15A9300A28C33 /* guichan.framework */; };
+ 926857B011F15AB200A28C33 /* guichan.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 926857AB11F15A9300A28C33 /* guichan.framework */; };
+ 9268581311F15F3900A28C33 /* adminhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856C011F1433E00A28C33 /* adminhandler.cpp */; };
+ 9268581411F15F3A00A28C33 /* beinghandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856C211F1433E00A28C33 /* beinghandler.cpp */; };
+ 9268581511F15F3B00A28C33 /* buysellhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856C411F1433E00A28C33 /* buysellhandler.cpp */; };
+ 9268581611F15F3C00A28C33 /* charhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856C611F1433E00A28C33 /* charhandler.cpp */; };
+ 9268581711F15F3D00A28C33 /* chathandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856C811F1433E00A28C33 /* chathandler.cpp */; };
+ 9268581811F15F3E00A28C33 /* connection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856CA11F1433E00A28C33 /* connection.cpp */; };
+ 9268581911F15F3F00A28C33 /* effecthandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856CC11F1433E00A28C33 /* effecthandler.cpp */; };
+ 9268581A11F15F4000A28C33 /* gamehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856CE11F1433E00A28C33 /* gamehandler.cpp */; };
+ 9268581B11F15F4000A28C33 /* generalhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856D011F1433E00A28C33 /* generalhandler.cpp */; };
+ 9268581C11F15F4200A28C33 /* guildhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856D211F1433E00A28C33 /* guildhandler.cpp */; };
+ 9268581D11F15F4300A28C33 /* internal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856D411F1433E00A28C33 /* internal.cpp */; };
+ 9268581E11F15F4400A28C33 /* inventoryhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856D611F1433E00A28C33 /* inventoryhandler.cpp */; };
+ 9268581F11F15F4500A28C33 /* itemhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856D811F1433E00A28C33 /* itemhandler.cpp */; };
+ 9268582011F15F4600A28C33 /* loginhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856DA11F1433E00A28C33 /* loginhandler.cpp */; };
+ 9268582111F15F4600A28C33 /* messagehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856DC11F1433E00A28C33 /* messagehandler.cpp */; };
+ 9268582211F15F4700A28C33 /* messagein.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856DE11F1433E00A28C33 /* messagein.cpp */; };
+ 9268582311F15F4800A28C33 /* messageout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856E011F1433E00A28C33 /* messageout.cpp */; };
+ 9268582411F15F4A00A28C33 /* network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856E211F1433E00A28C33 /* network.cpp */; };
+ 9268582511F15F4A00A28C33 /* npchandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856E411F1433E00A28C33 /* npchandler.cpp */; };
+ 9268582611F15F4C00A28C33 /* partyhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856E611F1433E00A28C33 /* partyhandler.cpp */; };
+ 9268582711F15F4C00A28C33 /* playerhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856E811F1433E00A28C33 /* playerhandler.cpp */; };
+ 9268582811F15F4E00A28C33 /* specialhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856EB11F1433E00A28C33 /* specialhandler.cpp */; };
+ 9268582911F15F4E00A28C33 /* stats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856ED11F1433E00A28C33 /* stats.cpp */; };
+ 9268582A11F15F5000A28C33 /* tradehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926856EF11F1433E00A28C33 /* tradehandler.cpp */; };
+ 9268583011F15F6800A28C33 /* changeemaildialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1191B0F8ED79A0048CA8D /* changeemaildialog.cpp */; };
+ 9268583111F15F6900A28C33 /* changepassworddialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C116E40F8ECBE80048CA8D /* changepassworddialog.cpp */; };
+ 9268583211F15F7100A28C33 /* quitdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1186F0F8ED33F0048CA8D /* quitdialog.cpp */; };
+ 9268583311F15F7300A28C33 /* serverdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C119830F8ED80E0048CA8D /* serverdialog.cpp */; };
+ 9268583411F15F7600A28C33 /* skilldialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C117530F8ECEEA0048CA8D /* skilldialog.cpp */; };
+ 9268583511F15F7900A28C33 /* statuswindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C117560F8ECF0B0048CA8D /* statuswindow.cpp */; };
+ 9268583611F15F7B00A28C33 /* textdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C118F20F8ED5DE0048CA8D /* textdialog.cpp */; };
+ 9268583711F15F7E00A28C33 /* unregisterdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C117580F8ECF0B0048CA8D /* unregisterdialog.cpp */; };
+ 9268583A11F15FAC00A28C33 /* guild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1188E0F8ED4B30048CA8D /* guild.cpp */; };
+ 9268583B11F15FC200A28C33 /* position.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C119980F8ED8B00048CA8D /* position.cpp */; };
+ 9268583C11F15FC900A28C33 /* sha256.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1198E0F8ED85E0048CA8D /* sha256.cpp */; };
+ 926A294A0F23BD88005D6466 /* layout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926A29440F23BD88005D6466 /* layout.cpp */; };
+ 926A294B0F23BD88005D6466 /* tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926A29460F23BD88005D6466 /* tab.cpp */; };
+ 926A294C0F23BD88005D6466 /* tabbedarea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926A29480F23BD88005D6466 /* tabbedarea.cpp */; };
+ 926A29580F23BD9E005D6466 /* sdlinput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926A29520F23BD9E005D6466 /* sdlinput.cpp */; };
+ 926A29590F23BD9E005D6466 /* truetypefont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926A29540F23BD9E005D6466 /* truetypefont.cpp */; };
+ 926A297A0F23C155005D6466 /* SDL_ttf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 926A29790F23C155005D6466 /* SDL_ttf.framework */; };
+ 926A299C0F23CA27005D6466 /* windows.txt in Copy Help Files */ = {isa = PBXBuildFile; fileRef = 926A29840F23C1C8005D6466 /* windows.txt */; };
+ 926A299E0F23CA5A005D6466 /* dejavusans.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 926A29980F23C988005D6466 /* dejavusans.ttf */; };
+ 926F9CF80DB005FA00AACD26 /* itemshortcut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926F9CF60DB005FA00AACD26 /* itemshortcut.cpp */; };
+ 9273BDFC0EF33DFD008E56E1 /* COPYING in Resources */ = {isa = PBXBuildFile; fileRef = 9273BDFB0EF33DFD008E56E1 /* COPYING */; };
+ 9273BDFF0EF33E1A008E56E1 /* AUTHORS in Resources */ = {isa = PBXBuildFile; fileRef = 9273BDFD0EF33E1A008E56E1 /* AUTHORS */; };
+ 9273BE000EF33E1A008E56E1 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 9273BDFE0EF33E1A008E56E1 /* README */; };
+ 9273BE080EF33FB3008E56E1 /* particlecontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9273BE040EF33FB3008E56E1 /* particlecontainer.cpp */; };
+ 9273BE090EF33FB3008E56E1 /* statuseffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9273BE060EF33FB3008E56E1 /* statuseffect.cpp */; };
+ 9294DAA10C17E73200FCEDE9 /* libpng.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9294DAA00C17E73200FCEDE9 /* libpng.framework */; };
+ 92A245C40F93626900B7719B /* desktop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A245C20F93626900B7719B /* desktop.cpp */; };
+ 92A245C50F93626C00B7719B /* container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A244B50F935FB400B7719B /* container.cpp */; };
+ 92A245CC0F93635800B7719B /* npcpostdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C119010F8ED63F0048CA8D /* npcpostdialog.cpp */; };
+ 92A4CC9E0D1C622E00CA28FB /* dye.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A4CC9D0D1C622E00CA28FB /* dye.cpp */; };
+ 92BC3FF60BAEE55B000DAB7F /* animatedsprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3ECA0BAEE55A000DAB7F /* animatedsprite.cpp */; };
+ 92BC3FF70BAEE55B000DAB7F /* being.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3ECC0BAEE55A000DAB7F /* being.cpp */; };
+ 92BC3FF80BAEE55B000DAB7F /* beingmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3ECE0BAEE55A000DAB7F /* beingmanager.cpp */; };
+ 92BC3FFA0BAEE55B000DAB7F /* configuration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3ED20BAEE55A000DAB7F /* configuration.cpp */; };
+ 92BC40050BAEE55B000DAB7F /* flooritemmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3EEA0BAEE55A000DAB7F /* flooritemmanager.cpp */; };
+ 92BC40060BAEE55B000DAB7F /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3EEC0BAEE55A000DAB7F /* game.cpp */; };
+ 92BC40070BAEE55B000DAB7F /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3EEE0BAEE55A000DAB7F /* graphics.cpp */; };
+ 92BC400C0BAEE55B000DAB7F /* buy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3EF90BAEE55A000DAB7F /* buy.cpp */; };
+ 92BC400D0BAEE55B000DAB7F /* buysell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3EFB0BAEE55A000DAB7F /* buysell.cpp */; };
+ 92BC40110BAEE55B000DAB7F /* chat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F030BAEE55A000DAB7F /* chat.cpp */; };
+ 92BC40160BAEE55B000DAB7F /* debugwindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F0D0BAEE55A000DAB7F /* debugwindow.cpp */; };
+ 92BC40170BAEE55B000DAB7F /* equipmentwindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F0F0BAEE55A000DAB7F /* equipmentwindow.cpp */; };
+ 92BC40180BAEE55B000DAB7F /* focushandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F110BAEE55A000DAB7F /* focushandler.cpp */; };
+ 92BC401A0BAEE55B000DAB7F /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F150BAEE55A000DAB7F /* gui.cpp */; };
+ 92BC401C0BAEE55B000DAB7F /* help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F190BAEE55A000DAB7F /* help.cpp */; };
+ 92BC401E0BAEE55B000DAB7F /* inventorywindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F1D0BAEE55A000DAB7F /* inventorywindow.cpp */; };
+ 92BC40220BAEE55B000DAB7F /* login.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F260BAEE55A000DAB7F /* login.cpp */; };
+ 92BC40240BAEE55B000DAB7F /* minimap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F2A0BAEE55A000DAB7F /* minimap.cpp */; };
+ 92BC40250BAEE55B000DAB7F /* ministatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F2C0BAEE55A000DAB7F /* ministatus.cpp */; };
+ 92BC402C0BAEE55B000DAB7F /* popupmenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F3A0BAEE55A000DAB7F /* popupmenu.cpp */; };
+ 92BC402F0BAEE55B000DAB7F /* register.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F400BAEE55A000DAB7F /* register.cpp */; };
+ 92BC40310BAEE55B000DAB7F /* sell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F450BAEE55A000DAB7F /* sell.cpp */; };
+ 92BC40320BAEE55B000DAB7F /* setup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F470BAEE55A000DAB7F /* setup.cpp */; };
+ 92BC40330BAEE55B000DAB7F /* setup_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F490BAEE55A000DAB7F /* setup_audio.cpp */; };
+ 92BC40340BAEE55B000DAB7F /* setup_joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F4B0BAEE55A000DAB7F /* setup_joystick.cpp */; };
+ 92BC40350BAEE55B000DAB7F /* setup_video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F4D0BAEE55A000DAB7F /* setup_video.cpp */; };
+ 92BC403E0BAEE55B000DAB7F /* trade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F600BAEE55B000DAB7F /* trade.cpp */; };
+ 92BC403F0BAEE55B000DAB7F /* updatewindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F620BAEE55B000DAB7F /* updatewindow.cpp */; };
+ 92BC40410BAEE55B000DAB7F /* viewport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F660BAEE55B000DAB7F /* viewport.cpp */; };
+ 92BC40440BAEE55B000DAB7F /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F6D0BAEE55B000DAB7F /* inventory.cpp */; };
+ 92BC40450BAEE55B000DAB7F /* item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F6F0BAEE55B000DAB7F /* item.cpp */; };
+ 92BC40460BAEE55B000DAB7F /* joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F710BAEE55B000DAB7F /* joystick.cpp */; };
+ 92BC40470BAEE55B000DAB7F /* localplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F730BAEE55B000DAB7F /* localplayer.cpp */; };
+ 92BC40480BAEE55B000DAB7F /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F760BAEE55B000DAB7F /* log.cpp */; };
+ 92BC40490BAEE55B000DAB7F /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F790BAEE55B000DAB7F /* main.cpp */; };
+ 92BC404B0BAEE55B000DAB7F /* map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F7C0BAEE55B000DAB7F /* map.cpp */; };
+ 92BC404C0BAEE55B000DAB7F /* monster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F7E0BAEE55B000DAB7F /* monster.cpp */; };
+ 92BC40570BAEE55B000DAB7F /* messagein.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F950BAEE55B000DAB7F /* messagein.cpp */; };
+ 92BC40580BAEE55B000DAB7F /* messageout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3F970BAEE55B000DAB7F /* messageout.cpp */; };
+ 92BC405F0BAEE55B000DAB7F /* npc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FA50BAEE55B000DAB7F /* npc.cpp */; };
+ 92BC40600BAEE55B000DAB7F /* openglgraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FA70BAEE55B000DAB7F /* openglgraphics.cpp */; };
+ 92BC406E0BAEE55B000DAB7F /* player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FBA0BAEE55B000DAB7F /* player.cpp */; };
+ 92BC406F0BAEE55B000DAB7F /* action.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FBE0BAEE55B000DAB7F /* action.cpp */; };
+ 92BC40700BAEE55B000DAB7F /* ambientoverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FC00BAEE55B000DAB7F /* ambientoverlay.cpp */; };
+ 92BC40710BAEE55B000DAB7F /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FC20BAEE55B000DAB7F /* animation.cpp */; };
+ 92BC40740BAEE55B000DAB7F /* image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FC90BAEE55B000DAB7F /* image.cpp */; };
+ 92BC40750BAEE55B000DAB7F /* imagewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FCB0BAEE55B000DAB7F /* imagewriter.cpp */; };
+ 92BC40760BAEE55B000DAB7F /* itemdb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FCD0BAEE55B000DAB7F /* itemdb.cpp */; };
+ 92BC40770BAEE55B000DAB7F /* iteminfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FCF0BAEE55B000DAB7F /* iteminfo.cpp */; };
+ 92BC40780BAEE55B000DAB7F /* mapreader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FD10BAEE55B000DAB7F /* mapreader.cpp */; };
+ 92BC40790BAEE55B000DAB7F /* monsterdb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FD30BAEE55B000DAB7F /* monsterdb.cpp */; };
+ 92BC407A0BAEE55B000DAB7F /* monsterinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FD50BAEE55B000DAB7F /* monsterinfo.cpp */; };
+ 92BC407B0BAEE55B000DAB7F /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FD70BAEE55B000DAB7F /* music.cpp */; };
+ 92BC407D0BAEE55B000DAB7F /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FDB0BAEE55B000DAB7F /* resource.cpp */; };
+ 92BC407E0BAEE55B000DAB7F /* resourcemanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FDD0BAEE55B000DAB7F /* resourcemanager.cpp */; };
+ 92BC40800BAEE55B000DAB7F /* soundeffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FE10BAEE55B000DAB7F /* soundeffect.cpp */; };
+ 92BC40810BAEE55B000DAB7F /* spritedef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FE30BAEE55B000DAB7F /* spritedef.cpp */; };
+ 92BC40830BAEE55B000DAB7F /* simpleanimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FE80BAEE55B000DAB7F /* simpleanimation.cpp */; };
+ 92BC40840BAEE55B000DAB7F /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FEA0BAEE55B000DAB7F /* sound.cpp */; };
+ 92BC40850BAEE55B000DAB7F /* base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FEF0BAEE55B000DAB7F /* base64.cpp */; };
+ 92BC40860BAEE55B000DAB7F /* xml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92BC3FF40BAEE55B000DAB7F /* xml.cpp */; };
+ 92BC40940BAEE818000DAB7F /* SDL_image.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC408E0BAEE818000DAB7F /* SDL_image.framework */; };
+ 92BC40950BAEE818000DAB7F /* SDL_mixer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC408F0BAEE818000DAB7F /* SDL_mixer.framework */; };
+ 92BC40960BAEE818000DAB7F /* SDL_net.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC40900BAEE818000DAB7F /* SDL_net.framework */; };
+ 92BC40970BAEE818000DAB7F /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC40910BAEE818000DAB7F /* SDL.framework */; };
+ 92BC40C70BAEEDAA000DAB7F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC40C60BAEEDAA000DAB7F /* OpenGL.framework */; };
+ 92BC40D90BAEEED3000DAB7F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC40D80BAEEED3000DAB7F /* IOKit.framework */; };
+ 92BC40E60BAEF54B000DAB7F /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 92BC40E50BAEF54B000DAB7F /* SDLMain.m */; };
+ 92BC40E90BAEF57D000DAB7F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC40E80BAEF57D000DAB7F /* Cocoa.framework */; };
+ 92C1150E0F8EBB360048CA8D /* window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1150C0F8EBB360048CA8D /* window.cpp */; };
+ 92C115120F8EBB550048CA8D /* itempopup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115100F8EBB550048CA8D /* itempopup.cpp */; };
+ 92C1151A0F8EBB830048CA8D /* listbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115140F8EBB830048CA8D /* listbox.cpp */; };
+ 92C1151B0F8EBB830048CA8D /* scrollarea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115160F8EBB830048CA8D /* scrollarea.cpp */; };
+ 92C1151C0F8EBB830048CA8D /* slider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115180F8EBB830048CA8D /* slider.cpp */; };
+ 92C115200F8EBBA90048CA8D /* emoteshortcut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1151E0F8EBBA90048CA8D /* emoteshortcut.cpp */; };
+ 92C115280F8EBBD50048CA8D /* inttextfield.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115220F8EBBD50048CA8D /* inttextfield.cpp */; };
+ 92C115290F8EBBD50048CA8D /* popup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115240F8EBBD50048CA8D /* popup.cpp */; };
+ 92C1152A0F8EBBD50048CA8D /* textfield.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115260F8EBBD50048CA8D /* textfield.cpp */; };
+ 92C115360F8EBC450048CA8D /* browserbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115320F8EBC450048CA8D /* browserbox.cpp */; };
+ 92C115370F8EBC450048CA8D /* windowcontainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115340F8EBC450048CA8D /* windowcontainer.cpp */; };
+ 92C1153B0F8EBC730048CA8D /* chattab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115390F8EBC730048CA8D /* chattab.cpp */; };
+ 92C115440F8EBCB70048CA8D /* shortcutwindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115410F8EBCB70048CA8D /* shortcutwindow.cpp */; };
+ 92C115470F8EBCD00048CA8D /* passwordfield.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115450F8EBCD00048CA8D /* passwordfield.cpp */; };
+ 92C1154D0F8EBD000048CA8D /* checkbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115490F8EBD000048CA8D /* checkbox.cpp */; };
+ 92C1154E0F8EBD000048CA8D /* textbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1154B0F8EBD000048CA8D /* textbox.cpp */; };
+ 92C115540F8EBD250048CA8D /* label.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115500F8EBD250048CA8D /* label.cpp */; };
+ 92C115550F8EBD250048CA8D /* progressbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115520F8EBD250048CA8D /* progressbar.cpp */; };
+ 92C115590F8EBD490048CA8D /* net.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115570F8EBD490048CA8D /* net.cpp */; };
+ 92C1159B0F8EBD900048CA8D /* emotedb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115990F8EBD900048CA8D /* emotedb.cpp */; };
+ 92C115A20F8EBDB20048CA8D /* commandhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1159C0F8EBDB20048CA8D /* commandhandler.cpp */; };
+ 92C115A30F8EBDB20048CA8D /* effectmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C1159E0F8EBDB20048CA8D /* effectmanager.cpp */; };
+ 92C115A40F8EBDB20048CA8D /* units.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115A00F8EBDB20048CA8D /* units.cpp */; };
+ 92C115B70F8EBE450048CA8D /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115AD0F8EBE450048CA8D /* palette.cpp */; };
+ 92C115B90F8EBE450048CA8D /* recorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115B10F8EBE450048CA8D /* recorder.cpp */; };
+ 92C115BB0F8EBE450048CA8D /* speechbubble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115B50F8EBE450048CA8D /* speechbubble.cpp */; };
+ 92C115BF0F8EBE5E0048CA8D /* channeltab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115BD0F8EBE5E0048CA8D /* channeltab.cpp */; };
+ 92C115C60F8EBE950048CA8D /* whispertab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115C30F8EBE950048CA8D /* whispertab.cpp */; };
+ 92C115C90F8EBECE0048CA8D /* charcreatedialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115C70F8EBECE0048CA8D /* charcreatedialog.cpp */; };
+ 92C115CD0F8EBF090048CA8D /* channelmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115CB0F8EBF090048CA8D /* channelmanager.cpp */; };
+ 92C115D20F8EBF1C0048CA8D /* colordb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115CE0F8EBF1C0048CA8D /* colordb.cpp */; };
+ 92C115D30F8EBF1C0048CA8D /* wallpaper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115D00F8EBF1C0048CA8D /* wallpaper.cpp */; };
+ 92C115DB0F8EBF530048CA8D /* button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115D50F8EBF530048CA8D /* button.cpp */; };
+ 92C115DC0F8EBF530048CA8D /* icon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115D70F8EBF530048CA8D /* icon.cpp */; };
+ 92C115DD0F8EBF530048CA8D /* radiobutton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115D90F8EBF530048CA8D /* radiobutton.cpp */; };
+ 92C115EA0F8EBFA60048CA8D /* stringutils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115E80F8EBFA60048CA8D /* stringutils.cpp */; };
+ 92C115EE0F8EBFC20048CA8D /* channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115EC0F8EBFC20048CA8D /* channel.cpp */; };
+ 92C115F70F8EBFDD0048CA8D /* dropdown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115F50F8EBFDD0048CA8D /* dropdown.cpp */; };
+ 92C115FB0F8EBFF30048CA8D /* setup_colors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115F90F8EBFF30048CA8D /* setup_colors.cpp */; };
+ 92C115FF0F8EC0150048CA8D /* textpreview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C115FD0F8EC0150048CA8D /* textpreview.cpp */; };
+ 92C636BB0FC5663000EE8D8D /* flooritem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636B30FC5663000EE8D8D /* flooritem.cpp */; };
+ 92C636BC0FC5663000EE8D8D /* playerrelations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636B50FC5663000EE8D8D /* playerrelations.cpp */; };
+ 92C636BD0FC5663000EE8D8D /* rotationalparticle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636B80FC5663000EE8D8D /* rotationalparticle.cpp */; };
+ 92C636BE0FC5663000EE8D8D /* vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636BA0FC5663000EE8D8D /* vector.cpp */; };
+ 92C636D70FC5670700EE8D8D /* charselectdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636C40FC5670700EE8D8D /* charselectdialog.cpp */; };
+ 92C636D80FC5670700EE8D8D /* confirmdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636C60FC5670700EE8D8D /* confirmdialog.cpp */; };
+ 92C636D90FC5670700EE8D8D /* emotepopup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636C80FC5670700EE8D8D /* emotepopup.cpp */; };
+ 92C636DA0FC5670700EE8D8D /* itemamount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636CA0FC5670700EE8D8D /* itemamount.cpp */; };
+ 92C636DB0FC5670700EE8D8D /* npcdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636CC0FC5670700EE8D8D /* npcdialog.cpp */; };
+ 92C636DC0FC5670700EE8D8D /* okdialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636CE0FC5670700EE8D8D /* okdialog.cpp */; };
+ 92C636DD0FC5670700EE8D8D /* outfitwindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636D00FC5670700EE8D8D /* outfitwindow.cpp */; };
+ 92C636DF0FC5670700EE8D8D /* windowmenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92C636D50FC5670700EE8D8D /* windowmenu.cpp */; };
+ 92C6378C0FC5756400EE8D8D /* dejavusans-bold.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 92C637850FC5751700EE8D8D /* dejavusans-bold.ttf */; };
+ 92DD76470F267B3600B2B519 /* layouthelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92DD76450F267B3600B2B519 /* layouthelper.cpp */; };
+ 92EA98B40FC5CB17003DC005 /* SDLMain.nib in Resources */ = {isa = PBXBuildFile; fileRef = 92EA98B30FC5CB17003DC005 /* SDLMain.nib */; };
+ 92EEA0030D2E20B300DDE300 /* libpng.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 9294DAA00C17E73200FCEDE9 /* libpng.framework */; };
+ 92EEA0050D2E20B300DDE300 /* SDL_image.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC408E0BAEE818000DAB7F /* SDL_image.framework */; };
+ 92EEA0060D2E20B300DDE300 /* SDL_mixer.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC408F0BAEE818000DAB7F /* SDL_mixer.framework */; };
+ 92EEA0070D2E20B300DDE300 /* SDL_net.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC40900BAEE818000DAB7F /* SDL_net.framework */; };
+ 92EEA0080D2E20B300DDE300 /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 92BC40910BAEE818000DAB7F /* SDL.framework */; };
+ 92FD19BA0DDCE53400D14E5D /* setup_players.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92FD19B30DDCE53400D14E5D /* setup_players.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 924A3A520C085C190066885E /* Copy Data Files */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = data;
+ dstSubfolderSpec = 7;
+ files = (
+ 924A40570C085EF50066885E /* items.xsd in Copy Data Files */,
+ );
+ name = "Copy Data Files";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 924A3E540C085CAF0066885E /* Copy GUI Files */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = data/graphics/gui;
+ dstSubfolderSpec = 7;
+ files = (
+ 9268560211F142A000A28C33 /* colors.xml in Copy GUI Files */,
+ 9268560311F142A000A28C33 /* progress-indicator.png in Copy GUI Files */,
+ 9268560411F142A000A28C33 /* radioin_highlight.png in Copy GUI Files */,
+ 9268560511F142A000A28C33 /* radioout_highlight.png in Copy GUI Files */,
+ 9268560611F142A000A28C33 /* slider_hilight.png in Copy GUI Files */,
+ 9268560711F142A000A28C33 /* tab_hilight.png in Copy GUI Files */,
+ 9268560811F142A000A28C33 /* vscroll_highlight.png in Copy GUI Files */,
+ 9268560911F142A000A28C33 /* window.xml in Copy GUI Files */,
+ 9268560A11F142A000A28C33 /* window.png in Copy GUI Files */,
+ 9268560B11F142A000A28C33 /* circle-gray.png in Copy GUI Files */,
+ 9268560C11F142A000A28C33 /* circle-green.png in Copy GUI Files */,
+ 9268560D11F142A000A28C33 /* speechbubble.xml in Copy GUI Files */,
+ 9268560E11F142A000A28C33 /* sticky_button.png in Copy GUI Files */,
+ 9268560F11F142A000A28C33 /* bubble.png in Copy GUI Files */,
+ 9268561011F142A000A28C33 /* tab.png in Copy GUI Files */,
+ 9268561111F142A000A28C33 /* tabselected.png in Copy GUI Files */,
+ 9268561211F142A000A28C33 /* close_button.png in Copy GUI Files */,
+ 9268561311F142A000A28C33 /* unknown-item.png in Copy GUI Files */,
+ 9268561411F142A000A28C33 /* item_shortcut_bgr.png in Copy GUI Files */,
+ 9268561511F142A000A28C33 /* button.png in Copy GUI Files */,
+ 9268561611F142A000A28C33 /* button_disabled.png in Copy GUI Files */,
+ 9268561711F142A000A28C33 /* buttonhi.png in Copy GUI Files */,
+ 9268561811F142A000A28C33 /* buttonpress.png in Copy GUI Files */,
+ 9268561911F142A000A28C33 /* checkbox.png in Copy GUI Files */,
+ 9268561A11F142A000A28C33 /* deepbox.png in Copy GUI Files */,
+ 9268561B11F142A000A28C33 /* hscroll_left_default.png in Copy GUI Files */,
+ 9268561C11F142A000A28C33 /* hscroll_left_highlight.png in Copy GUI Files */,
+ 9268561D11F142A000A28C33 /* hscroll_left_pressed.png in Copy GUI Files */,
+ 9268561E11F142A000A28C33 /* hscroll_right_default.png in Copy GUI Files */,
+ 9268561F11F142A000A28C33 /* hscroll_right_highlight.png in Copy GUI Files */,
+ 9268562011F142A000A28C33 /* hscroll_right_pressed.png in Copy GUI Files */,
+ 9268562111F142A000A28C33 /* mouse.png in Copy GUI Files */,
+ 9268562211F142A000A28C33 /* radioin.png in Copy GUI Files */,
+ 9268562311F142A000A28C33 /* radioout.png in Copy GUI Files */,
+ 9268562411F142A000A28C33 /* resize.png in Copy GUI Files */,
+ 9268562511F142A000A28C33 /* selection.png in Copy GUI Files */,
+ 9268562611F142A000A28C33 /* slider.png in Copy GUI Files */,
+ 9268562711F142A000A28C33 /* target-cursor-blue-l.png in Copy GUI Files */,
+ 9268562811F142A000A28C33 /* target-cursor-blue-m.png in Copy GUI Files */,
+ 9268562911F142A000A28C33 /* target-cursor-blue-s.png in Copy GUI Files */,
+ 9268562A11F142A000A28C33 /* target-cursor-red-l.png in Copy GUI Files */,
+ 9268562B11F142A000A28C33 /* target-cursor-red-m.png in Copy GUI Files */,
+ 9268562C11F142A000A28C33 /* target-cursor-red-s.png in Copy GUI Files */,
+ 9268562D11F142A000A28C33 /* vscroll_down_default.png in Copy GUI Files */,
+ 9268562E11F142A000A28C33 /* vscroll_down_highlight.png in Copy GUI Files */,
+ 9268562F11F142A000A28C33 /* vscroll_down_pressed.png in Copy GUI Files */,
+ 9268563011F142A000A28C33 /* vscroll_grey.png in Copy GUI Files */,
+ 9268563111F142A000A28C33 /* vscroll_up_default.png in Copy GUI Files */,
+ 9268563211F142A000A28C33 /* vscroll_up_highlight.png in Copy GUI Files */,
+ 9268563311F142A000A28C33 /* vscroll_up_pressed.png in Copy GUI Files */,
+ );
+ name = "Copy GUI Files";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 924A40880C085FBD0066885E /* Copy Image Files */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = data/graphics/images;
+ dstSubfolderSpec = 7;
+ files = (
+ 924A408B0C0860120066885E /* login_wallpaper.png in Copy Image Files */,
+ );
+ name = "Copy Image Files";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 924A42000C0861C70066885E /* Copy Help Files */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = data/help;
+ dstSubfolderSpec = 7;
+ files = (
+ 926A299C0F23CA27005D6466 /* windows.txt in Copy Help Files */,
+ 924A42020C0861EC0066885E /* about.txt in Copy Help Files */,
+ 924A42030C0861EC0066885E /* changes.txt in Copy Help Files */,
+ 924A42040C0861EC0066885E /* commands.txt in Copy Help Files */,
+ 924A42050C0861EC0066885E /* header.txt in Copy Help Files */,
+ 924A42060C0861EC0066885E /* index.txt in Copy Help Files */,
+ 924A42070C0861EC0066885E /* skills.txt in Copy Help Files */,
+ 924A42080C0861EC0066885E /* support.txt in Copy Help Files */,
+ 924A42090C0861EC0066885E /* team.txt in Copy Help Files */,
+ );
+ name = "Copy Help Files";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 926A29AA0F23CA6D005D6466 /* Copy Font Files */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = data/fonts;
+ dstSubfolderSpec = 7;
+ files = (
+ 92C6378C0FC5756400EE8D8D /* dejavusans-bold.ttf in Copy Font Files */,
+ 926A299E0F23CA5A005D6466 /* dejavusans.ttf in Copy Font Files */,
+ );
+ name = "Copy Font Files";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9273BE3C0EF34050008E56E1 /* Copy Music Files */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = data/music;
+ dstSubfolderSpec = 7;
+ files = (
+ );
+ name = "Copy Music Files";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 92EEA0090D2E20D100DDE300 /* Copy Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 922895C211F6678700AE53BB /* libSDL-1.2.0.dylib in Copy Frameworks */,
+ 922895C111F6678300AE53BB /* libiconv.2.dylib in Copy Frameworks */,
+ 922895BC11F665AF00AE53BB /* libSDL_gfx.13.dylib in Copy Frameworks */,
+ 922895BB11F665AB00AE53BB /* libphysfs.1.dylib in Copy Frameworks */,
+ 922895BA11F665A700AE53BB /* libintl.8.dylib in Copy Frameworks */,
+ 926857B011F15AB200A28C33 /* guichan.framework in Copy Frameworks */,
+ 920C631F0F37D0EF001DD274 /* SDL_ttf.framework in Copy Frameworks */,
+ 92EEA0030D2E20B300DDE300 /* libpng.framework in Copy Frameworks */,
+ 92EEA0050D2E20B300DDE300 /* SDL_image.framework in Copy Frameworks */,
+ 92EEA0060D2E20B300DDE300 /* SDL_mixer.framework in Copy Frameworks */,
+ 92EEA0070D2E20B300DDE300 /* SDL_net.framework in Copy Frameworks */,
+ 92EEA0080D2E20B300DDE300 /* SDL.framework in Copy Frameworks */,
+ );
+ name = "Copy Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
+ 508344B209E5C41E0093A071 /* The Mana World.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "The Mana World.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 92024D2A0CF1BD9E006B55CB /* keyboardconfig.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = keyboardconfig.cpp; path = src/keyboardconfig.cpp; sourceTree = "<group>"; };
+ 92024D2B0CF1BD9E006B55CB /* keyboardconfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = keyboardconfig.h; path = src/keyboardconfig.h; sourceTree = "<group>"; };
+ 92024D2C0CF1BD9E006B55CB /* vector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vector.h; path = src/vector.h; sourceTree = "<group>"; };
+ 92024D360CF1BDF7006B55CB /* setup_keyboard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = setup_keyboard.cpp; sourceTree = "<group>"; };
+ 92024D370CF1BDF7006B55CB /* setup_keyboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_keyboard.h; sourceTree = "<group>"; };
+ 92024D5B0CF1BE5C006B55CB /* close_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = close_button.png; sourceTree = "<group>"; };
+ 92024D5C0CF1BE5C006B55CB /* item_shortcut_bgr.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = item_shortcut_bgr.png; sourceTree = "<group>"; };
+ 92024D5D0CF1BE5C006B55CB /* unknown-item.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unknown-item.png"; sourceTree = "<group>"; };
+ 92024E740CF1DCF6006B55CB /* imageloader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = imageloader.cpp; sourceTree = "<group>"; };
+ 92024E750CF1DCF6006B55CB /* imageloader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = imageloader.h; sourceTree = "<group>"; };
+ 92037A190ED2035A00D3712D /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLMain.h; path = src/SDLMain.h; sourceTree = "<group>"; };
+ 92037A1A0ED2037300D3712D /* particleemitterprop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = particleemitterprop.h; path = src/particleemitterprop.h; sourceTree = "<group>"; };
+ 92037A1B0ED2037300D3712D /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = text.cpp; path = src/text.cpp; sourceTree = "<group>"; };
+ 92037A1C0ED2037300D3712D /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = text.h; path = src/text.h; sourceTree = "<group>"; };
+ 92037A1D0ED2037300D3712D /* textmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = textmanager.cpp; path = src/textmanager.cpp; sourceTree = "<group>"; };
+ 92037A1E0ED2037300D3712D /* textmanager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = textmanager.h; path = src/textmanager.h; sourceTree = "<group>"; };
+ 922895B411F665A200AE53BB /* libintl.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libintl.8.dylib; sourceTree = "<group>"; };
+ 922895B511F665A200AE53BB /* libphysfs.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libphysfs.1.dylib; sourceTree = "<group>"; };
+ 922895B611F665A200AE53BB /* libSDL_gfx.13.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libSDL_gfx.13.dylib; sourceTree = "<group>"; };
+ 922895BF11F6677F00AE53BB /* libiconv.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libiconv.2.dylib; sourceTree = "<group>"; };
+ 922895C011F6677F00AE53BB /* libSDL-1.2.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = "libSDL-1.2.0.dylib"; sourceTree = "<group>"; };
+ 922CD9560E3D00900074C50E /* npcdb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = npcdb.cpp; sourceTree = "<group>"; };
+ 922CD9570E3D00900074C50E /* npcdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = npcdb.h; sourceTree = "<group>"; };
+ 922CD95D0E3D01080074C50E /* shopitem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = shopitem.cpp; path = src/shopitem.cpp; sourceTree = "<group>"; };
+ 922CD95E0E3D01080074C50E /* shopitem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = shopitem.h; path = src/shopitem.h; sourceTree = "<group>"; };
+ 924A39E80C0784280066885E /* animationparticle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = animationparticle.cpp; path = src/animationparticle.cpp; sourceTree = "<group>"; };
+ 924A39E90C0784280066885E /* animationparticle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = animationparticle.h; path = src/animationparticle.h; sourceTree = "<group>"; };
+ 924A39EA0C0784280066885E /* imageparticle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = imageparticle.cpp; path = src/imageparticle.cpp; sourceTree = "<group>"; };
+ 924A39EB0C0784280066885E /* imageparticle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = imageparticle.h; path = src/imageparticle.h; sourceTree = "<group>"; };
+ 924A39EC0C0784280066885E /* particle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = particle.cpp; path = src/particle.cpp; sourceTree = "<group>"; };
+ 924A39ED0C0784280066885E /* particle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = particle.h; path = src/particle.h; sourceTree = "<group>"; };
+ 924A39EE0C0784280066885E /* particleemitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = particleemitter.cpp; path = src/particleemitter.cpp; sourceTree = "<group>"; };
+ 924A39EF0C0784280066885E /* particleemitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = particleemitter.h; path = src/particleemitter.h; sourceTree = "<group>"; };
+ 924A39F00C0784280066885E /* textparticle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = textparticle.cpp; path = src/textparticle.cpp; sourceTree = "<group>"; };
+ 924A39F10C0784280066885E /* textparticle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = textparticle.h; path = src/textparticle.h; sourceTree = "<group>"; };
+ 924A3A100C07A60B0066885E /* resizegrip.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = resizegrip.cpp; sourceTree = "<group>"; };
+ 924A3A110C07A60B0066885E /* resizegrip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = resizegrip.h; sourceTree = "<group>"; };
+ 924A3E620C085ED70066885E /* button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = button.png; sourceTree = "<group>"; };
+ 924A3E630C085ED70066885E /* button_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = button_disabled.png; sourceTree = "<group>"; };
+ 924A3E640C085ED70066885E /* buttonhi.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buttonhi.png; sourceTree = "<group>"; };
+ 924A3E650C085ED70066885E /* buttonpress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buttonpress.png; sourceTree = "<group>"; };
+ 924A3E660C085ED70066885E /* checkbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkbox.png; sourceTree = "<group>"; };
+ 924A3E680C085ED70066885E /* deepbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = deepbox.png; sourceTree = "<group>"; };
+ 924A3E6D0C085ED70066885E /* hscroll_left_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hscroll_left_default.png; sourceTree = "<group>"; };
+ 924A3E6E0C085ED70066885E /* hscroll_left_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hscroll_left_highlight.png; sourceTree = "<group>"; };
+ 924A3E6F0C085ED70066885E /* hscroll_left_pressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hscroll_left_pressed.png; sourceTree = "<group>"; };
+ 924A3E700C085ED70066885E /* hscroll_right_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hscroll_right_default.png; sourceTree = "<group>"; };
+ 924A3E710C085ED70066885E /* hscroll_right_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hscroll_right_highlight.png; sourceTree = "<group>"; };
+ 924A3E720C085ED70066885E /* hscroll_right_pressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hscroll_right_pressed.png; sourceTree = "<group>"; };
+ 924A3E780C085ED70066885E /* mouse.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mouse.png; sourceTree = "<group>"; };
+ 924A3E790C085ED70066885E /* radioin.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = radioin.png; sourceTree = "<group>"; };
+ 924A3E7A0C085ED70066885E /* radioout.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = radioout.png; sourceTree = "<group>"; };
+ 924A3E7B0C085ED70066885E /* resize.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = resize.png; sourceTree = "<group>"; };
+ 924A3E7E0C085ED70066885E /* selection.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = selection.png; sourceTree = "<group>"; };
+ 924A3E7F0C085ED70066885E /* slider.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = slider.png; sourceTree = "<group>"; };
+ 924A3E800C085ED70066885E /* target-cursor-blue-l.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "target-cursor-blue-l.png"; sourceTree = "<group>"; };
+ 924A3E810C085ED70066885E /* target-cursor-blue-m.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "target-cursor-blue-m.png"; sourceTree = "<group>"; };
+ 924A3E820C085ED70066885E /* target-cursor-blue-s.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "target-cursor-blue-s.png"; sourceTree = "<group>"; };
+ 924A3E830C085ED70066885E /* target-cursor-red-l.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "target-cursor-red-l.png"; sourceTree = "<group>"; };
+ 924A3E840C085ED70066885E /* target-cursor-red-m.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "target-cursor-red-m.png"; sourceTree = "<group>"; };
+ 924A3E850C085ED70066885E /* target-cursor-red-s.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "target-cursor-red-s.png"; sourceTree = "<group>"; };
+ 924A3E880C085ED70066885E /* vscroll_down_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_down_default.png; sourceTree = "<group>"; };
+ 924A3E890C085ED70066885E /* vscroll_down_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_down_highlight.png; sourceTree = "<group>"; };
+ 924A3E8A0C085ED70066885E /* vscroll_down_pressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_down_pressed.png; sourceTree = "<group>"; };
+ 924A3E8B0C085ED70066885E /* vscroll_grey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_grey.png; sourceTree = "<group>"; };
+ 924A3E8D0C085ED70066885E /* vscroll_up_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_up_default.png; sourceTree = "<group>"; };
+ 924A3E8E0C085ED70066885E /* vscroll_up_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_up_highlight.png; sourceTree = "<group>"; };
+ 924A3E8F0C085ED70066885E /* vscroll_up_pressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_up_pressed.png; sourceTree = "<group>"; };
+ 924A3E9A0C085ED70066885E /* login_wallpaper.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = login_wallpaper.png; sourceTree = "<group>"; };
+ 924A400A0C085ED80066885E /* about.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = about.txt; sourceTree = "<group>"; };
+ 924A400B0C085ED80066885E /* changes.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = changes.txt; sourceTree = "<group>"; };
+ 924A400D0C085ED80066885E /* commands.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = commands.txt; sourceTree = "<group>"; };
+ 924A400E0C085ED80066885E /* header.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = header.txt; sourceTree = "<group>"; };
+ 924A400F0C085ED80066885E /* index.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = index.txt; sourceTree = "<group>"; };
+ 924A40110C085ED80066885E /* skills.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = skills.txt; sourceTree = "<group>"; };
+ 924A40120C085ED80066885E /* support.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = support.txt; sourceTree = "<group>"; };
+ 924A40130C085ED80066885E /* team.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = team.txt; sourceTree = "<group>"; };
+ 924A401C0C085ED80066885E /* items.xsd */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = items.xsd; sourceTree = "<group>"; };
+ 924A42600C0874D00066885E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 925350010BC12A3200115FD5 /* imageset.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = imageset.cpp; sourceTree = "<group>"; };
+ 925350020BC12A3200115FD5 /* imageset.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = imageset.h; sourceTree = "<group>"; };
+ 926855E711F141D500A28C33 /* colors.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = colors.xml; sourceTree = "<group>"; };
+ 926855E811F141D500A28C33 /* progress-indicator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "progress-indicator.png"; sourceTree = "<group>"; };
+ 926855E911F141D500A28C33 /* radioin_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = radioin_highlight.png; sourceTree = "<group>"; };
+ 926855EA11F141D500A28C33 /* radioout_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = radioout_highlight.png; sourceTree = "<group>"; };
+ 926855EB11F141D500A28C33 /* slider_hilight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = slider_hilight.png; sourceTree = "<group>"; };
+ 926855EC11F141D500A28C33 /* tab_hilight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab_hilight.png; sourceTree = "<group>"; };
+ 926855ED11F141D500A28C33 /* vscroll_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vscroll_highlight.png; sourceTree = "<group>"; };
+ 926855EE11F141D500A28C33 /* window.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = window.xml; sourceTree = "<group>"; };
+ 926855FF11F141FD00A28C33 /* mana.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = mana.icns; sourceTree = "<group>"; };
+ 9268564B11F142D500A28C33 /* avatar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = avatar.cpp; path = src/avatar.cpp; sourceTree = "<group>"; };
+ 9268564C11F142D500A28C33 /* avatar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = avatar.h; path = src/avatar.h; sourceTree = "<group>"; };
+ 9268564D11F142D500A28C33 /* client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = client.cpp; path = src/client.cpp; sourceTree = "<group>"; };
+ 9268564E11F142D500A28C33 /* client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = client.h; path = src/client.h; sourceTree = "<group>"; };
+ 9268564F11F142D500A28C33 /* party.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = party.cpp; path = src/party.cpp; sourceTree = "<group>"; };
+ 9268565011F142D500A28C33 /* party.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = party.h; path = src/party.h; sourceTree = "<group>"; };
+ 9268565111F142D500A28C33 /* textrenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = textrenderer.h; path = src/textrenderer.h; sourceTree = "<group>"; };
+ 9268565811F142F100A28C33 /* beingpopup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = beingpopup.cpp; sourceTree = "<group>"; };
+ 9268565911F142F100A28C33 /* beingpopup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = beingpopup.h; sourceTree = "<group>"; };
+ 9268565A11F142F100A28C33 /* connectiondialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = connectiondialog.cpp; sourceTree = "<group>"; };
+ 9268565B11F142F100A28C33 /* connectiondialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = connectiondialog.h; sourceTree = "<group>"; };
+ 9268565C11F142F100A28C33 /* socialwindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = socialwindow.cpp; sourceTree = "<group>"; };
+ 9268565D11F142F100A28C33 /* socialwindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socialwindow.h; sourceTree = "<group>"; };
+ 9268565E11F142F100A28C33 /* specialswindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = specialswindow.cpp; sourceTree = "<group>"; };
+ 9268565F11F142F100A28C33 /* specialswindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = specialswindow.h; sourceTree = "<group>"; };
+ 9268566011F142F100A28C33 /* textpopup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textpopup.cpp; sourceTree = "<group>"; };
+ 9268566111F142F100A28C33 /* textpopup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textpopup.h; sourceTree = "<group>"; };
+ 9268566211F142F100A28C33 /* theme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = theme.cpp; sourceTree = "<group>"; };
+ 9268566311F142F100A28C33 /* theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = theme.h; sourceTree = "<group>"; };
+ 9268566411F142F100A28C33 /* userpalette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = userpalette.cpp; sourceTree = "<group>"; };
+ 9268566511F142F100A28C33 /* userpalette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = userpalette.h; sourceTree = "<group>"; };
+ 9268566611F142F100A28C33 /* worldselectdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = worldselectdialog.cpp; sourceTree = "<group>"; };
+ 9268566711F142F100A28C33 /* worldselectdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = worldselectdialog.h; sourceTree = "<group>"; };
+ 9268567811F1431300A28C33 /* avatarlistbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = avatarlistbox.cpp; sourceTree = "<group>"; };
+ 9268567911F1431300A28C33 /* avatarlistbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avatarlistbox.h; sourceTree = "<group>"; };
+ 9268567A11F1431300A28C33 /* emoteshortcutcontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = emoteshortcutcontainer.cpp; sourceTree = "<group>"; };
+ 9268567B11F1431300A28C33 /* emoteshortcutcontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emoteshortcutcontainer.h; sourceTree = "<group>"; };
+ 9268567C11F1431300A28C33 /* flowcontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = flowcontainer.cpp; sourceTree = "<group>"; };
+ 9268567D11F1431300A28C33 /* flowcontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flowcontainer.h; sourceTree = "<group>"; };
+ 9268567E11F1431300A28C33 /* itemcontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itemcontainer.cpp; sourceTree = "<group>"; };
+ 9268567F11F1431300A28C33 /* itemcontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itemcontainer.h; sourceTree = "<group>"; };
+ 9268568011F1431300A28C33 /* itemlinkhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itemlinkhandler.cpp; sourceTree = "<group>"; };
+ 9268568111F1431300A28C33 /* itemlinkhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itemlinkhandler.h; sourceTree = "<group>"; };
+ 9268568211F1431300A28C33 /* itemshortcutcontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itemshortcutcontainer.cpp; sourceTree = "<group>"; };
+ 9268568311F1431300A28C33 /* itemshortcutcontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itemshortcutcontainer.h; sourceTree = "<group>"; };
+ 9268568411F1431300A28C33 /* linkhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linkhandler.h; sourceTree = "<group>"; };
+ 9268568511F1431300A28C33 /* playerbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = playerbox.cpp; sourceTree = "<group>"; };
+ 9268568611F1431300A28C33 /* playerbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = playerbox.h; sourceTree = "<group>"; };
+ 9268568711F1431300A28C33 /* progressindicator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = progressindicator.cpp; sourceTree = "<group>"; };
+ 9268568811F1431300A28C33 /* progressindicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = progressindicator.h; sourceTree = "<group>"; };
+ 9268568911F1431300A28C33 /* setuptab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = setuptab.cpp; sourceTree = "<group>"; };
+ 9268568A11F1431300A28C33 /* setuptab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = setuptab.h; sourceTree = "<group>"; };
+ 9268568B11F1431300A28C33 /* shopitems.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shopitems.cpp; sourceTree = "<group>"; };
+ 9268568C11F1431300A28C33 /* shopitems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shopitems.h; sourceTree = "<group>"; };
+ 9268568D11F1431300A28C33 /* shoplistbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shoplistbox.cpp; sourceTree = "<group>"; };
+ 9268568E11F1431300A28C33 /* shoplistbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shoplistbox.h; sourceTree = "<group>"; };
+ 9268568F11F1431300A28C33 /* shortcutcontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shortcutcontainer.cpp; sourceTree = "<group>"; };
+ 9268569011F1431300A28C33 /* shortcutcontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shortcutcontainer.h; sourceTree = "<group>"; };
+ 9268569111F1431300A28C33 /* table.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table.cpp; sourceTree = "<group>"; };
+ 9268569211F1431300A28C33 /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = "<group>"; };
+ 9268569311F1431300A28C33 /* tablemodel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tablemodel.cpp; sourceTree = "<group>"; };
+ 9268569411F1431300A28C33 /* tablemodel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tablemodel.h; sourceTree = "<group>"; };
+ 9268569511F1431300A28C33 /* vertcontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vertcontainer.cpp; sourceTree = "<group>"; };
+ 9268569611F1431300A28C33 /* vertcontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vertcontainer.h; sourceTree = "<group>"; };
+ 926856B511F1433300A28C33 /* charhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charhandler.cpp; sourceTree = "<group>"; };
+ 926856B611F1433300A28C33 /* download.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = download.cpp; sourceTree = "<group>"; };
+ 926856B711F1433300A28C33 /* download.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = download.h; sourceTree = "<group>"; };
+ 926856B811F1433300A28C33 /* gamehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gamehandler.h; sourceTree = "<group>"; };
+ 926856B911F1433300A28C33 /* specialhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = specialhandler.h; sourceTree = "<group>"; };
+ 926856BA11F1433300A28C33 /* worldinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = worldinfo.h; sourceTree = "<group>"; };
+ 926856C011F1433E00A28C33 /* adminhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adminhandler.cpp; sourceTree = "<group>"; };
+ 926856C111F1433E00A28C33 /* adminhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adminhandler.h; sourceTree = "<group>"; };
+ 926856C211F1433E00A28C33 /* beinghandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = beinghandler.cpp; sourceTree = "<group>"; };
+ 926856C311F1433E00A28C33 /* beinghandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = beinghandler.h; sourceTree = "<group>"; };
+ 926856C411F1433E00A28C33 /* buysellhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = buysellhandler.cpp; sourceTree = "<group>"; };
+ 926856C511F1433E00A28C33 /* buysellhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buysellhandler.h; sourceTree = "<group>"; };
+ 926856C611F1433E00A28C33 /* charhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charhandler.cpp; sourceTree = "<group>"; };
+ 926856C711F1433E00A28C33 /* charhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charhandler.h; sourceTree = "<group>"; };
+ 926856C811F1433E00A28C33 /* chathandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chathandler.cpp; sourceTree = "<group>"; };
+ 926856C911F1433E00A28C33 /* chathandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chathandler.h; sourceTree = "<group>"; };
+ 926856CA11F1433E00A28C33 /* connection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = connection.cpp; sourceTree = "<group>"; };
+ 926856CB11F1433E00A28C33 /* connection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = connection.h; sourceTree = "<group>"; };
+ 926856CC11F1433E00A28C33 /* effecthandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = effecthandler.cpp; sourceTree = "<group>"; };
+ 926856CD11F1433E00A28C33 /* effecthandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = effecthandler.h; sourceTree = "<group>"; };
+ 926856CE11F1433E00A28C33 /* gamehandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gamehandler.cpp; sourceTree = "<group>"; };
+ 926856CF11F1433E00A28C33 /* gamehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gamehandler.h; sourceTree = "<group>"; };
+ 926856D011F1433E00A28C33 /* generalhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = generalhandler.cpp; sourceTree = "<group>"; };
+ 926856D111F1433E00A28C33 /* generalhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = generalhandler.h; sourceTree = "<group>"; };
+ 926856D211F1433E00A28C33 /* guildhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guildhandler.cpp; sourceTree = "<group>"; };
+ 926856D311F1433E00A28C33 /* guildhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guildhandler.h; sourceTree = "<group>"; };
+ 926856D411F1433E00A28C33 /* internal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = internal.cpp; sourceTree = "<group>"; };
+ 926856D511F1433E00A28C33 /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
+ 926856D611F1433E00A28C33 /* inventoryhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inventoryhandler.cpp; sourceTree = "<group>"; };
+ 926856D711F1433E00A28C33 /* inventoryhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inventoryhandler.h; sourceTree = "<group>"; };
+ 926856D811F1433E00A28C33 /* itemhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itemhandler.cpp; sourceTree = "<group>"; };
+ 926856D911F1433E00A28C33 /* itemhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itemhandler.h; sourceTree = "<group>"; };
+ 926856DA11F1433E00A28C33 /* loginhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loginhandler.cpp; sourceTree = "<group>"; };
+ 926856DB11F1433E00A28C33 /* loginhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = loginhandler.h; sourceTree = "<group>"; };
+ 926856DC11F1433E00A28C33 /* messagehandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messagehandler.cpp; sourceTree = "<group>"; };
+ 926856DD11F1433E00A28C33 /* messagehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messagehandler.h; sourceTree = "<group>"; };
+ 926856DE11F1433E00A28C33 /* messagein.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messagein.cpp; sourceTree = "<group>"; };
+ 926856DF11F1433E00A28C33 /* messagein.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messagein.h; sourceTree = "<group>"; };
+ 926856E011F1433E00A28C33 /* messageout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messageout.cpp; sourceTree = "<group>"; };
+ 926856E111F1433E00A28C33 /* messageout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messageout.h; sourceTree = "<group>"; };
+ 926856E211F1433E00A28C33 /* network.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = network.cpp; sourceTree = "<group>"; };
+ 926856E311F1433E00A28C33 /* network.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = network.h; sourceTree = "<group>"; };
+ 926856E411F1433E00A28C33 /* npchandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = npchandler.cpp; sourceTree = "<group>"; };
+ 926856E511F1433E00A28C33 /* npchandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = npchandler.h; sourceTree = "<group>"; };
+ 926856E611F1433E00A28C33 /* partyhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = partyhandler.cpp; sourceTree = "<group>"; };
+ 926856E711F1433E00A28C33 /* partyhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = partyhandler.h; sourceTree = "<group>"; };
+ 926856E811F1433E00A28C33 /* playerhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = playerhandler.cpp; sourceTree = "<group>"; };
+ 926856E911F1433E00A28C33 /* playerhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = playerhandler.h; sourceTree = "<group>"; };
+ 926856EA11F1433E00A28C33 /* protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = "<group>"; };
+ 926856EB11F1433E00A28C33 /* specialhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = specialhandler.cpp; sourceTree = "<group>"; };
+ 926856EC11F1433E00A28C33 /* specialhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = specialhandler.h; sourceTree = "<group>"; };
+ 926856ED11F1433E00A28C33 /* stats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stats.cpp; sourceTree = "<group>"; };
+ 926856EE11F1433E00A28C33 /* stats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stats.h; sourceTree = "<group>"; };
+ 926856EF11F1433E00A28C33 /* tradehandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tradehandler.cpp; sourceTree = "<group>"; };
+ 926856F011F1433E00A28C33 /* tradehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tradehandler.h; sourceTree = "<group>"; };
+ 926856F211F1433E00A28C33 /* adminhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adminhandler.cpp; sourceTree = "<group>"; };
+ 926856F311F1433E00A28C33 /* adminhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adminhandler.h; sourceTree = "<group>"; };
+ 926856F411F1433E00A28C33 /* beinghandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = beinghandler.cpp; sourceTree = "<group>"; };
+ 926856F511F1433E00A28C33 /* beinghandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = beinghandler.h; sourceTree = "<group>"; };
+ 926856F611F1433E00A28C33 /* buysellhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = buysellhandler.cpp; sourceTree = "<group>"; };
+ 926856F711F1433E00A28C33 /* buysellhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buysellhandler.h; sourceTree = "<group>"; };
+ 926856F811F1433E00A28C33 /* charserverhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charserverhandler.cpp; sourceTree = "<group>"; };
+ 926856F911F1433E00A28C33 /* charserverhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charserverhandler.h; sourceTree = "<group>"; };
+ 926856FA11F1433F00A28C33 /* chathandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chathandler.cpp; sourceTree = "<group>"; };
+ 926856FB11F1433F00A28C33 /* chathandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chathandler.h; sourceTree = "<group>"; };
+ 926856FC11F1433F00A28C33 /* gamehandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gamehandler.cpp; sourceTree = "<group>"; };
+ 926856FD11F1433F00A28C33 /* gamehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gamehandler.h; sourceTree = "<group>"; };
+ 926856FE11F1433F00A28C33 /* generalhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = generalhandler.cpp; sourceTree = "<group>"; };
+ 926856FF11F1433F00A28C33 /* generalhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = generalhandler.h; sourceTree = "<group>"; };
+ 9268570111F1433F00A28C33 /* guildtab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guildtab.cpp; sourceTree = "<group>"; };
+ 9268570211F1433F00A28C33 /* guildtab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guildtab.h; sourceTree = "<group>"; };
+ 9268570311F1433F00A28C33 /* partytab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = partytab.cpp; sourceTree = "<group>"; };
+ 9268570411F1433F00A28C33 /* partytab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = partytab.h; sourceTree = "<group>"; };
+ 9268570511F1433F00A28C33 /* guildhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guildhandler.cpp; sourceTree = "<group>"; };
+ 9268570611F1433F00A28C33 /* guildhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guildhandler.h; sourceTree = "<group>"; };
+ 9268570711F1433F00A28C33 /* inventoryhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inventoryhandler.cpp; sourceTree = "<group>"; };
+ 9268570811F1433F00A28C33 /* inventoryhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inventoryhandler.h; sourceTree = "<group>"; };
+ 9268570911F1433F00A28C33 /* itemhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itemhandler.cpp; sourceTree = "<group>"; };
+ 9268570A11F1433F00A28C33 /* itemhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itemhandler.h; sourceTree = "<group>"; };
+ 9268570B11F1433F00A28C33 /* loginhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loginhandler.cpp; sourceTree = "<group>"; };
+ 9268570C11F1433F00A28C33 /* loginhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = loginhandler.h; sourceTree = "<group>"; };
+ 9268570D11F1433F00A28C33 /* messagehandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messagehandler.cpp; sourceTree = "<group>"; };
+ 9268570E11F1433F00A28C33 /* messagehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messagehandler.h; sourceTree = "<group>"; };
+ 9268570F11F1433F00A28C33 /* messagein.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messagein.cpp; sourceTree = "<group>"; };
+ 9268571011F1433F00A28C33 /* messagein.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messagein.h; sourceTree = "<group>"; };
+ 9268571111F1433F00A28C33 /* messageout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messageout.cpp; sourceTree = "<group>"; };
+ 9268571211F1433F00A28C33 /* messageout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messageout.h; sourceTree = "<group>"; };
+ 9268571311F1433F00A28C33 /* network.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = network.cpp; sourceTree = "<group>"; };
+ 9268571411F1433F00A28C33 /* network.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = network.h; sourceTree = "<group>"; };
+ 9268571511F1433F00A28C33 /* npchandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = npchandler.cpp; sourceTree = "<group>"; };
+ 9268571611F1433F00A28C33 /* npchandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = npchandler.h; sourceTree = "<group>"; };
+ 9268571711F1433F00A28C33 /* partyhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = partyhandler.cpp; sourceTree = "<group>"; };
+ 9268571811F1433F00A28C33 /* partyhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = partyhandler.h; sourceTree = "<group>"; };
+ 9268571911F1433F00A28C33 /* playerhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = playerhandler.cpp; sourceTree = "<group>"; };
+ 9268571A11F1433F00A28C33 /* playerhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = playerhandler.h; sourceTree = "<group>"; };
+ 9268571B11F1433F00A28C33 /* protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = "<group>"; };
+ 9268571C11F1433F00A28C33 /* specialhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = specialhandler.cpp; sourceTree = "<group>"; };
+ 9268571D11F1433F00A28C33 /* specialhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = specialhandler.h; sourceTree = "<group>"; };
+ 9268571E11F1433F00A28C33 /* token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = token.h; sourceTree = "<group>"; };
+ 9268571F11F1433F00A28C33 /* tradehandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tradehandler.cpp; sourceTree = "<group>"; };
+ 9268572011F1433F00A28C33 /* tradehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tradehandler.h; sourceTree = "<group>"; };
+ 9268577D11F1435200A28C33 /* ambientlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ambientlayer.cpp; sourceTree = "<group>"; };
+ 9268577E11F1435200A28C33 /* ambientlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ambientlayer.h; sourceTree = "<group>"; };
+ 9268578111F1435F00A28C33 /* copynpaste.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = copynpaste.cpp; sourceTree = "<group>"; };
+ 9268578211F1435F00A28C33 /* copynpaste.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = copynpaste.h; sourceTree = "<group>"; };
+ 9268578311F1435F00A28C33 /* mkdir.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mkdir.cpp; sourceTree = "<group>"; };
+ 9268578411F1435F00A28C33 /* mkdir.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mkdir.h; sourceTree = "<group>"; };
+ 9268578511F1435F00A28C33 /* specialfolder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = specialfolder.cpp; sourceTree = "<group>"; };
+ 9268578611F1435F00A28C33 /* specialfolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = specialfolder.h; sourceTree = "<group>"; };
+ 926857AB11F15A9300A28C33 /* guichan.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = guichan.framework; path = /Library/Frameworks/guichan.framework; sourceTree = "<absolute>"; };
+ 926A29440F23BD88005D6466 /* layout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layout.cpp; sourceTree = "<group>"; };
+ 926A29450F23BD88005D6466 /* layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layout.h; sourceTree = "<group>"; };
+ 926A29460F23BD88005D6466 /* tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tab.cpp; sourceTree = "<group>"; };
+ 926A29470F23BD88005D6466 /* tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tab.h; sourceTree = "<group>"; };
+ 926A29480F23BD88005D6466 /* tabbedarea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tabbedarea.cpp; sourceTree = "<group>"; };
+ 926A29490F23BD88005D6466 /* tabbedarea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tabbedarea.h; sourceTree = "<group>"; };
+ 926A29520F23BD9E005D6466 /* sdlinput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sdlinput.cpp; sourceTree = "<group>"; };
+ 926A29530F23BD9E005D6466 /* sdlinput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sdlinput.h; sourceTree = "<group>"; };
+ 926A29540F23BD9E005D6466 /* truetypefont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = truetypefont.cpp; sourceTree = "<group>"; };
+ 926A29550F23BD9E005D6466 /* truetypefont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = truetypefont.h; sourceTree = "<group>"; };
+ 926A295A0F23BDB1005D6466 /* gettext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gettext.h; sourceTree = "<group>"; };
+ 926A295B0F23BDB1005D6466 /* mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mutex.h; sourceTree = "<group>"; };
+ 926A29790F23C155005D6466 /* SDL_ttf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_ttf.framework; path = /Library/Frameworks/SDL_ttf.framework; sourceTree = "<absolute>"; };
+ 926A297E0F23C18E005D6466 /* tab.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab.png; sourceTree = "<group>"; };
+ 926A297F0F23C18E005D6466 /* tabselected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tabselected.png; sourceTree = "<group>"; };
+ 926A29840F23C1C8005D6466 /* windows.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = windows.txt; sourceTree = "<group>"; };
+ 926A29980F23C988005D6466 /* dejavusans.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = dejavusans.ttf; path = fonts/dejavusans.ttf; sourceTree = "<group>"; };
+ 926F9CF60DB005FA00AACD26 /* itemshortcut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = itemshortcut.cpp; path = src/itemshortcut.cpp; sourceTree = "<group>"; };
+ 926F9CF70DB005FA00AACD26 /* itemshortcut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = itemshortcut.h; path = src/itemshortcut.h; sourceTree = "<group>"; };
+ 9273BDFB0EF33DFD008E56E1 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYING; sourceTree = "<group>"; };
+ 9273BDFD0EF33E1A008E56E1 /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS; sourceTree = "<group>"; };
+ 9273BDFE0EF33E1A008E56E1 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+ 9273BE040EF33FB3008E56E1 /* particlecontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = particlecontainer.cpp; path = src/particlecontainer.cpp; sourceTree = "<group>"; };
+ 9273BE050EF33FB3008E56E1 /* particlecontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = particlecontainer.h; path = src/particlecontainer.h; sourceTree = "<group>"; };
+ 9273BE060EF33FB3008E56E1 /* statuseffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = statuseffect.cpp; path = src/statuseffect.cpp; sourceTree = "<group>"; };
+ 9273BE070EF33FB3008E56E1 /* statuseffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = statuseffect.h; path = src/statuseffect.h; sourceTree = "<group>"; };
+ 928B50E40F2FB5430011C755 /* bubble.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bubble.png; sourceTree = "<group>"; };
+ 9294DAA00C17E73200FCEDE9 /* libpng.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libpng.framework; path = /Library/Frameworks/libpng.framework; sourceTree = "<absolute>"; };
+ 92A244B50F935FB400B7719B /* container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = container.cpp; sourceTree = "<group>"; };
+ 92A244B60F935FB400B7719B /* container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = container.h; sourceTree = "<group>"; };
+ 92A245C20F93626900B7719B /* desktop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = desktop.cpp; sourceTree = "<group>"; };
+ 92A245C30F93626900B7719B /* desktop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = desktop.h; sourceTree = "<group>"; };
+ 92A4CC9D0D1C622E00CA28FB /* dye.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dye.cpp; sourceTree = "<group>"; };
+ 92BC3ECA0BAEE55A000DAB7F /* animatedsprite.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = animatedsprite.cpp; path = src/animatedsprite.cpp; sourceTree = "<group>"; };
+ 92BC3ECB0BAEE55A000DAB7F /* animatedsprite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = animatedsprite.h; path = src/animatedsprite.h; sourceTree = "<group>"; };
+ 92BC3ECC0BAEE55A000DAB7F /* being.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = being.cpp; path = src/being.cpp; sourceTree = "<group>"; };
+ 92BC3ECD0BAEE55A000DAB7F /* being.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = being.h; path = src/being.h; sourceTree = "<group>"; };
+ 92BC3ECE0BAEE55A000DAB7F /* beingmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = beingmanager.cpp; path = src/beingmanager.cpp; sourceTree = "<group>"; };
+ 92BC3ECF0BAEE55A000DAB7F /* beingmanager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = beingmanager.h; path = src/beingmanager.h; sourceTree = "<group>"; };
+ 92BC3ED10BAEE55A000DAB7F /* configlistener.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = configlistener.h; path = src/configlistener.h; sourceTree = "<group>"; };
+ 92BC3ED20BAEE55A000DAB7F /* configuration.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = configuration.cpp; path = src/configuration.cpp; sourceTree = "<group>"; };
+ 92BC3ED30BAEE55A000DAB7F /* configuration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = configuration.h; path = src/configuration.h; sourceTree = "<group>"; };
+ 92BC3EE70BAEE55A000DAB7F /* equipment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = equipment.h; path = src/equipment.h; sourceTree = "<group>"; };
+ 92BC3EEA0BAEE55A000DAB7F /* flooritemmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = flooritemmanager.cpp; path = src/flooritemmanager.cpp; sourceTree = "<group>"; };
+ 92BC3EEB0BAEE55A000DAB7F /* flooritemmanager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = flooritemmanager.h; path = src/flooritemmanager.h; sourceTree = "<group>"; };
+ 92BC3EEC0BAEE55A000DAB7F /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = game.cpp; path = src/game.cpp; sourceTree = "<group>"; };
+ 92BC3EED0BAEE55A000DAB7F /* game.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = game.h; path = src/game.h; sourceTree = "<group>"; };
+ 92BC3EEE0BAEE55A000DAB7F /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = graphics.cpp; path = src/graphics.cpp; sourceTree = "<group>"; };
+ 92BC3EEF0BAEE55A000DAB7F /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = graphics.h; path = src/graphics.h; sourceTree = "<group>"; };
+ 92BC3EF90BAEE55A000DAB7F /* buy.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = buy.cpp; sourceTree = "<group>"; };
+ 92BC3EFA0BAEE55A000DAB7F /* buy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = buy.h; sourceTree = "<group>"; };
+ 92BC3EFB0BAEE55A000DAB7F /* buysell.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = buysell.cpp; sourceTree = "<group>"; };
+ 92BC3EFC0BAEE55A000DAB7F /* buysell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = buysell.h; sourceTree = "<group>"; };
+ 92BC3F030BAEE55A000DAB7F /* chat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = chat.cpp; sourceTree = "<group>"; };
+ 92BC3F040BAEE55A000DAB7F /* chat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = chat.h; sourceTree = "<group>"; };
+ 92BC3F0D0BAEE55A000DAB7F /* debugwindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = debugwindow.cpp; sourceTree = "<group>"; };
+ 92BC3F0E0BAEE55A000DAB7F /* debugwindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = debugwindow.h; sourceTree = "<group>"; };
+ 92BC3F0F0BAEE55A000DAB7F /* equipmentwindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = equipmentwindow.cpp; sourceTree = "<group>"; };
+ 92BC3F100BAEE55A000DAB7F /* equipmentwindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = equipmentwindow.h; sourceTree = "<group>"; };
+ 92BC3F110BAEE55A000DAB7F /* focushandler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = focushandler.cpp; sourceTree = "<group>"; };
+ 92BC3F120BAEE55A000DAB7F /* focushandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = focushandler.h; sourceTree = "<group>"; };
+ 92BC3F150BAEE55A000DAB7F /* gui.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = gui.cpp; sourceTree = "<group>"; };
+ 92BC3F160BAEE55A000DAB7F /* gui.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gui.h; sourceTree = "<group>"; };
+ 92BC3F190BAEE55A000DAB7F /* help.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = help.cpp; sourceTree = "<group>"; };
+ 92BC3F1A0BAEE55A000DAB7F /* help.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = help.h; sourceTree = "<group>"; };
+ 92BC3F1D0BAEE55A000DAB7F /* inventorywindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = inventorywindow.cpp; sourceTree = "<group>"; };
+ 92BC3F1E0BAEE55A000DAB7F /* inventorywindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = inventorywindow.h; sourceTree = "<group>"; };
+ 92BC3F260BAEE55A000DAB7F /* login.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = login.cpp; sourceTree = "<group>"; };
+ 92BC3F270BAEE55A000DAB7F /* login.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = login.h; sourceTree = "<group>"; };
+ 92BC3F2A0BAEE55A000DAB7F /* minimap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = minimap.cpp; sourceTree = "<group>"; };
+ 92BC3F2B0BAEE55A000DAB7F /* minimap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minimap.h; sourceTree = "<group>"; };
+ 92BC3F2C0BAEE55A000DAB7F /* ministatus.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ministatus.cpp; sourceTree = "<group>"; };
+ 92BC3F2D0BAEE55A000DAB7F /* ministatus.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ministatus.h; sourceTree = "<group>"; };
+ 92BC3F3A0BAEE55A000DAB7F /* popupmenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = popupmenu.cpp; sourceTree = "<group>"; };
+ 92BC3F3B0BAEE55A000DAB7F /* popupmenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = popupmenu.h; sourceTree = "<group>"; };
+ 92BC3F400BAEE55A000DAB7F /* register.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = register.cpp; sourceTree = "<group>"; };
+ 92BC3F410BAEE55A000DAB7F /* register.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = register.h; sourceTree = "<group>"; };
+ 92BC3F450BAEE55A000DAB7F /* sell.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sell.cpp; sourceTree = "<group>"; };
+ 92BC3F460BAEE55A000DAB7F /* sell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sell.h; sourceTree = "<group>"; };
+ 92BC3F470BAEE55A000DAB7F /* setup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = setup.cpp; sourceTree = "<group>"; };
+ 92BC3F480BAEE55A000DAB7F /* setup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup.h; sourceTree = "<group>"; };
+ 92BC3F490BAEE55A000DAB7F /* setup_audio.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = setup_audio.cpp; sourceTree = "<group>"; };
+ 92BC3F4A0BAEE55A000DAB7F /* setup_audio.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_audio.h; sourceTree = "<group>"; };
+ 92BC3F4B0BAEE55A000DAB7F /* setup_joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = setup_joystick.cpp; sourceTree = "<group>"; };
+ 92BC3F4C0BAEE55A000DAB7F /* setup_joystick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_joystick.h; sourceTree = "<group>"; };
+ 92BC3F4D0BAEE55A000DAB7F /* setup_video.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = setup_video.cpp; sourceTree = "<group>"; };
+ 92BC3F4E0BAEE55A000DAB7F /* setup_video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_video.h; sourceTree = "<group>"; };
+ 92BC3F600BAEE55B000DAB7F /* trade.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = trade.cpp; sourceTree = "<group>"; };
+ 92BC3F610BAEE55B000DAB7F /* trade.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = trade.h; sourceTree = "<group>"; };
+ 92BC3F620BAEE55B000DAB7F /* updatewindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = updatewindow.cpp; sourceTree = "<group>"; };
+ 92BC3F630BAEE55B000DAB7F /* updatewindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = updatewindow.h; sourceTree = "<group>"; };
+ 92BC3F660BAEE55B000DAB7F /* viewport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = viewport.cpp; sourceTree = "<group>"; };
+ 92BC3F670BAEE55B000DAB7F /* viewport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = viewport.h; sourceTree = "<group>"; };
+ 92BC3F6C0BAEE55B000DAB7F /* guichanfwd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = guichanfwd.h; path = src/guichanfwd.h; sourceTree = "<group>"; };
+ 92BC3F6D0BAEE55B000DAB7F /* inventory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = inventory.cpp; path = src/inventory.cpp; sourceTree = "<group>"; };
+ 92BC3F6E0BAEE55B000DAB7F /* inventory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inventory.h; path = src/inventory.h; sourceTree = "<group>"; };
+ 92BC3F6F0BAEE55B000DAB7F /* item.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = item.cpp; path = src/item.cpp; sourceTree = "<group>"; };
+ 92BC3F700BAEE55B000DAB7F /* item.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = item.h; path = src/item.h; sourceTree = "<group>"; };
+ 92BC3F710BAEE55B000DAB7F /* joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = joystick.cpp; path = src/joystick.cpp; sourceTree = "<group>"; };
+ 92BC3F720BAEE55B000DAB7F /* joystick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = joystick.h; path = src/joystick.h; sourceTree = "<group>"; };
+ 92BC3F730BAEE55B000DAB7F /* localplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = localplayer.cpp; path = src/localplayer.cpp; sourceTree = "<group>"; };
+ 92BC3F740BAEE55B000DAB7F /* localplayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = localplayer.h; path = src/localplayer.h; sourceTree = "<group>"; };
+ 92BC3F760BAEE55B000DAB7F /* log.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = log.cpp; path = src/log.cpp; sourceTree = "<group>"; };
+ 92BC3F770BAEE55B000DAB7F /* log.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = log.h; path = src/log.h; sourceTree = "<group>"; };
+ 92BC3F790BAEE55B000DAB7F /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = src/main.cpp; sourceTree = "<group>"; };
+ 92BC3F7A0BAEE55B000DAB7F /* main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = main.h; path = src/main.h; sourceTree = "<group>"; };
+ 92BC3F7C0BAEE55B000DAB7F /* map.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = map.cpp; path = src/map.cpp; sourceTree = "<group>"; };
+ 92BC3F7D0BAEE55B000DAB7F /* map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = map.h; path = src/map.h; sourceTree = "<group>"; };
+ 92BC3F7E0BAEE55B000DAB7F /* monster.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = monster.cpp; path = src/monster.cpp; sourceTree = "<group>"; };
+ 92BC3F7F0BAEE55B000DAB7F /* monster.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = monster.h; path = src/monster.h; sourceTree = "<group>"; };
+ 92BC3F880BAEE55B000DAB7F /* chathandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = chathandler.h; sourceTree = "<group>"; };
+ 92BC3F8C0BAEE55B000DAB7F /* inventoryhandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = inventoryhandler.h; sourceTree = "<group>"; };
+ 92BC3F900BAEE55B000DAB7F /* loginhandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = loginhandler.h; sourceTree = "<group>"; };
+ 92BC3F940BAEE55B000DAB7F /* messagehandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = messagehandler.h; sourceTree = "<group>"; };
+ 92BC3F950BAEE55B000DAB7F /* messagein.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = messagein.cpp; sourceTree = "<group>"; };
+ 92BC3F960BAEE55B000DAB7F /* messagein.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = messagein.h; sourceTree = "<group>"; };
+ 92BC3F970BAEE55B000DAB7F /* messageout.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = messageout.cpp; sourceTree = "<group>"; };
+ 92BC3F980BAEE55B000DAB7F /* messageout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = messageout.h; sourceTree = "<group>"; };
+ 92BC3F9C0BAEE55B000DAB7F /* npchandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = npchandler.h; sourceTree = "<group>"; };
+ 92BC3F9E0BAEE55B000DAB7F /* playerhandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = playerhandler.h; sourceTree = "<group>"; };
+ 92BC3FA40BAEE55B000DAB7F /* tradehandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tradehandler.h; sourceTree = "<group>"; };
+ 92BC3FA50BAEE55B000DAB7F /* npc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = npc.cpp; path = src/npc.cpp; sourceTree = "<group>"; };
+ 92BC3FA60BAEE55B000DAB7F /* npc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = npc.h; path = src/npc.h; sourceTree = "<group>"; };
+ 92BC3FA70BAEE55B000DAB7F /* openglgraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = openglgraphics.cpp; path = src/openglgraphics.cpp; sourceTree = "<group>"; };
+ 92BC3FA80BAEE55B000DAB7F /* openglgraphics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = openglgraphics.h; path = src/openglgraphics.h; sourceTree = "<group>"; };
+ 92BC3FBA0BAEE55B000DAB7F /* player.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = player.cpp; path = src/player.cpp; sourceTree = "<group>"; };
+ 92BC3FBB0BAEE55B000DAB7F /* player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = player.h; path = src/player.h; sourceTree = "<group>"; };
+ 92BC3FBC0BAEE55B000DAB7F /* properties.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = properties.h; path = src/properties.h; sourceTree = "<group>"; };
+ 92BC3FBE0BAEE55B000DAB7F /* action.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = action.cpp; sourceTree = "<group>"; };
+ 92BC3FBF0BAEE55B000DAB7F /* action.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = action.h; sourceTree = "<group>"; };
+ 92BC3FC00BAEE55B000DAB7F /* ambientoverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ambientoverlay.cpp; sourceTree = "<group>"; };
+ 92BC3FC10BAEE55B000DAB7F /* ambientoverlay.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ambientoverlay.h; sourceTree = "<group>"; };
+ 92BC3FC20BAEE55B000DAB7F /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
+ 92BC3FC30BAEE55B000DAB7F /* animation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = animation.h; sourceTree = "<group>"; };
+ 92BC3FC90BAEE55B000DAB7F /* image.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = image.cpp; sourceTree = "<group>"; };
+ 92BC3FCA0BAEE55B000DAB7F /* image.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = image.h; sourceTree = "<group>"; };
+ 92BC3FCB0BAEE55B000DAB7F /* imagewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = imagewriter.cpp; sourceTree = "<group>"; };
+ 92BC3FCC0BAEE55B000DAB7F /* imagewriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = imagewriter.h; sourceTree = "<group>"; };
+ 92BC3FCD0BAEE55B000DAB7F /* itemdb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = itemdb.cpp; sourceTree = "<group>"; };
+ 92BC3FCE0BAEE55B000DAB7F /* itemdb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = itemdb.h; sourceTree = "<group>"; };
+ 92BC3FCF0BAEE55B000DAB7F /* iteminfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = iteminfo.cpp; sourceTree = "<group>"; };
+ 92BC3FD00BAEE55B000DAB7F /* iteminfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = iteminfo.h; sourceTree = "<group>"; };
+ 92BC3FD10BAEE55B000DAB7F /* mapreader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mapreader.cpp; sourceTree = "<group>"; };
+ 92BC3FD20BAEE55B000DAB7F /* mapreader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mapreader.h; sourceTree = "<group>"; };
+ 92BC3FD30BAEE55B000DAB7F /* monsterdb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = monsterdb.cpp; sourceTree = "<group>"; };
+ 92BC3FD40BAEE55B000DAB7F /* monsterdb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = monsterdb.h; sourceTree = "<group>"; };
+ 92BC3FD50BAEE55B000DAB7F /* monsterinfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = monsterinfo.cpp; sourceTree = "<group>"; };
+ 92BC3FD60BAEE55B000DAB7F /* monsterinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = monsterinfo.h; sourceTree = "<group>"; };
+ 92BC3FD70BAEE55B000DAB7F /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
+ 92BC3FD80BAEE55B000DAB7F /* music.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
+ 92BC3FDB0BAEE55B000DAB7F /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
+ 92BC3FDC0BAEE55B000DAB7F /* resource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
+ 92BC3FDD0BAEE55B000DAB7F /* resourcemanager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = resourcemanager.cpp; sourceTree = "<group>"; };
+ 92BC3FDE0BAEE55B000DAB7F /* resourcemanager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = resourcemanager.h; sourceTree = "<group>"; };
+ 92BC3FE10BAEE55B000DAB7F /* soundeffect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = soundeffect.cpp; sourceTree = "<group>"; };
+ 92BC3FE20BAEE55B000DAB7F /* soundeffect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = soundeffect.h; sourceTree = "<group>"; };
+ 92BC3FE30BAEE55B000DAB7F /* spritedef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = spritedef.cpp; sourceTree = "<group>"; };
+ 92BC3FE40BAEE55B000DAB7F /* spritedef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = spritedef.h; sourceTree = "<group>"; };
+ 92BC3FE80BAEE55B000DAB7F /* simpleanimation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = simpleanimation.cpp; path = src/simpleanimation.cpp; sourceTree = "<group>"; };
+ 92BC3FE90BAEE55B000DAB7F /* simpleanimation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = simpleanimation.h; path = src/simpleanimation.h; sourceTree = "<group>"; };
+ 92BC3FEA0BAEE55B000DAB7F /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sound.cpp; path = src/sound.cpp; sourceTree = "<group>"; };
+ 92BC3FEB0BAEE55B000DAB7F /* sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sound.h; path = src/sound.h; sourceTree = "<group>"; };
+ 92BC3FEC0BAEE55B000DAB7F /* sprite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sprite.h; path = src/sprite.h; sourceTree = "<group>"; };
+ 92BC3FED0BAEE55B000DAB7F /* tileset.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tileset.h; path = src/tileset.h; sourceTree = "<group>"; };
+ 92BC3FEF0BAEE55B000DAB7F /* base64.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = base64.cpp; sourceTree = "<group>"; };
+ 92BC3FF00BAEE55B000DAB7F /* base64.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = base64.h; sourceTree = "<group>"; };
+ 92BC3FF10BAEE55B000DAB7F /* dtor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dtor.h; sourceTree = "<group>"; };
+ 92BC3FF40BAEE55B000DAB7F /* xml.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = xml.cpp; sourceTree = "<group>"; };
+ 92BC3FF50BAEE55B000DAB7F /* xml.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = xml.h; sourceTree = "<group>"; };
+ 92BC408E0BAEE818000DAB7F /* SDL_image.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_image.framework; path = /Library/Frameworks/SDL_image.framework; sourceTree = "<absolute>"; };
+ 92BC408F0BAEE818000DAB7F /* SDL_mixer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_mixer.framework; path = /Library/Frameworks/SDL_mixer.framework; sourceTree = "<absolute>"; };
+ 92BC40900BAEE818000DAB7F /* SDL_net.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_net.framework; path = /Library/Frameworks/SDL_net.framework; sourceTree = "<absolute>"; };
+ 92BC40910BAEE818000DAB7F /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
+ 92BC40C60BAEEDAA000DAB7F /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
+ 92BC40D80BAEEED3000DAB7F /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+ 92BC40E50BAEF54B000DAB7F /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = SDLMain.m; path = src/SDLMain.m; sourceTree = "<group>"; };
+ 92BC40E80BAEF57D000DAB7F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 92C1150C0F8EBB360048CA8D /* window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = window.cpp; sourceTree = "<group>"; };
+ 92C1150D0F8EBB360048CA8D /* window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
+ 92C115100F8EBB550048CA8D /* itempopup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itempopup.cpp; sourceTree = "<group>"; };
+ 92C115110F8EBB550048CA8D /* itempopup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itempopup.h; sourceTree = "<group>"; };
+ 92C115140F8EBB830048CA8D /* listbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = listbox.cpp; sourceTree = "<group>"; };
+ 92C115150F8EBB830048CA8D /* listbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = listbox.h; sourceTree = "<group>"; };
+ 92C115160F8EBB830048CA8D /* scrollarea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scrollarea.cpp; sourceTree = "<group>"; };
+ 92C115170F8EBB830048CA8D /* scrollarea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scrollarea.h; sourceTree = "<group>"; };
+ 92C115180F8EBB830048CA8D /* slider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slider.cpp; sourceTree = "<group>"; };
+ 92C115190F8EBB830048CA8D /* slider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = slider.h; sourceTree = "<group>"; };
+ 92C1151E0F8EBBA90048CA8D /* emoteshortcut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = emoteshortcut.cpp; path = src/emoteshortcut.cpp; sourceTree = "<group>"; };
+ 92C1151F0F8EBBA90048CA8D /* emoteshortcut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = emoteshortcut.h; path = src/emoteshortcut.h; sourceTree = "<group>"; };
+ 92C115220F8EBBD50048CA8D /* inttextfield.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inttextfield.cpp; sourceTree = "<group>"; };
+ 92C115230F8EBBD50048CA8D /* inttextfield.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inttextfield.h; sourceTree = "<group>"; };
+ 92C115240F8EBBD50048CA8D /* popup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = popup.cpp; sourceTree = "<group>"; };
+ 92C115250F8EBBD50048CA8D /* popup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = popup.h; sourceTree = "<group>"; };
+ 92C115260F8EBBD50048CA8D /* textfield.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textfield.cpp; sourceTree = "<group>"; };
+ 92C115270F8EBBD50048CA8D /* textfield.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textfield.h; sourceTree = "<group>"; };
+ 92C115320F8EBC450048CA8D /* browserbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = browserbox.cpp; sourceTree = "<group>"; };
+ 92C115330F8EBC450048CA8D /* browserbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browserbox.h; sourceTree = "<group>"; };
+ 92C115340F8EBC450048CA8D /* windowcontainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = windowcontainer.cpp; sourceTree = "<group>"; };
+ 92C115350F8EBC450048CA8D /* windowcontainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = windowcontainer.h; sourceTree = "<group>"; };
+ 92C115390F8EBC730048CA8D /* chattab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chattab.cpp; sourceTree = "<group>"; };
+ 92C1153A0F8EBC730048CA8D /* chattab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chattab.h; sourceTree = "<group>"; };
+ 92C115410F8EBCB70048CA8D /* shortcutwindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shortcutwindow.cpp; sourceTree = "<group>"; };
+ 92C115420F8EBCB70048CA8D /* shortcutwindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shortcutwindow.h; sourceTree = "<group>"; };
+ 92C115450F8EBCD00048CA8D /* passwordfield.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = passwordfield.cpp; sourceTree = "<group>"; };
+ 92C115460F8EBCD00048CA8D /* passwordfield.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = passwordfield.h; sourceTree = "<group>"; };
+ 92C115490F8EBD000048CA8D /* checkbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = checkbox.cpp; sourceTree = "<group>"; };
+ 92C1154A0F8EBD000048CA8D /* checkbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = checkbox.h; sourceTree = "<group>"; };
+ 92C1154B0F8EBD000048CA8D /* textbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textbox.cpp; sourceTree = "<group>"; };
+ 92C1154C0F8EBD000048CA8D /* textbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textbox.h; sourceTree = "<group>"; };
+ 92C115500F8EBD250048CA8D /* label.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = label.cpp; sourceTree = "<group>"; };
+ 92C115510F8EBD250048CA8D /* label.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = label.h; sourceTree = "<group>"; };
+ 92C115520F8EBD250048CA8D /* progressbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = progressbar.cpp; sourceTree = "<group>"; };
+ 92C115530F8EBD250048CA8D /* progressbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = progressbar.h; sourceTree = "<group>"; };
+ 92C115570F8EBD490048CA8D /* net.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = net.cpp; sourceTree = "<group>"; };
+ 92C115580F8EBD490048CA8D /* net.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = net.h; sourceTree = "<group>"; };
+ 92C115990F8EBD900048CA8D /* emotedb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = emotedb.cpp; sourceTree = "<group>"; };
+ 92C1159A0F8EBD900048CA8D /* emotedb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emotedb.h; sourceTree = "<group>"; };
+ 92C1159C0F8EBDB20048CA8D /* commandhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = commandhandler.cpp; path = src/commandhandler.cpp; sourceTree = "<group>"; };
+ 92C1159D0F8EBDB20048CA8D /* commandhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = commandhandler.h; path = src/commandhandler.h; sourceTree = "<group>"; };
+ 92C1159E0F8EBDB20048CA8D /* effectmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = effectmanager.cpp; path = src/effectmanager.cpp; sourceTree = "<group>"; };
+ 92C1159F0F8EBDB20048CA8D /* effectmanager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = effectmanager.h; path = src/effectmanager.h; sourceTree = "<group>"; };
+ 92C115A00F8EBDB20048CA8D /* units.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = units.cpp; path = src/units.cpp; sourceTree = "<group>"; };
+ 92C115A10F8EBDB20048CA8D /* units.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = units.h; path = src/units.h; sourceTree = "<group>"; };
+ 92C115AD0F8EBE450048CA8D /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
+ 92C115AE0F8EBE450048CA8D /* palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palette.h; sourceTree = "<group>"; };
+ 92C115B50F8EBE450048CA8D /* speechbubble.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = speechbubble.cpp; sourceTree = "<group>"; };
+ 92C115B60F8EBE450048CA8D /* speechbubble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speechbubble.h; sourceTree = "<group>"; };
+ 92C115BD0F8EBE5E0048CA8D /* channeltab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = channeltab.cpp; sourceTree = "<group>"; };
+ 92C115BE0F8EBE5E0048CA8D /* channeltab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = channeltab.h; sourceTree = "<group>"; };
+ 92C115C30F8EBE950048CA8D /* whispertab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = whispertab.cpp; sourceTree = "<group>"; };
+ 92C115C40F8EBE950048CA8D /* whispertab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = whispertab.h; sourceTree = "<group>"; };
+ 92C115C70F8EBECE0048CA8D /* charcreatedialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charcreatedialog.cpp; sourceTree = "<group>"; };
+ 92C115C80F8EBECE0048CA8D /* charcreatedialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charcreatedialog.h; sourceTree = "<group>"; };
+ 92C115CB0F8EBF090048CA8D /* channelmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = channelmanager.cpp; path = src/channelmanager.cpp; sourceTree = "<group>"; };
+ 92C115CC0F8EBF090048CA8D /* channelmanager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = channelmanager.h; path = src/channelmanager.h; sourceTree = "<group>"; };
+ 92C115CE0F8EBF1C0048CA8D /* colordb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = colordb.cpp; sourceTree = "<group>"; };
+ 92C115CF0F8EBF1C0048CA8D /* colordb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colordb.h; sourceTree = "<group>"; };
+ 92C115D00F8EBF1C0048CA8D /* wallpaper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wallpaper.cpp; sourceTree = "<group>"; };
+ 92C115D10F8EBF1C0048CA8D /* wallpaper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wallpaper.h; sourceTree = "<group>"; };
+ 92C115D50F8EBF530048CA8D /* button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = button.cpp; sourceTree = "<group>"; };
+ 92C115D60F8EBF530048CA8D /* button.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = button.h; sourceTree = "<group>"; };
+ 92C115D70F8EBF530048CA8D /* icon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = icon.cpp; sourceTree = "<group>"; };
+ 92C115D80F8EBF530048CA8D /* icon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icon.h; sourceTree = "<group>"; };
+ 92C115D90F8EBF530048CA8D /* radiobutton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = radiobutton.cpp; sourceTree = "<group>"; };
+ 92C115DA0F8EBF530048CA8D /* radiobutton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = radiobutton.h; sourceTree = "<group>"; };
+ 92C115E80F8EBFA60048CA8D /* stringutils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stringutils.cpp; sourceTree = "<group>"; };
+ 92C115E90F8EBFA60048CA8D /* stringutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringutils.h; sourceTree = "<group>"; };
+ 92C115EC0F8EBFC20048CA8D /* channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = channel.cpp; path = src/channel.cpp; sourceTree = "<group>"; };
+ 92C115ED0F8EBFC20048CA8D /* channel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = channel.h; path = src/channel.h; sourceTree = "<group>"; };
+ 92C115F50F8EBFDD0048CA8D /* dropdown.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dropdown.cpp; sourceTree = "<group>"; };
+ 92C115F60F8EBFDD0048CA8D /* dropdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dropdown.h; sourceTree = "<group>"; };
+ 92C115F90F8EBFF30048CA8D /* setup_colors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = setup_colors.cpp; sourceTree = "<group>"; };
+ 92C115FA0F8EBFF30048CA8D /* setup_colors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = setup_colors.h; sourceTree = "<group>"; };
+ 92C115FD0F8EC0150048CA8D /* textpreview.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textpreview.cpp; sourceTree = "<group>"; };
+ 92C115FE0F8EC0150048CA8D /* textpreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textpreview.h; sourceTree = "<group>"; };
+ 92C116010F8EC0590048CA8D /* circle-gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "circle-gray.png"; sourceTree = "<group>"; };
+ 92C116020F8EC0590048CA8D /* circle-green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "circle-green.png"; sourceTree = "<group>"; };
+ 92C116070F8EC0590048CA8D /* speechbubble.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = speechbubble.xml; sourceTree = "<group>"; };
+ 92C116080F8EC0590048CA8D /* sticky_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = sticky_button.png; sourceTree = "<group>"; };
+ 92C116E40F8ECBE80048CA8D /* changepassworddialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = changepassworddialog.cpp; sourceTree = "<group>"; };
+ 92C116E50F8ECBE80048CA8D /* changepassworddialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = changepassworddialog.h; sourceTree = "<group>"; };
+ 92C117530F8ECEEA0048CA8D /* skilldialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = skilldialog.cpp; sourceTree = "<group>"; };
+ 92C117540F8ECEEA0048CA8D /* skilldialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = skilldialog.h; sourceTree = "<group>"; };
+ 92C117560F8ECF0B0048CA8D /* statuswindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = statuswindow.cpp; sourceTree = "<group>"; };
+ 92C117570F8ECF0B0048CA8D /* statuswindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = statuswindow.h; sourceTree = "<group>"; };
+ 92C117580F8ECF0B0048CA8D /* unregisterdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unregisterdialog.cpp; sourceTree = "<group>"; };
+ 92C117590F8ECF0B0048CA8D /* unregisterdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unregisterdialog.h; sourceTree = "<group>"; };
+ 92C1186F0F8ED33F0048CA8D /* quitdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = quitdialog.cpp; sourceTree = "<group>"; };
+ 92C118700F8ED33F0048CA8D /* quitdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = quitdialog.h; sourceTree = "<group>"; };
+ 92C1188E0F8ED4B30048CA8D /* guild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = guild.cpp; path = src/guild.cpp; sourceTree = "<group>"; };
+ 92C1188F0F8ED4B30048CA8D /* guild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = guild.h; path = src/guild.h; sourceTree = "<group>"; };
+ 92C118F20F8ED5DE0048CA8D /* textdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textdialog.cpp; sourceTree = "<group>"; };
+ 92C118F30F8ED5DE0048CA8D /* textdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textdialog.h; sourceTree = "<group>"; };
+ 92C119010F8ED63F0048CA8D /* npcpostdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = npcpostdialog.cpp; sourceTree = "<group>"; };
+ 92C119020F8ED63F0048CA8D /* npcpostdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = npcpostdialog.h; sourceTree = "<group>"; };
+ 92C1191B0F8ED79A0048CA8D /* changeemaildialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = changeemaildialog.cpp; sourceTree = "<group>"; };
+ 92C1191C0F8ED79A0048CA8D /* changeemaildialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = changeemaildialog.h; sourceTree = "<group>"; };
+ 92C119830F8ED80E0048CA8D /* serverdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = serverdialog.cpp; sourceTree = "<group>"; };
+ 92C119840F8ED80E0048CA8D /* serverdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serverdialog.h; sourceTree = "<group>"; };
+ 92C1198E0F8ED85E0048CA8D /* sha256.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sha256.cpp; sourceTree = "<group>"; };
+ 92C1198F0F8ED85E0048CA8D /* sha256.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sha256.h; sourceTree = "<group>"; };
+ 92C119980F8ED8B00048CA8D /* position.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = position.cpp; path = src/position.cpp; sourceTree = "<group>"; };
+ 92C636AF0FC5605300EE8D8D /* mathutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mathutils.h; sourceTree = "<group>"; };
+ 92C636B30FC5663000EE8D8D /* flooritem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flooritem.cpp; path = src/flooritem.cpp; sourceTree = "<group>"; };
+ 92C636B40FC5663000EE8D8D /* flooritem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flooritem.h; path = src/flooritem.h; sourceTree = "<group>"; };
+ 92C636B50FC5663000EE8D8D /* playerrelations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = playerrelations.cpp; path = src/playerrelations.cpp; sourceTree = "<group>"; };
+ 92C636B60FC5663000EE8D8D /* playerrelations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = playerrelations.h; path = src/playerrelations.h; sourceTree = "<group>"; };
+ 92C636B70FC5663000EE8D8D /* position.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = position.h; path = src/position.h; sourceTree = "<group>"; };
+ 92C636B80FC5663000EE8D8D /* rotationalparticle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rotationalparticle.cpp; path = src/rotationalparticle.cpp; sourceTree = "<group>"; };
+ 92C636B90FC5663000EE8D8D /* rotationalparticle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rotationalparticle.h; path = src/rotationalparticle.h; sourceTree = "<group>"; };
+ 92C636BA0FC5663000EE8D8D /* vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = vector.cpp; path = src/vector.cpp; sourceTree = "<group>"; };
+ 92C636C40FC5670700EE8D8D /* charselectdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charselectdialog.cpp; sourceTree = "<group>"; };
+ 92C636C50FC5670700EE8D8D /* charselectdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charselectdialog.h; sourceTree = "<group>"; };
+ 92C636C60FC5670700EE8D8D /* confirmdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = confirmdialog.cpp; sourceTree = "<group>"; };
+ 92C636C70FC5670700EE8D8D /* confirmdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = confirmdialog.h; sourceTree = "<group>"; };
+ 92C636C80FC5670700EE8D8D /* emotepopup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = emotepopup.cpp; sourceTree = "<group>"; };
+ 92C636C90FC5670700EE8D8D /* emotepopup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emotepopup.h; sourceTree = "<group>"; };
+ 92C636CA0FC5670700EE8D8D /* itemamount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itemamount.cpp; sourceTree = "<group>"; };
+ 92C636CB0FC5670700EE8D8D /* itemamount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itemamount.h; sourceTree = "<group>"; };
+ 92C636CC0FC5670700EE8D8D /* npcdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = npcdialog.cpp; sourceTree = "<group>"; };
+ 92C636CD0FC5670700EE8D8D /* npcdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = npcdialog.h; sourceTree = "<group>"; };
+ 92C636CE0FC5670700EE8D8D /* okdialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = okdialog.cpp; sourceTree = "<group>"; };
+ 92C636CF0FC5670700EE8D8D /* okdialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = okdialog.h; sourceTree = "<group>"; };
+ 92C636D00FC5670700EE8D8D /* outfitwindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = outfitwindow.cpp; sourceTree = "<group>"; };
+ 92C636D10FC5670700EE8D8D /* outfitwindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = outfitwindow.h; sourceTree = "<group>"; };
+ 92C636D50FC5670700EE8D8D /* windowmenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = windowmenu.cpp; sourceTree = "<group>"; };
+ 92C636D60FC5670700EE8D8D /* windowmenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = windowmenu.h; sourceTree = "<group>"; };
+ 92C636EA0FC5677500EE8D8D /* adminhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adminhandler.h; sourceTree = "<group>"; };
+ 92C636EB0FC5677500EE8D8D /* charhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charhandler.h; sourceTree = "<group>"; };
+ 92C636EC0FC5677500EE8D8D /* generalhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = generalhandler.h; sourceTree = "<group>"; };
+ 92C636ED0FC5677500EE8D8D /* guildhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guildhandler.h; sourceTree = "<group>"; };
+ 92C636EE0FC5677500EE8D8D /* logindata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logindata.h; sourceTree = "<group>"; };
+ 92C636F10FC5677500EE8D8D /* partyhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = partyhandler.h; sourceTree = "<group>"; };
+ 92C636F20FC5677500EE8D8D /* serverinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serverinfo.h; sourceTree = "<group>"; };
+ 92C637800FC574B500EE8D8D /* window.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = window.png; sourceTree = "<group>"; };
+ 92C637850FC5751700EE8D8D /* dejavusans-bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "dejavusans-bold.ttf"; path = "fonts/dejavusans-bold.ttf"; sourceTree = "<group>"; };
+ 92C85CF411F28D2300AB20CA /* error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = error.png; sourceTree = "<group>"; };
+ 92C85CF511F28D2300AB20CA /* error.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = error.xml; sourceTree = "<group>"; };
+ 92DD76450F267B3600B2B519 /* layouthelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layouthelper.cpp; sourceTree = "<group>"; };
+ 92DD76460F267B3600B2B519 /* layouthelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layouthelper.h; sourceTree = "<group>"; };
+ 92EA98B30FC5CB17003DC005 /* SDLMain.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = SDLMain.nib; sourceTree = "<group>"; };
+ 92FD19B30DDCE53400D14E5D /* setup_players.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = setup_players.cpp; sourceTree = "<group>"; };
+ 92FD19B40DDCE53400D14E5D /* setup_players.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = setup_players.h; sourceTree = "<group>"; };
+ 92FD19BD0DDCE56A00D14E5D /* dye.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dye.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D0C4E910486CD37000505A6 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */,
+ 92BC40940BAEE818000DAB7F /* SDL_image.framework in Frameworks */,
+ 92BC40950BAEE818000DAB7F /* SDL_mixer.framework in Frameworks */,
+ 92BC40960BAEE818000DAB7F /* SDL_net.framework in Frameworks */,
+ 92BC40970BAEE818000DAB7F /* SDL.framework in Frameworks */,
+ 92BC40C70BAEEDAA000DAB7F /* OpenGL.framework in Frameworks */,
+ 92BC40D90BAEEED3000DAB7F /* IOKit.framework in Frameworks */,
+ 92BC40E90BAEF57D000DAB7F /* Cocoa.framework in Frameworks */,
+ 9294DAA10C17E73200FCEDE9 /* libpng.framework in Frameworks */,
+ 926A297A0F23C155005D6466 /* SDL_ttf.framework in Frameworks */,
+ 926857AC11F15A9300A28C33 /* guichan.framework in Frameworks */,
+ 922895B711F665A200AE53BB /* libintl.8.dylib in Frameworks */,
+ 922895B811F665A200AE53BB /* libphysfs.1.dylib in Frameworks */,
+ 922895B911F665A200AE53BB /* libSDL_gfx.13.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 195DF8CFFE9D517E11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 508344B209E5C41E0093A071 /* The Mana World.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 20286C29FDCF999611CA2CEA /* themanaworld */ = {
+ isa = PBXGroup;
+ children = (
+ 924A42600C0874D00066885E /* Info.plist */,
+ 5048396909E3304600765E4B /* Configuration Files */,
+ 20286C2AFDCF999611CA2CEA /* Sources */,
+ 20286C2CFDCF999611CA2CEA /* Resources */,
+ 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */,
+ 195DF8CFFE9D517E11CA2CBB /* Products */,
+ );
+ name = themanaworld;
+ sourceTree = "<group>";
+ };
+ 20286C2AFDCF999611CA2CEA /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 9268564B11F142D500A28C33 /* avatar.cpp */,
+ 9268564C11F142D500A28C33 /* avatar.h */,
+ 9268564D11F142D500A28C33 /* client.cpp */,
+ 9268564E11F142D500A28C33 /* client.h */,
+ 9268564F11F142D500A28C33 /* party.cpp */,
+ 9268565011F142D500A28C33 /* party.h */,
+ 9268565111F142D500A28C33 /* textrenderer.h */,
+ 92C636B30FC5663000EE8D8D /* flooritem.cpp */,
+ 92C636B40FC5663000EE8D8D /* flooritem.h */,
+ 92C636B50FC5663000EE8D8D /* playerrelations.cpp */,
+ 92C636B60FC5663000EE8D8D /* playerrelations.h */,
+ 92C636B70FC5663000EE8D8D /* position.h */,
+ 92C636B80FC5663000EE8D8D /* rotationalparticle.cpp */,
+ 92C636B90FC5663000EE8D8D /* rotationalparticle.h */,
+ 92C636BA0FC5663000EE8D8D /* vector.cpp */,
+ 92C119980F8ED8B00048CA8D /* position.cpp */,
+ 92C1188E0F8ED4B30048CA8D /* guild.cpp */,
+ 92C1188F0F8ED4B30048CA8D /* guild.h */,
+ 92C115EC0F8EBFC20048CA8D /* channel.cpp */,
+ 92C115ED0F8EBFC20048CA8D /* channel.h */,
+ 92C115CB0F8EBF090048CA8D /* channelmanager.cpp */,
+ 92C115CC0F8EBF090048CA8D /* channelmanager.h */,
+ 92C1159C0F8EBDB20048CA8D /* commandhandler.cpp */,
+ 92C1159D0F8EBDB20048CA8D /* commandhandler.h */,
+ 92C1159E0F8EBDB20048CA8D /* effectmanager.cpp */,
+ 92C1159F0F8EBDB20048CA8D /* effectmanager.h */,
+ 92C115A00F8EBDB20048CA8D /* units.cpp */,
+ 92C115A10F8EBDB20048CA8D /* units.h */,
+ 92C1151E0F8EBBA90048CA8D /* emoteshortcut.cpp */,
+ 92C1151F0F8EBBA90048CA8D /* emoteshortcut.h */,
+ 9273BE040EF33FB3008E56E1 /* particlecontainer.cpp */,
+ 9273BE050EF33FB3008E56E1 /* particlecontainer.h */,
+ 9273BE060EF33FB3008E56E1 /* statuseffect.cpp */,
+ 9273BE070EF33FB3008E56E1 /* statuseffect.h */,
+ 92037A1A0ED2037300D3712D /* particleemitterprop.h */,
+ 92037A1B0ED2037300D3712D /* text.cpp */,
+ 92037A1C0ED2037300D3712D /* text.h */,
+ 92037A1D0ED2037300D3712D /* textmanager.cpp */,
+ 92037A1E0ED2037300D3712D /* textmanager.h */,
+ 922CD95D0E3D01080074C50E /* shopitem.cpp */,
+ 922CD95E0E3D01080074C50E /* shopitem.h */,
+ 926F9CF60DB005FA00AACD26 /* itemshortcut.cpp */,
+ 926F9CF70DB005FA00AACD26 /* itemshortcut.h */,
+ 92024D2A0CF1BD9E006B55CB /* keyboardconfig.cpp */,
+ 92024D2B0CF1BD9E006B55CB /* keyboardconfig.h */,
+ 92024D2C0CF1BD9E006B55CB /* vector.h */,
+ 924A39E80C0784280066885E /* animationparticle.cpp */,
+ 924A39E90C0784280066885E /* animationparticle.h */,
+ 924A39EA0C0784280066885E /* imageparticle.cpp */,
+ 924A39EB0C0784280066885E /* imageparticle.h */,
+ 924A39EC0C0784280066885E /* particle.cpp */,
+ 924A39ED0C0784280066885E /* particle.h */,
+ 924A39EE0C0784280066885E /* particleemitter.cpp */,
+ 924A39EF0C0784280066885E /* particleemitter.h */,
+ 924A39F00C0784280066885E /* textparticle.cpp */,
+ 924A39F10C0784280066885E /* textparticle.h */,
+ 92BC3ECA0BAEE55A000DAB7F /* animatedsprite.cpp */,
+ 92BC3ECB0BAEE55A000DAB7F /* animatedsprite.h */,
+ 92BC3ECC0BAEE55A000DAB7F /* being.cpp */,
+ 92BC3ECD0BAEE55A000DAB7F /* being.h */,
+ 92BC3ECE0BAEE55A000DAB7F /* beingmanager.cpp */,
+ 92BC3ECF0BAEE55A000DAB7F /* beingmanager.h */,
+ 92BC3ED10BAEE55A000DAB7F /* configlistener.h */,
+ 92BC3ED20BAEE55A000DAB7F /* configuration.cpp */,
+ 92BC3ED30BAEE55A000DAB7F /* configuration.h */,
+ 92BC3EE70BAEE55A000DAB7F /* equipment.h */,
+ 92BC3EEA0BAEE55A000DAB7F /* flooritemmanager.cpp */,
+ 92BC3EEB0BAEE55A000DAB7F /* flooritemmanager.h */,
+ 92BC3EEC0BAEE55A000DAB7F /* game.cpp */,
+ 92BC3EED0BAEE55A000DAB7F /* game.h */,
+ 92BC3EEE0BAEE55A000DAB7F /* graphics.cpp */,
+ 92BC3EEF0BAEE55A000DAB7F /* graphics.h */,
+ 92BC3EF00BAEE55A000DAB7F /* gui */,
+ 92BC3F6C0BAEE55B000DAB7F /* guichanfwd.h */,
+ 92BC3F6D0BAEE55B000DAB7F /* inventory.cpp */,
+ 92BC3F6E0BAEE55B000DAB7F /* inventory.h */,
+ 92BC3F6F0BAEE55B000DAB7F /* item.cpp */,
+ 92BC3F700BAEE55B000DAB7F /* item.h */,
+ 92BC3F710BAEE55B000DAB7F /* joystick.cpp */,
+ 92BC3F720BAEE55B000DAB7F /* joystick.h */,
+ 92BC3F730BAEE55B000DAB7F /* localplayer.cpp */,
+ 92BC3F740BAEE55B000DAB7F /* localplayer.h */,
+ 92BC3F760BAEE55B000DAB7F /* log.cpp */,
+ 92BC3F770BAEE55B000DAB7F /* log.h */,
+ 92BC3F790BAEE55B000DAB7F /* main.cpp */,
+ 92BC3F7A0BAEE55B000DAB7F /* main.h */,
+ 92BC3F7C0BAEE55B000DAB7F /* map.cpp */,
+ 92BC3F7D0BAEE55B000DAB7F /* map.h */,
+ 92BC3F7E0BAEE55B000DAB7F /* monster.cpp */,
+ 92BC3F7F0BAEE55B000DAB7F /* monster.h */,
+ 92BC3F800BAEE55B000DAB7F /* net */,
+ 92BC3FA50BAEE55B000DAB7F /* npc.cpp */,
+ 92BC3FA60BAEE55B000DAB7F /* npc.h */,
+ 92BC3FA70BAEE55B000DAB7F /* openglgraphics.cpp */,
+ 92BC3FA80BAEE55B000DAB7F /* openglgraphics.h */,
+ 92BC3FBA0BAEE55B000DAB7F /* player.cpp */,
+ 92BC3FBB0BAEE55B000DAB7F /* player.h */,
+ 92BC3FBC0BAEE55B000DAB7F /* properties.h */,
+ 92BC3FBD0BAEE55B000DAB7F /* resources */,
+ 92BC3FE80BAEE55B000DAB7F /* simpleanimation.cpp */,
+ 92BC3FE90BAEE55B000DAB7F /* simpleanimation.h */,
+ 92BC3FEA0BAEE55B000DAB7F /* sound.cpp */,
+ 92BC3FEB0BAEE55B000DAB7F /* sound.h */,
+ 92BC3FEC0BAEE55B000DAB7F /* sprite.h */,
+ 92BC3FED0BAEE55B000DAB7F /* tileset.h */,
+ 92BC3FEE0BAEE55B000DAB7F /* utils */,
+ );
+ name = Sources;
+ sourceTree = "<group>";
+ };
+ 20286C2CFDCF999611CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 92EA98B30FC5CB17003DC005 /* SDLMain.nib */,
+ 9273BDFD0EF33E1A008E56E1 /* AUTHORS */,
+ 9273BDFE0EF33E1A008E56E1 /* README */,
+ 9273BDFB0EF33DFD008E56E1 /* COPYING */,
+ 924A3E590C085ED70066885E /* data */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 922895BF11F6677F00AE53BB /* libiconv.2.dylib */,
+ 922895C011F6677F00AE53BB /* libSDL-1.2.0.dylib */,
+ 922895B411F665A200AE53BB /* libintl.8.dylib */,
+ 922895B511F665A200AE53BB /* libphysfs.1.dylib */,
+ 922895B611F665A200AE53BB /* libSDL_gfx.13.dylib */,
+ 926A29790F23C155005D6466 /* SDL_ttf.framework */,
+ 9294DAA00C17E73200FCEDE9 /* libpng.framework */,
+ 92BC40E80BAEF57D000DAB7F /* Cocoa.framework */,
+ 92BC40D80BAEEED3000DAB7F /* IOKit.framework */,
+ 92BC40C60BAEEDAA000DAB7F /* OpenGL.framework */,
+ 92BC408E0BAEE818000DAB7F /* SDL_image.framework */,
+ 92BC408F0BAEE818000DAB7F /* SDL_mixer.framework */,
+ 92BC40900BAEE818000DAB7F /* SDL_net.framework */,
+ 92BC40910BAEE818000DAB7F /* SDL.framework */,
+ 20286C33FDCF999611CA2CEA /* Carbon.framework */,
+ 926857AB11F15A9300A28C33 /* guichan.framework */,
+ );
+ name = "External Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 5048396909E3304600765E4B /* Configuration Files */ = {
+ isa = PBXGroup;
+ children = (
+ 92037A190ED2035A00D3712D /* SDLMain.h */,
+ 92BC40E50BAEF54B000DAB7F /* SDLMain.m */,
+ );
+ name = "Configuration Files";
+ sourceTree = "<group>";
+ };
+ 924A3A0F0C07A60B0066885E /* widgets */ = {
+ isa = PBXGroup;
+ children = (
+ 9268567811F1431300A28C33 /* avatarlistbox.cpp */,
+ 9268567911F1431300A28C33 /* avatarlistbox.h */,
+ 9268567A11F1431300A28C33 /* emoteshortcutcontainer.cpp */,
+ 9268567B11F1431300A28C33 /* emoteshortcutcontainer.h */,
+ 9268567C11F1431300A28C33 /* flowcontainer.cpp */,
+ 9268567D11F1431300A28C33 /* flowcontainer.h */,
+ 9268567E11F1431300A28C33 /* itemcontainer.cpp */,
+ 9268567F11F1431300A28C33 /* itemcontainer.h */,
+ 9268568011F1431300A28C33 /* itemlinkhandler.cpp */,
+ 9268568111F1431300A28C33 /* itemlinkhandler.h */,
+ 9268568211F1431300A28C33 /* itemshortcutcontainer.cpp */,
+ 9268568311F1431300A28C33 /* itemshortcutcontainer.h */,
+ 9268568411F1431300A28C33 /* linkhandler.h */,
+ 9268568511F1431300A28C33 /* playerbox.cpp */,
+ 9268568611F1431300A28C33 /* playerbox.h */,
+ 9268568711F1431300A28C33 /* progressindicator.cpp */,
+ 9268568811F1431300A28C33 /* progressindicator.h */,
+ 9268568911F1431300A28C33 /* setuptab.cpp */,
+ 9268568A11F1431300A28C33 /* setuptab.h */,
+ 9268568B11F1431300A28C33 /* shopitems.cpp */,
+ 9268568C11F1431300A28C33 /* shopitems.h */,
+ 9268568D11F1431300A28C33 /* shoplistbox.cpp */,
+ 9268568E11F1431300A28C33 /* shoplistbox.h */,
+ 9268568F11F1431300A28C33 /* shortcutcontainer.cpp */,
+ 9268569011F1431300A28C33 /* shortcutcontainer.h */,
+ 9268569111F1431300A28C33 /* table.cpp */,
+ 9268569211F1431300A28C33 /* table.h */,
+ 9268569311F1431300A28C33 /* tablemodel.cpp */,
+ 9268569411F1431300A28C33 /* tablemodel.h */,
+ 9268569511F1431300A28C33 /* vertcontainer.cpp */,
+ 9268569611F1431300A28C33 /* vertcontainer.h */,
+ 92A245C20F93626900B7719B /* desktop.cpp */,
+ 92A245C30F93626900B7719B /* desktop.h */,
+ 92A244B50F935FB400B7719B /* container.cpp */,
+ 92A244B60F935FB400B7719B /* container.h */,
+ 92C115FD0F8EC0150048CA8D /* textpreview.cpp */,
+ 92C115FE0F8EC0150048CA8D /* textpreview.h */,
+ 92C115F50F8EBFDD0048CA8D /* dropdown.cpp */,
+ 92C115F60F8EBFDD0048CA8D /* dropdown.h */,
+ 92C115D50F8EBF530048CA8D /* button.cpp */,
+ 92C115D60F8EBF530048CA8D /* button.h */,
+ 92C115D70F8EBF530048CA8D /* icon.cpp */,
+ 92C115D80F8EBF530048CA8D /* icon.h */,
+ 92C115D90F8EBF530048CA8D /* radiobutton.cpp */,
+ 92C115DA0F8EBF530048CA8D /* radiobutton.h */,
+ 92C115C30F8EBE950048CA8D /* whispertab.cpp */,
+ 92C115C40F8EBE950048CA8D /* whispertab.h */,
+ 92C115BD0F8EBE5E0048CA8D /* channeltab.cpp */,
+ 92C115BE0F8EBE5E0048CA8D /* channeltab.h */,
+ 92C115500F8EBD250048CA8D /* label.cpp */,
+ 92C115510F8EBD250048CA8D /* label.h */,
+ 92C115520F8EBD250048CA8D /* progressbar.cpp */,
+ 92C115530F8EBD250048CA8D /* progressbar.h */,
+ 92C115490F8EBD000048CA8D /* checkbox.cpp */,
+ 92C1154A0F8EBD000048CA8D /* checkbox.h */,
+ 92C1154B0F8EBD000048CA8D /* textbox.cpp */,
+ 92C1154C0F8EBD000048CA8D /* textbox.h */,
+ 92C115450F8EBCD00048CA8D /* passwordfield.cpp */,
+ 92C115460F8EBCD00048CA8D /* passwordfield.h */,
+ 92C115390F8EBC730048CA8D /* chattab.cpp */,
+ 92C1153A0F8EBC730048CA8D /* chattab.h */,
+ 92C115320F8EBC450048CA8D /* browserbox.cpp */,
+ 92C115330F8EBC450048CA8D /* browserbox.h */,
+ 92C115340F8EBC450048CA8D /* windowcontainer.cpp */,
+ 92C115350F8EBC450048CA8D /* windowcontainer.h */,
+ 92C115220F8EBBD50048CA8D /* inttextfield.cpp */,
+ 92C115230F8EBBD50048CA8D /* inttextfield.h */,
+ 92C115240F8EBBD50048CA8D /* popup.cpp */,
+ 92C115250F8EBBD50048CA8D /* popup.h */,
+ 92C115260F8EBBD50048CA8D /* textfield.cpp */,
+ 92C115270F8EBBD50048CA8D /* textfield.h */,
+ 92C115140F8EBB830048CA8D /* listbox.cpp */,
+ 92C115150F8EBB830048CA8D /* listbox.h */,
+ 92C115160F8EBB830048CA8D /* scrollarea.cpp */,
+ 92C115170F8EBB830048CA8D /* scrollarea.h */,
+ 92C115180F8EBB830048CA8D /* slider.cpp */,
+ 92C115190F8EBB830048CA8D /* slider.h */,
+ 92C1150C0F8EBB360048CA8D /* window.cpp */,
+ 92C1150D0F8EBB360048CA8D /* window.h */,
+ 92DD76450F267B3600B2B519 /* layouthelper.cpp */,
+ 92DD76460F267B3600B2B519 /* layouthelper.h */,
+ 926A29440F23BD88005D6466 /* layout.cpp */,
+ 926A29450F23BD88005D6466 /* layout.h */,
+ 926A29460F23BD88005D6466 /* tab.cpp */,
+ 926A29470F23BD88005D6466 /* tab.h */,
+ 926A29480F23BD88005D6466 /* tabbedarea.cpp */,
+ 926A29490F23BD88005D6466 /* tabbedarea.h */,
+ 924A3A100C07A60B0066885E /* resizegrip.cpp */,
+ 924A3A110C07A60B0066885E /* resizegrip.h */,
+ );
+ path = widgets;
+ sourceTree = "<group>";
+ };
+ 924A3E590C085ED70066885E /* data */ = {
+ isa = PBXGroup;
+ children = (
+ 926A29970F23C97C005D6466 /* fonts */,
+ 924A3E5C0C085ED70066885E /* graphics */,
+ 924A40090C085ED80066885E /* help */,
+ 924A40140C085ED80066885E /* icons */,
+ 924A401C0C085ED80066885E /* items.xsd */,
+ );
+ path = data;
+ sourceTree = "<group>";
+ };
+ 924A3E5C0C085ED70066885E /* graphics */ = {
+ isa = PBXGroup;
+ children = (
+ 92C85CF211F28D2300AB20CA /* sprites */,
+ 924A3E5E0C085ED70066885E /* gui */,
+ 924A3E900C085ED70066885E /* images */,
+ );
+ path = graphics;
+ sourceTree = "<group>";
+ };
+ 924A3E5E0C085ED70066885E /* gui */ = {
+ isa = PBXGroup;
+ children = (
+ 926855E711F141D500A28C33 /* colors.xml */,
+ 926855E811F141D500A28C33 /* progress-indicator.png */,
+ 926855E911F141D500A28C33 /* radioin_highlight.png */,
+ 926855EA11F141D500A28C33 /* radioout_highlight.png */,
+ 926855EB11F141D500A28C33 /* slider_hilight.png */,
+ 926855EC11F141D500A28C33 /* tab_hilight.png */,
+ 926855ED11F141D500A28C33 /* vscroll_highlight.png */,
+ 926855EE11F141D500A28C33 /* window.xml */,
+ 92C637800FC574B500EE8D8D /* window.png */,
+ 92C116010F8EC0590048CA8D /* circle-gray.png */,
+ 92C116020F8EC0590048CA8D /* circle-green.png */,
+ 92C116070F8EC0590048CA8D /* speechbubble.xml */,
+ 92C116080F8EC0590048CA8D /* sticky_button.png */,
+ 928B50E40F2FB5430011C755 /* bubble.png */,
+ 926A297E0F23C18E005D6466 /* tab.png */,
+ 926A297F0F23C18E005D6466 /* tabselected.png */,
+ 92024D5B0CF1BE5C006B55CB /* close_button.png */,
+ 92024D5D0CF1BE5C006B55CB /* unknown-item.png */,
+ 92024D5C0CF1BE5C006B55CB /* item_shortcut_bgr.png */,
+ 924A3E620C085ED70066885E /* button.png */,
+ 924A3E630C085ED70066885E /* button_disabled.png */,
+ 924A3E640C085ED70066885E /* buttonhi.png */,
+ 924A3E650C085ED70066885E /* buttonpress.png */,
+ 924A3E660C085ED70066885E /* checkbox.png */,
+ 924A3E680C085ED70066885E /* deepbox.png */,
+ 924A3E6D0C085ED70066885E /* hscroll_left_default.png */,
+ 924A3E6E0C085ED70066885E /* hscroll_left_highlight.png */,
+ 924A3E6F0C085ED70066885E /* hscroll_left_pressed.png */,
+ 924A3E700C085ED70066885E /* hscroll_right_default.png */,
+ 924A3E710C085ED70066885E /* hscroll_right_highlight.png */,
+ 924A3E720C085ED70066885E /* hscroll_right_pressed.png */,
+ 924A3E780C085ED70066885E /* mouse.png */,
+ 924A3E790C085ED70066885E /* radioin.png */,
+ 924A3E7A0C085ED70066885E /* radioout.png */,
+ 924A3E7B0C085ED70066885E /* resize.png */,
+ 924A3E7E0C085ED70066885E /* selection.png */,
+ 924A3E7F0C085ED70066885E /* slider.png */,
+ 924A3E800C085ED70066885E /* target-cursor-blue-l.png */,
+ 924A3E810C085ED70066885E /* target-cursor-blue-m.png */,
+ 924A3E820C085ED70066885E /* target-cursor-blue-s.png */,
+ 924A3E830C085ED70066885E /* target-cursor-red-l.png */,
+ 924A3E840C085ED70066885E /* target-cursor-red-m.png */,
+ 924A3E850C085ED70066885E /* target-cursor-red-s.png */,
+ 924A3E880C085ED70066885E /* vscroll_down_default.png */,
+ 924A3E890C085ED70066885E /* vscroll_down_highlight.png */,
+ 924A3E8A0C085ED70066885E /* vscroll_down_pressed.png */,
+ 924A3E8B0C085ED70066885E /* vscroll_grey.png */,
+ 924A3E8D0C085ED70066885E /* vscroll_up_default.png */,
+ 924A3E8E0C085ED70066885E /* vscroll_up_highlight.png */,
+ 924A3E8F0C085ED70066885E /* vscroll_up_pressed.png */,
+ );
+ path = gui;
+ sourceTree = "<group>";
+ };
+ 924A3E900C085ED70066885E /* images */ = {
+ isa = PBXGroup;
+ children = (
+ 924A3E9A0C085ED70066885E /* login_wallpaper.png */,
+ );
+ path = images;
+ sourceTree = "<group>";
+ };
+ 924A40090C085ED80066885E /* help */ = {
+ isa = PBXGroup;
+ children = (
+ 926A29840F23C1C8005D6466 /* windows.txt */,
+ 924A400A0C085ED80066885E /* about.txt */,
+ 924A400B0C085ED80066885E /* changes.txt */,
+ 924A400D0C085ED80066885E /* commands.txt */,
+ 924A400E0C085ED80066885E /* header.txt */,
+ 924A400F0C085ED80066885E /* index.txt */,
+ 924A40110C085ED80066885E /* skills.txt */,
+ 924A40120C085ED80066885E /* support.txt */,
+ 924A40130C085ED80066885E /* team.txt */,
+ );
+ path = help;
+ sourceTree = "<group>";
+ };
+ 924A40140C085ED80066885E /* icons */ = {
+ isa = PBXGroup;
+ children = (
+ 926855FF11F141FD00A28C33 /* mana.icns */,
+ );
+ path = icons;
+ sourceTree = "<group>";
+ };
+ 926856BF11F1433E00A28C33 /* manaserv */ = {
+ isa = PBXGroup;
+ children = (
+ 926856C011F1433E00A28C33 /* adminhandler.cpp */,
+ 926856C111F1433E00A28C33 /* adminhandler.h */,
+ 926856C211F1433E00A28C33 /* beinghandler.cpp */,
+ 926856C311F1433E00A28C33 /* beinghandler.h */,
+ 926856C411F1433E00A28C33 /* buysellhandler.cpp */,
+ 926856C511F1433E00A28C33 /* buysellhandler.h */,
+ 926856C611F1433E00A28C33 /* charhandler.cpp */,
+ 926856C711F1433E00A28C33 /* charhandler.h */,
+ 926856C811F1433E00A28C33 /* chathandler.cpp */,
+ 926856C911F1433E00A28C33 /* chathandler.h */,
+ 926856CA11F1433E00A28C33 /* connection.cpp */,
+ 926856CB11F1433E00A28C33 /* connection.h */,
+ 926856CC11F1433E00A28C33 /* effecthandler.cpp */,
+ 926856CD11F1433E00A28C33 /* effecthandler.h */,
+ 926856CE11F1433E00A28C33 /* gamehandler.cpp */,
+ 926856CF11F1433E00A28C33 /* gamehandler.h */,
+ 926856D011F1433E00A28C33 /* generalhandler.cpp */,
+ 926856D111F1433E00A28C33 /* generalhandler.h */,
+ 926856D211F1433E00A28C33 /* guildhandler.cpp */,
+ 926856D311F1433E00A28C33 /* guildhandler.h */,
+ 926856D411F1433E00A28C33 /* internal.cpp */,
+ 926856D511F1433E00A28C33 /* internal.h */,
+ 926856D611F1433E00A28C33 /* inventoryhandler.cpp */,
+ 926856D711F1433E00A28C33 /* inventoryhandler.h */,
+ 926856D811F1433E00A28C33 /* itemhandler.cpp */,
+ 926856D911F1433E00A28C33 /* itemhandler.h */,
+ 926856DA11F1433E00A28C33 /* loginhandler.cpp */,
+ 926856DB11F1433E00A28C33 /* loginhandler.h */,
+ 926856DC11F1433E00A28C33 /* messagehandler.cpp */,
+ 926856DD11F1433E00A28C33 /* messagehandler.h */,
+ 926856DE11F1433E00A28C33 /* messagein.cpp */,
+ 926856DF11F1433E00A28C33 /* messagein.h */,
+ 926856E011F1433E00A28C33 /* messageout.cpp */,
+ 926856E111F1433E00A28C33 /* messageout.h */,
+ 926856E211F1433E00A28C33 /* network.cpp */,
+ 926856E311F1433E00A28C33 /* network.h */,
+ 926856E411F1433E00A28C33 /* npchandler.cpp */,
+ 926856E511F1433E00A28C33 /* npchandler.h */,
+ 926856E611F1433E00A28C33 /* partyhandler.cpp */,
+ 926856E711F1433E00A28C33 /* partyhandler.h */,
+ 926856E811F1433E00A28C33 /* playerhandler.cpp */,
+ 926856E911F1433E00A28C33 /* playerhandler.h */,
+ 926856EA11F1433E00A28C33 /* protocol.h */,
+ 926856EB11F1433E00A28C33 /* specialhandler.cpp */,
+ 926856EC11F1433E00A28C33 /* specialhandler.h */,
+ 926856ED11F1433E00A28C33 /* stats.cpp */,
+ 926856EE11F1433E00A28C33 /* stats.h */,
+ 926856EF11F1433E00A28C33 /* tradehandler.cpp */,
+ 926856F011F1433E00A28C33 /* tradehandler.h */,
+ );
+ path = manaserv;
+ sourceTree = "<group>";
+ };
+ 926856F111F1433E00A28C33 /* tmwa */ = {
+ isa = PBXGroup;
+ children = (
+ 926856F211F1433E00A28C33 /* adminhandler.cpp */,
+ 926856F311F1433E00A28C33 /* adminhandler.h */,
+ 926856F411F1433E00A28C33 /* beinghandler.cpp */,
+ 926856F511F1433E00A28C33 /* beinghandler.h */,
+ 926856F611F1433E00A28C33 /* buysellhandler.cpp */,
+ 926856F711F1433E00A28C33 /* buysellhandler.h */,
+ 926856F811F1433E00A28C33 /* charserverhandler.cpp */,
+ 926856F911F1433E00A28C33 /* charserverhandler.h */,
+ 926856FA11F1433F00A28C33 /* chathandler.cpp */,
+ 926856FB11F1433F00A28C33 /* chathandler.h */,
+ 926856FC11F1433F00A28C33 /* gamehandler.cpp */,
+ 926856FD11F1433F00A28C33 /* gamehandler.h */,
+ 926856FE11F1433F00A28C33 /* generalhandler.cpp */,
+ 926856FF11F1433F00A28C33 /* generalhandler.h */,
+ 9268570011F1433F00A28C33 /* gui */,
+ 9268570511F1433F00A28C33 /* guildhandler.cpp */,
+ 9268570611F1433F00A28C33 /* guildhandler.h */,
+ 9268570711F1433F00A28C33 /* inventoryhandler.cpp */,
+ 9268570811F1433F00A28C33 /* inventoryhandler.h */,
+ 9268570911F1433F00A28C33 /* itemhandler.cpp */,
+ 9268570A11F1433F00A28C33 /* itemhandler.h */,
+ 9268570B11F1433F00A28C33 /* loginhandler.cpp */,
+ 9268570C11F1433F00A28C33 /* loginhandler.h */,
+ 9268570D11F1433F00A28C33 /* messagehandler.cpp */,
+ 9268570E11F1433F00A28C33 /* messagehandler.h */,
+ 9268570F11F1433F00A28C33 /* messagein.cpp */,
+ 9268571011F1433F00A28C33 /* messagein.h */,
+ 9268571111F1433F00A28C33 /* messageout.cpp */,
+ 9268571211F1433F00A28C33 /* messageout.h */,
+ 9268571311F1433F00A28C33 /* network.cpp */,
+ 9268571411F1433F00A28C33 /* network.h */,
+ 9268571511F1433F00A28C33 /* npchandler.cpp */,
+ 9268571611F1433F00A28C33 /* npchandler.h */,
+ 9268571711F1433F00A28C33 /* partyhandler.cpp */,
+ 9268571811F1433F00A28C33 /* partyhandler.h */,
+ 9268571911F1433F00A28C33 /* playerhandler.cpp */,
+ 9268571A11F1433F00A28C33 /* playerhandler.h */,
+ 9268571B11F1433F00A28C33 /* protocol.h */,
+ 9268571C11F1433F00A28C33 /* specialhandler.cpp */,
+ 9268571D11F1433F00A28C33 /* specialhandler.h */,
+ 9268571E11F1433F00A28C33 /* token.h */,
+ 9268571F11F1433F00A28C33 /* tradehandler.cpp */,
+ 9268572011F1433F00A28C33 /* tradehandler.h */,
+ );
+ path = tmwa;
+ sourceTree = "<group>";
+ };
+ 9268570011F1433F00A28C33 /* gui */ = {
+ isa = PBXGroup;
+ children = (
+ 9268570111F1433F00A28C33 /* guildtab.cpp */,
+ 9268570211F1433F00A28C33 /* guildtab.h */,
+ 9268570311F1433F00A28C33 /* partytab.cpp */,
+ 9268570411F1433F00A28C33 /* partytab.h */,
+ );
+ path = gui;
+ sourceTree = "<group>";
+ };
+ 926A29970F23C97C005D6466 /* fonts */ = {
+ isa = PBXGroup;
+ children = (
+ 92C637850FC5751700EE8D8D /* dejavusans-bold.ttf */,
+ 926A29980F23C988005D6466 /* dejavusans.ttf */,
+ );
+ name = fonts;
+ sourceTree = "<group>";
+ };
+ 92BC3EF00BAEE55A000DAB7F /* gui */ = {
+ isa = PBXGroup;
+ children = (
+ 9268565811F142F100A28C33 /* beingpopup.cpp */,
+ 9268565911F142F100A28C33 /* beingpopup.h */,
+ 9268565A11F142F100A28C33 /* connectiondialog.cpp */,
+ 9268565B11F142F100A28C33 /* connectiondialog.h */,
+ 9268565C11F142F100A28C33 /* socialwindow.cpp */,
+ 9268565D11F142F100A28C33 /* socialwindow.h */,
+ 9268565E11F142F100A28C33 /* specialswindow.cpp */,
+ 9268565F11F142F100A28C33 /* specialswindow.h */,
+ 9268566011F142F100A28C33 /* textpopup.cpp */,
+ 9268566111F142F100A28C33 /* textpopup.h */,
+ 9268566211F142F100A28C33 /* theme.cpp */,
+ 9268566311F142F100A28C33 /* theme.h */,
+ 9268566411F142F100A28C33 /* userpalette.cpp */,
+ 9268566511F142F100A28C33 /* userpalette.h */,
+ 9268566611F142F100A28C33 /* worldselectdialog.cpp */,
+ 9268566711F142F100A28C33 /* worldselectdialog.h */,
+ 92C636C40FC5670700EE8D8D /* charselectdialog.cpp */,
+ 92C636C50FC5670700EE8D8D /* charselectdialog.h */,
+ 92C636C60FC5670700EE8D8D /* confirmdialog.cpp */,
+ 92C636C70FC5670700EE8D8D /* confirmdialog.h */,
+ 92C636C80FC5670700EE8D8D /* emotepopup.cpp */,
+ 92C636C90FC5670700EE8D8D /* emotepopup.h */,
+ 92C636CA0FC5670700EE8D8D /* itemamount.cpp */,
+ 92C636CB0FC5670700EE8D8D /* itemamount.h */,
+ 92C636CC0FC5670700EE8D8D /* npcdialog.cpp */,
+ 92C636CD0FC5670700EE8D8D /* npcdialog.h */,
+ 92C636CE0FC5670700EE8D8D /* okdialog.cpp */,
+ 92C636CF0FC5670700EE8D8D /* okdialog.h */,
+ 92C636D00FC5670700EE8D8D /* outfitwindow.cpp */,
+ 92C636D10FC5670700EE8D8D /* outfitwindow.h */,
+ 92C636D50FC5670700EE8D8D /* windowmenu.cpp */,
+ 92C636D60FC5670700EE8D8D /* windowmenu.h */,
+ 92C119830F8ED80E0048CA8D /* serverdialog.cpp */,
+ 92C119840F8ED80E0048CA8D /* serverdialog.h */,
+ 92C1191B0F8ED79A0048CA8D /* changeemaildialog.cpp */,
+ 92C1191C0F8ED79A0048CA8D /* changeemaildialog.h */,
+ 92C119010F8ED63F0048CA8D /* npcpostdialog.cpp */,
+ 92C119020F8ED63F0048CA8D /* npcpostdialog.h */,
+ 92C118F20F8ED5DE0048CA8D /* textdialog.cpp */,
+ 92C118F30F8ED5DE0048CA8D /* textdialog.h */,
+ 92C1186F0F8ED33F0048CA8D /* quitdialog.cpp */,
+ 92C118700F8ED33F0048CA8D /* quitdialog.h */,
+ 92C117560F8ECF0B0048CA8D /* statuswindow.cpp */,
+ 92C117570F8ECF0B0048CA8D /* statuswindow.h */,
+ 92C117580F8ECF0B0048CA8D /* unregisterdialog.cpp */,
+ 92C117590F8ECF0B0048CA8D /* unregisterdialog.h */,
+ 92C117530F8ECEEA0048CA8D /* skilldialog.cpp */,
+ 92C117540F8ECEEA0048CA8D /* skilldialog.h */,
+ 92C116E40F8ECBE80048CA8D /* changepassworddialog.cpp */,
+ 92C116E50F8ECBE80048CA8D /* changepassworddialog.h */,
+ 92C115F90F8EBFF30048CA8D /* setup_colors.cpp */,
+ 92C115FA0F8EBFF30048CA8D /* setup_colors.h */,
+ 92C115C70F8EBECE0048CA8D /* charcreatedialog.cpp */,
+ 92C115C80F8EBECE0048CA8D /* charcreatedialog.h */,
+ 92C115AD0F8EBE450048CA8D /* palette.cpp */,
+ 92C115AE0F8EBE450048CA8D /* palette.h */,
+ 92C115B50F8EBE450048CA8D /* speechbubble.cpp */,
+ 92C115B60F8EBE450048CA8D /* speechbubble.h */,
+ 92C115410F8EBCB70048CA8D /* shortcutwindow.cpp */,
+ 92C115420F8EBCB70048CA8D /* shortcutwindow.h */,
+ 92C115100F8EBB550048CA8D /* itempopup.cpp */,
+ 92C115110F8EBB550048CA8D /* itempopup.h */,
+ 926A29520F23BD9E005D6466 /* sdlinput.cpp */,
+ 926A29530F23BD9E005D6466 /* sdlinput.h */,
+ 926A29540F23BD9E005D6466 /* truetypefont.cpp */,
+ 926A29550F23BD9E005D6466 /* truetypefont.h */,
+ 92FD19B30DDCE53400D14E5D /* setup_players.cpp */,
+ 92FD19B40DDCE53400D14E5D /* setup_players.h */,
+ 92024D360CF1BDF7006B55CB /* setup_keyboard.cpp */,
+ 92024D370CF1BDF7006B55CB /* setup_keyboard.h */,
+ 924A3A0F0C07A60B0066885E /* widgets */,
+ 92BC3EF90BAEE55A000DAB7F /* buy.cpp */,
+ 92BC3EFA0BAEE55A000DAB7F /* buy.h */,
+ 92BC3EFB0BAEE55A000DAB7F /* buysell.cpp */,
+ 92BC3EFC0BAEE55A000DAB7F /* buysell.h */,
+ 92BC3F030BAEE55A000DAB7F /* chat.cpp */,
+ 92BC3F040BAEE55A000DAB7F /* chat.h */,
+ 92BC3F0D0BAEE55A000DAB7F /* debugwindow.cpp */,
+ 92BC3F0E0BAEE55A000DAB7F /* debugwindow.h */,
+ 92BC3F0F0BAEE55A000DAB7F /* equipmentwindow.cpp */,
+ 92BC3F100BAEE55A000DAB7F /* equipmentwindow.h */,
+ 92BC3F110BAEE55A000DAB7F /* focushandler.cpp */,
+ 92BC3F120BAEE55A000DAB7F /* focushandler.h */,
+ 92BC3F150BAEE55A000DAB7F /* gui.cpp */,
+ 92BC3F160BAEE55A000DAB7F /* gui.h */,
+ 92BC3F190BAEE55A000DAB7F /* help.cpp */,
+ 92BC3F1A0BAEE55A000DAB7F /* help.h */,
+ 92BC3F1D0BAEE55A000DAB7F /* inventorywindow.cpp */,
+ 92BC3F1E0BAEE55A000DAB7F /* inventorywindow.h */,
+ 92BC3F260BAEE55A000DAB7F /* login.cpp */,
+ 92BC3F270BAEE55A000DAB7F /* login.h */,
+ 92BC3F2A0BAEE55A000DAB7F /* minimap.cpp */,
+ 92BC3F2B0BAEE55A000DAB7F /* minimap.h */,
+ 92BC3F2C0BAEE55A000DAB7F /* ministatus.cpp */,
+ 92BC3F2D0BAEE55A000DAB7F /* ministatus.h */,
+ 92BC3F3A0BAEE55A000DAB7F /* popupmenu.cpp */,
+ 92BC3F3B0BAEE55A000DAB7F /* popupmenu.h */,
+ 92BC3F400BAEE55A000DAB7F /* register.cpp */,
+ 92BC3F410BAEE55A000DAB7F /* register.h */,
+ 92BC3F450BAEE55A000DAB7F /* sell.cpp */,
+ 92BC3F460BAEE55A000DAB7F /* sell.h */,
+ 92BC3F470BAEE55A000DAB7F /* setup.cpp */,
+ 92BC3F480BAEE55A000DAB7F /* setup.h */,
+ 92BC3F490BAEE55A000DAB7F /* setup_audio.cpp */,
+ 92BC3F4A0BAEE55A000DAB7F /* setup_audio.h */,
+ 92BC3F4B0BAEE55A000DAB7F /* setup_joystick.cpp */,
+ 92BC3F4C0BAEE55A000DAB7F /* setup_joystick.h */,
+ 92BC3F4D0BAEE55A000DAB7F /* setup_video.cpp */,
+ 92BC3F4E0BAEE55A000DAB7F /* setup_video.h */,
+ 92BC3F600BAEE55B000DAB7F /* trade.cpp */,
+ 92BC3F610BAEE55B000DAB7F /* trade.h */,
+ 92BC3F620BAEE55B000DAB7F /* updatewindow.cpp */,
+ 92BC3F630BAEE55B000DAB7F /* updatewindow.h */,
+ 92BC3F660BAEE55B000DAB7F /* viewport.cpp */,
+ 92BC3F670BAEE55B000DAB7F /* viewport.h */,
+ );
+ name = gui;
+ path = src/gui;
+ sourceTree = "<group>";
+ };
+ 92BC3F800BAEE55B000DAB7F /* net */ = {
+ isa = PBXGroup;
+ children = (
+ 926856BF11F1433E00A28C33 /* manaserv */,
+ 926856F111F1433E00A28C33 /* tmwa */,
+ 926856B511F1433300A28C33 /* charhandler.cpp */,
+ 926856B611F1433300A28C33 /* download.cpp */,
+ 926856B711F1433300A28C33 /* download.h */,
+ 926856B811F1433300A28C33 /* gamehandler.h */,
+ 926856B911F1433300A28C33 /* specialhandler.h */,
+ 926856BA11F1433300A28C33 /* worldinfo.h */,
+ 92C636EA0FC5677500EE8D8D /* adminhandler.h */,
+ 92C636EB0FC5677500EE8D8D /* charhandler.h */,
+ 92C636EC0FC5677500EE8D8D /* generalhandler.h */,
+ 92C636ED0FC5677500EE8D8D /* guildhandler.h */,
+ 92C636EE0FC5677500EE8D8D /* logindata.h */,
+ 92C636F10FC5677500EE8D8D /* partyhandler.h */,
+ 92C636F20FC5677500EE8D8D /* serverinfo.h */,
+ 92C115570F8EBD490048CA8D /* net.cpp */,
+ 92C115580F8EBD490048CA8D /* net.h */,
+ 92BC3F880BAEE55B000DAB7F /* chathandler.h */,
+ 92BC3F8C0BAEE55B000DAB7F /* inventoryhandler.h */,
+ 92BC3F900BAEE55B000DAB7F /* loginhandler.h */,
+ 92BC3F940BAEE55B000DAB7F /* messagehandler.h */,
+ 92BC3F950BAEE55B000DAB7F /* messagein.cpp */,
+ 92BC3F960BAEE55B000DAB7F /* messagein.h */,
+ 92BC3F970BAEE55B000DAB7F /* messageout.cpp */,
+ 92BC3F980BAEE55B000DAB7F /* messageout.h */,
+ 92BC3F9C0BAEE55B000DAB7F /* npchandler.h */,
+ 92BC3F9E0BAEE55B000DAB7F /* playerhandler.h */,
+ 92BC3FA40BAEE55B000DAB7F /* tradehandler.h */,
+ );
+ name = net;
+ path = src/net;
+ sourceTree = "<group>";
+ };
+ 92BC3FBD0BAEE55B000DAB7F /* resources */ = {
+ isa = PBXGroup;
+ children = (
+ 9268577D11F1435200A28C33 /* ambientlayer.cpp */,
+ 9268577E11F1435200A28C33 /* ambientlayer.h */,
+ 92C115CE0F8EBF1C0048CA8D /* colordb.cpp */,
+ 92C115CF0F8EBF1C0048CA8D /* colordb.h */,
+ 92C115D00F8EBF1C0048CA8D /* wallpaper.cpp */,
+ 92C115D10F8EBF1C0048CA8D /* wallpaper.h */,
+ 92C115990F8EBD900048CA8D /* emotedb.cpp */,
+ 92C1159A0F8EBD900048CA8D /* emotedb.h */,
+ 922CD9560E3D00900074C50E /* npcdb.cpp */,
+ 922CD9570E3D00900074C50E /* npcdb.h */,
+ 92A4CC9D0D1C622E00CA28FB /* dye.cpp */,
+ 92FD19BD0DDCE56A00D14E5D /* dye.h */,
+ 92024E740CF1DCF6006B55CB /* imageloader.cpp */,
+ 92024E750CF1DCF6006B55CB /* imageloader.h */,
+ 925350010BC12A3200115FD5 /* imageset.cpp */,
+ 925350020BC12A3200115FD5 /* imageset.h */,
+ 92BC3FBE0BAEE55B000DAB7F /* action.cpp */,
+ 92BC3FBF0BAEE55B000DAB7F /* action.h */,
+ 92BC3FC00BAEE55B000DAB7F /* ambientoverlay.cpp */,
+ 92BC3FC10BAEE55B000DAB7F /* ambientoverlay.h */,
+ 92BC3FC20BAEE55B000DAB7F /* animation.cpp */,
+ 92BC3FC30BAEE55B000DAB7F /* animation.h */,
+ 92BC3FC90BAEE55B000DAB7F /* image.cpp */,
+ 92BC3FCA0BAEE55B000DAB7F /* image.h */,
+ 92BC3FCB0BAEE55B000DAB7F /* imagewriter.cpp */,
+ 92BC3FCC0BAEE55B000DAB7F /* imagewriter.h */,
+ 92BC3FCD0BAEE55B000DAB7F /* itemdb.cpp */,
+ 92BC3FCE0BAEE55B000DAB7F /* itemdb.h */,
+ 92BC3FCF0BAEE55B000DAB7F /* iteminfo.cpp */,
+ 92BC3FD00BAEE55B000DAB7F /* iteminfo.h */,
+ 92BC3FD10BAEE55B000DAB7F /* mapreader.cpp */,
+ 92BC3FD20BAEE55B000DAB7F /* mapreader.h */,
+ 92BC3FD30BAEE55B000DAB7F /* monsterdb.cpp */,
+ 92BC3FD40BAEE55B000DAB7F /* monsterdb.h */,
+ 92BC3FD50BAEE55B000DAB7F /* monsterinfo.cpp */,
+ 92BC3FD60BAEE55B000DAB7F /* monsterinfo.h */,
+ 92BC3FD70BAEE55B000DAB7F /* music.cpp */,
+ 92BC3FD80BAEE55B000DAB7F /* music.h */,
+ 92BC3FDB0BAEE55B000DAB7F /* resource.cpp */,
+ 92BC3FDC0BAEE55B000DAB7F /* resource.h */,
+ 92BC3FDD0BAEE55B000DAB7F /* resourcemanager.cpp */,
+ 92BC3FDE0BAEE55B000DAB7F /* resourcemanager.h */,
+ 92BC3FE10BAEE55B000DAB7F /* soundeffect.cpp */,
+ 92BC3FE20BAEE55B000DAB7F /* soundeffect.h */,
+ 92BC3FE30BAEE55B000DAB7F /* spritedef.cpp */,
+ 92BC3FE40BAEE55B000DAB7F /* spritedef.h */,
+ );
+ name = resources;
+ path = src/resources;
+ sourceTree = "<group>";
+ };
+ 92BC3FEE0BAEE55B000DAB7F /* utils */ = {
+ isa = PBXGroup;
+ children = (
+ 9268578111F1435F00A28C33 /* copynpaste.cpp */,
+ 9268578211F1435F00A28C33 /* copynpaste.h */,
+ 9268578311F1435F00A28C33 /* mkdir.cpp */,
+ 9268578411F1435F00A28C33 /* mkdir.h */,
+ 9268578511F1435F00A28C33 /* specialfolder.cpp */,
+ 9268578611F1435F00A28C33 /* specialfolder.h */,
+ 92C636AF0FC5605300EE8D8D /* mathutils.h */,
+ 92C1198E0F8ED85E0048CA8D /* sha256.cpp */,
+ 92C1198F0F8ED85E0048CA8D /* sha256.h */,
+ 92C115E80F8EBFA60048CA8D /* stringutils.cpp */,
+ 92C115E90F8EBFA60048CA8D /* stringutils.h */,
+ 926A295A0F23BDB1005D6466 /* gettext.h */,
+ 926A295B0F23BDB1005D6466 /* mutex.h */,
+ 92BC3FEF0BAEE55B000DAB7F /* base64.cpp */,
+ 92BC3FF00BAEE55B000DAB7F /* base64.h */,
+ 92BC3FF10BAEE55B000DAB7F /* dtor.h */,
+ 92BC3FF40BAEE55B000DAB7F /* xml.cpp */,
+ 92BC3FF50BAEE55B000DAB7F /* xml.h */,
+ );
+ name = utils;
+ path = src/utils;
+ sourceTree = "<group>";
+ };
+ 92C85CF211F28D2300AB20CA /* sprites */ = {
+ isa = PBXGroup;
+ children = (
+ 92C85CF411F28D2300AB20CA /* error.png */,
+ 92C85CF511F28D2300AB20CA /* error.xml */,
+ );
+ path = sprites;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D0C4E890486CD37000505A6 /* themanaworld */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C0E91AC508A95435008D54AB /* Build configuration list for PBXNativeTarget "themanaworld" */;
+ buildPhases = (
+ 8D0C4E8C0486CD37000505A6 /* Resources */,
+ 8D0C4E8F0486CD37000505A6 /* Sources */,
+ 8D0C4E910486CD37000505A6 /* Frameworks */,
+ 924A3A520C085C190066885E /* Copy Data Files */,
+ 924A3E540C085CAF0066885E /* Copy GUI Files */,
+ 924A40880C085FBD0066885E /* Copy Image Files */,
+ 924A42000C0861C70066885E /* Copy Help Files */,
+ 92EEA0090D2E20D100DDE300 /* Copy Frameworks */,
+ 9273BE3C0EF34050008E56E1 /* Copy Music Files */,
+ 926A29AA0F23CA6D005D6466 /* Copy Font Files */,
+ 922890C411F661D000AE53BB /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = themanaworld;
+ productInstallPath = "$(HOME)/Applications";
+ productName = themanaworld;
+ productReference = 508344B209E5C41E0093A071 /* The Mana World.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 20286C28FDCF999611CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C0E91AC908A95435008D54AB /* Build configuration list for PBXProject "mana" */;
+ compatibilityVersion = "Xcode 3.0";
+ hasScannedForEncodings = 1;
+ mainGroup = 20286C29FDCF999611CA2CEA /* themanaworld */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8D0C4E890486CD37000505A6 /* themanaworld */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D0C4E8C0486CD37000505A6 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9273BDFC0EF33DFD008E56E1 /* COPYING in Resources */,
+ 9273BDFF0EF33E1A008E56E1 /* AUTHORS in Resources */,
+ 9273BE000EF33E1A008E56E1 /* README in Resources */,
+ 92EA98B40FC5CB17003DC005 /* SDLMain.nib in Resources */,
+ 9268560011F141FD00A28C33 /* mana.icns in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 922890C411F661D000AE53BB /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "#app\ninstall_name_tool -change /opt/local/lib/libphysfs.1.dylib @executable_path/../Frameworks/libphysfs.1.dylib \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Contents/MacOS/${PRODUCT_NAME}\"\ninstall_name_tool -change /opt/local/lib/libintl.8.dylib @executable_path/../Frameworks/libintl.8.dylib \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Contents/MacOS/${PRODUCT_NAME}\"\ninstall_name_tool -change /opt/local/lib/libSDL_gfx.13.dylib @executable_path/../Frameworks/libSDL_gfx.13.dylib \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Contents/MacOS/${PRODUCT_NAME}\"";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D0C4E8F0486CD37000505A6 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 92BC3FF60BAEE55B000DAB7F /* animatedsprite.cpp in Sources */,
+ 92BC3FF70BAEE55B000DAB7F /* being.cpp in Sources */,
+ 92BC3FF80BAEE55B000DAB7F /* beingmanager.cpp in Sources */,
+ 92BC3FFA0BAEE55B000DAB7F /* configuration.cpp in Sources */,
+ 92BC40050BAEE55B000DAB7F /* flooritemmanager.cpp in Sources */,
+ 92BC40060BAEE55B000DAB7F /* game.cpp in Sources */,
+ 92BC40070BAEE55B000DAB7F /* graphics.cpp in Sources */,
+ 92BC400C0BAEE55B000DAB7F /* buy.cpp in Sources */,
+ 92BC400D0BAEE55B000DAB7F /* buysell.cpp in Sources */,
+ 92BC40110BAEE55B000DAB7F /* chat.cpp in Sources */,
+ 92BC40160BAEE55B000DAB7F /* debugwindow.cpp in Sources */,
+ 92BC40170BAEE55B000DAB7F /* equipmentwindow.cpp in Sources */,
+ 92BC40180BAEE55B000DAB7F /* focushandler.cpp in Sources */,
+ 92BC401A0BAEE55B000DAB7F /* gui.cpp in Sources */,
+ 92BC401C0BAEE55B000DAB7F /* help.cpp in Sources */,
+ 92BC401E0BAEE55B000DAB7F /* inventorywindow.cpp in Sources */,
+ 92BC40220BAEE55B000DAB7F /* login.cpp in Sources */,
+ 92BC40240BAEE55B000DAB7F /* minimap.cpp in Sources */,
+ 92BC40250BAEE55B000DAB7F /* ministatus.cpp in Sources */,
+ 92BC402C0BAEE55B000DAB7F /* popupmenu.cpp in Sources */,
+ 92BC402F0BAEE55B000DAB7F /* register.cpp in Sources */,
+ 92BC40310BAEE55B000DAB7F /* sell.cpp in Sources */,
+ 92BC40320BAEE55B000DAB7F /* setup.cpp in Sources */,
+ 92BC40330BAEE55B000DAB7F /* setup_audio.cpp in Sources */,
+ 92BC40340BAEE55B000DAB7F /* setup_joystick.cpp in Sources */,
+ 92BC40350BAEE55B000DAB7F /* setup_video.cpp in Sources */,
+ 92BC403E0BAEE55B000DAB7F /* trade.cpp in Sources */,
+ 92BC403F0BAEE55B000DAB7F /* updatewindow.cpp in Sources */,
+ 92BC40410BAEE55B000DAB7F /* viewport.cpp in Sources */,
+ 92BC40440BAEE55B000DAB7F /* inventory.cpp in Sources */,
+ 92BC40450BAEE55B000DAB7F /* item.cpp in Sources */,
+ 92BC40460BAEE55B000DAB7F /* joystick.cpp in Sources */,
+ 92BC40470BAEE55B000DAB7F /* localplayer.cpp in Sources */,
+ 92BC40480BAEE55B000DAB7F /* log.cpp in Sources */,
+ 92BC40490BAEE55B000DAB7F /* main.cpp in Sources */,
+ 92BC404B0BAEE55B000DAB7F /* map.cpp in Sources */,
+ 92BC404C0BAEE55B000DAB7F /* monster.cpp in Sources */,
+ 92BC40570BAEE55B000DAB7F /* messagein.cpp in Sources */,
+ 92BC40580BAEE55B000DAB7F /* messageout.cpp in Sources */,
+ 92BC405F0BAEE55B000DAB7F /* npc.cpp in Sources */,
+ 92BC40600BAEE55B000DAB7F /* openglgraphics.cpp in Sources */,
+ 92BC406E0BAEE55B000DAB7F /* player.cpp in Sources */,
+ 92BC406F0BAEE55B000DAB7F /* action.cpp in Sources */,
+ 92BC40700BAEE55B000DAB7F /* ambientoverlay.cpp in Sources */,
+ 92BC40710BAEE55B000DAB7F /* animation.cpp in Sources */,
+ 92BC40740BAEE55B000DAB7F /* image.cpp in Sources */,
+ 92BC40750BAEE55B000DAB7F /* imagewriter.cpp in Sources */,
+ 92BC40760BAEE55B000DAB7F /* itemdb.cpp in Sources */,
+ 92BC40770BAEE55B000DAB7F /* iteminfo.cpp in Sources */,
+ 92BC40780BAEE55B000DAB7F /* mapreader.cpp in Sources */,
+ 92BC40790BAEE55B000DAB7F /* monsterdb.cpp in Sources */,
+ 92BC407A0BAEE55B000DAB7F /* monsterinfo.cpp in Sources */,
+ 92BC407B0BAEE55B000DAB7F /* music.cpp in Sources */,
+ 92BC407D0BAEE55B000DAB7F /* resource.cpp in Sources */,
+ 92BC407E0BAEE55B000DAB7F /* resourcemanager.cpp in Sources */,
+ 92BC40800BAEE55B000DAB7F /* soundeffect.cpp in Sources */,
+ 92BC40810BAEE55B000DAB7F /* spritedef.cpp in Sources */,
+ 92BC40830BAEE55B000DAB7F /* simpleanimation.cpp in Sources */,
+ 92BC40840BAEE55B000DAB7F /* sound.cpp in Sources */,
+ 92BC40850BAEE55B000DAB7F /* base64.cpp in Sources */,
+ 92BC40860BAEE55B000DAB7F /* xml.cpp in Sources */,
+ 92BC40E60BAEF54B000DAB7F /* SDLMain.m in Sources */,
+ 925350030BC12A3200115FD5 /* imageset.cpp in Sources */,
+ 924A39F20C0784280066885E /* animationparticle.cpp in Sources */,
+ 924A39F30C0784280066885E /* imageparticle.cpp in Sources */,
+ 924A39F40C0784280066885E /* particle.cpp in Sources */,
+ 924A39F50C0784280066885E /* particleemitter.cpp in Sources */,
+ 924A39F60C0784280066885E /* textparticle.cpp in Sources */,
+ 924A3A120C07A60B0066885E /* resizegrip.cpp in Sources */,
+ 92024D2F0CF1BD9E006B55CB /* keyboardconfig.cpp in Sources */,
+ 92024D3D0CF1BDF7006B55CB /* setup_keyboard.cpp in Sources */,
+ 92024E760CF1DCF6006B55CB /* imageloader.cpp in Sources */,
+ 92A4CC9E0D1C622E00CA28FB /* dye.cpp in Sources */,
+ 926F9CF80DB005FA00AACD26 /* itemshortcut.cpp in Sources */,
+ 92FD19BA0DDCE53400D14E5D /* setup_players.cpp in Sources */,
+ 922CD9580E3D00900074C50E /* npcdb.cpp in Sources */,
+ 922CD95F0E3D01080074C50E /* shopitem.cpp in Sources */,
+ 92037A1F0ED2037300D3712D /* text.cpp in Sources */,
+ 92037A200ED2037300D3712D /* textmanager.cpp in Sources */,
+ 9273BE080EF33FB3008E56E1 /* particlecontainer.cpp in Sources */,
+ 9273BE090EF33FB3008E56E1 /* statuseffect.cpp in Sources */,
+ 926A294A0F23BD88005D6466 /* layout.cpp in Sources */,
+ 926A294B0F23BD88005D6466 /* tab.cpp in Sources */,
+ 926A294C0F23BD88005D6466 /* tabbedarea.cpp in Sources */,
+ 926A29580F23BD9E005D6466 /* sdlinput.cpp in Sources */,
+ 926A29590F23BD9E005D6466 /* truetypefont.cpp in Sources */,
+ 92DD76470F267B3600B2B519 /* layouthelper.cpp in Sources */,
+ 92C1150E0F8EBB360048CA8D /* window.cpp in Sources */,
+ 92C115120F8EBB550048CA8D /* itempopup.cpp in Sources */,
+ 92C1151A0F8EBB830048CA8D /* listbox.cpp in Sources */,
+ 92C1151B0F8EBB830048CA8D /* scrollarea.cpp in Sources */,
+ 92C1151C0F8EBB830048CA8D /* slider.cpp in Sources */,
+ 92C115200F8EBBA90048CA8D /* emoteshortcut.cpp in Sources */,
+ 92C115280F8EBBD50048CA8D /* inttextfield.cpp in Sources */,
+ 92C115290F8EBBD50048CA8D /* popup.cpp in Sources */,
+ 92C1152A0F8EBBD50048CA8D /* textfield.cpp in Sources */,
+ 92C115360F8EBC450048CA8D /* browserbox.cpp in Sources */,
+ 92C115370F8EBC450048CA8D /* windowcontainer.cpp in Sources */,
+ 92C1153B0F8EBC730048CA8D /* chattab.cpp in Sources */,
+ 92C115440F8EBCB70048CA8D /* shortcutwindow.cpp in Sources */,
+ 92C115470F8EBCD00048CA8D /* passwordfield.cpp in Sources */,
+ 92C1154D0F8EBD000048CA8D /* checkbox.cpp in Sources */,
+ 92C1154E0F8EBD000048CA8D /* textbox.cpp in Sources */,
+ 92C115540F8EBD250048CA8D /* label.cpp in Sources */,
+ 92C115550F8EBD250048CA8D /* progressbar.cpp in Sources */,
+ 92C115590F8EBD490048CA8D /* net.cpp in Sources */,
+ 92C1159B0F8EBD900048CA8D /* emotedb.cpp in Sources */,
+ 92C115A20F8EBDB20048CA8D /* commandhandler.cpp in Sources */,
+ 92C115A30F8EBDB20048CA8D /* effectmanager.cpp in Sources */,
+ 92C115A40F8EBDB20048CA8D /* units.cpp in Sources */,
+ 92C115B70F8EBE450048CA8D /* palette.cpp in Sources */,
+ 92C115B90F8EBE450048CA8D /* recorder.cpp in Sources */,
+ 92C115BB0F8EBE450048CA8D /* speechbubble.cpp in Sources */,
+ 92C115BF0F8EBE5E0048CA8D /* channeltab.cpp in Sources */,
+ 92C115C60F8EBE950048CA8D /* whispertab.cpp in Sources */,
+ 92C115C90F8EBECE0048CA8D /* charcreatedialog.cpp in Sources */,
+ 92C115CD0F8EBF090048CA8D /* channelmanager.cpp in Sources */,
+ 92C115D20F8EBF1C0048CA8D /* colordb.cpp in Sources */,
+ 92C115D30F8EBF1C0048CA8D /* wallpaper.cpp in Sources */,
+ 92C115DB0F8EBF530048CA8D /* button.cpp in Sources */,
+ 92C115DC0F8EBF530048CA8D /* icon.cpp in Sources */,
+ 92C115DD0F8EBF530048CA8D /* radiobutton.cpp in Sources */,
+ 92C115EA0F8EBFA60048CA8D /* stringutils.cpp in Sources */,
+ 92C115EE0F8EBFC20048CA8D /* channel.cpp in Sources */,
+ 92C115F70F8EBFDD0048CA8D /* dropdown.cpp in Sources */,
+ 92C115FB0F8EBFF30048CA8D /* setup_colors.cpp in Sources */,
+ 92C115FF0F8EC0150048CA8D /* textpreview.cpp in Sources */,
+ 92A245C40F93626900B7719B /* desktop.cpp in Sources */,
+ 92A245C50F93626C00B7719B /* container.cpp in Sources */,
+ 92A245CC0F93635800B7719B /* npcpostdialog.cpp in Sources */,
+ 92C636BB0FC5663000EE8D8D /* flooritem.cpp in Sources */,
+ 92C636BC0FC5663000EE8D8D /* playerrelations.cpp in Sources */,
+ 92C636BD0FC5663000EE8D8D /* rotationalparticle.cpp in Sources */,
+ 92C636BE0FC5663000EE8D8D /* vector.cpp in Sources */,
+ 92C636D70FC5670700EE8D8D /* charselectdialog.cpp in Sources */,
+ 92C636D80FC5670700EE8D8D /* confirmdialog.cpp in Sources */,
+ 92C636D90FC5670700EE8D8D /* emotepopup.cpp in Sources */,
+ 92C636DA0FC5670700EE8D8D /* itemamount.cpp in Sources */,
+ 92C636DB0FC5670700EE8D8D /* npcdialog.cpp in Sources */,
+ 92C636DC0FC5670700EE8D8D /* okdialog.cpp in Sources */,
+ 92C636DD0FC5670700EE8D8D /* outfitwindow.cpp in Sources */,
+ 92C636DF0FC5670700EE8D8D /* windowmenu.cpp in Sources */,
+ 9268565211F142D500A28C33 /* avatar.cpp in Sources */,
+ 9268565311F142D500A28C33 /* client.cpp in Sources */,
+ 9268565411F142D500A28C33 /* party.cpp in Sources */,
+ 9268566811F142F100A28C33 /* beingpopup.cpp in Sources */,
+ 9268566911F142F100A28C33 /* connectiondialog.cpp in Sources */,
+ 9268566A11F142F100A28C33 /* socialwindow.cpp in Sources */,
+ 9268566B11F142F100A28C33 /* specialswindow.cpp in Sources */,
+ 9268566C11F142F100A28C33 /* textpopup.cpp in Sources */,
+ 9268566D11F142F100A28C33 /* theme.cpp in Sources */,
+ 9268566E11F142F100A28C33 /* userpalette.cpp in Sources */,
+ 9268566F11F142F100A28C33 /* worldselectdialog.cpp in Sources */,
+ 9268569711F1431300A28C33 /* avatarlistbox.cpp in Sources */,
+ 9268569811F1431300A28C33 /* emoteshortcutcontainer.cpp in Sources */,
+ 9268569911F1431300A28C33 /* flowcontainer.cpp in Sources */,
+ 9268569A11F1431300A28C33 /* itemcontainer.cpp in Sources */,
+ 9268569B11F1431300A28C33 /* itemlinkhandler.cpp in Sources */,
+ 9268569C11F1431300A28C33 /* itemshortcutcontainer.cpp in Sources */,
+ 9268569D11F1431300A28C33 /* playerbox.cpp in Sources */,
+ 9268569E11F1431300A28C33 /* progressindicator.cpp in Sources */,
+ 9268569F11F1431300A28C33 /* setuptab.cpp in Sources */,
+ 926856A011F1431300A28C33 /* shopitems.cpp in Sources */,
+ 926856A111F1431300A28C33 /* shoplistbox.cpp in Sources */,
+ 926856A211F1431300A28C33 /* shortcutcontainer.cpp in Sources */,
+ 926856A311F1431300A28C33 /* table.cpp in Sources */,
+ 926856A411F1431300A28C33 /* tablemodel.cpp in Sources */,
+ 926856A511F1431300A28C33 /* vertcontainer.cpp in Sources */,
+ 926856BB11F1433300A28C33 /* charhandler.cpp in Sources */,
+ 926856BC11F1433300A28C33 /* download.cpp in Sources */,
+ 9268573911F1433F00A28C33 /* adminhandler.cpp in Sources */,
+ 9268573A11F1433F00A28C33 /* beinghandler.cpp in Sources */,
+ 9268573B11F1433F00A28C33 /* buysellhandler.cpp in Sources */,
+ 9268573C11F1433F00A28C33 /* charserverhandler.cpp in Sources */,
+ 9268573D11F1433F00A28C33 /* chathandler.cpp in Sources */,
+ 9268573E11F1433F00A28C33 /* gamehandler.cpp in Sources */,
+ 9268573F11F1433F00A28C33 /* generalhandler.cpp in Sources */,
+ 9268574011F1433F00A28C33 /* guildtab.cpp in Sources */,
+ 9268574111F1433F00A28C33 /* partytab.cpp in Sources */,
+ 9268574211F1433F00A28C33 /* guildhandler.cpp in Sources */,
+ 9268574311F1433F00A28C33 /* inventoryhandler.cpp in Sources */,
+ 9268574411F1433F00A28C33 /* itemhandler.cpp in Sources */,
+ 9268574511F1433F00A28C33 /* loginhandler.cpp in Sources */,
+ 9268574611F1433F00A28C33 /* messagehandler.cpp in Sources */,
+ 9268574711F1433F00A28C33 /* messagein.cpp in Sources */,
+ 9268574811F1433F00A28C33 /* messageout.cpp in Sources */,
+ 9268574911F1433F00A28C33 /* network.cpp in Sources */,
+ 9268574A11F1433F00A28C33 /* npchandler.cpp in Sources */,
+ 9268574B11F1433F00A28C33 /* partyhandler.cpp in Sources */,
+ 9268574C11F1433F00A28C33 /* playerhandler.cpp in Sources */,
+ 9268574D11F1433F00A28C33 /* specialhandler.cpp in Sources */,
+ 9268574E11F1433F00A28C33 /* tradehandler.cpp in Sources */,
+ 9268577F11F1435200A28C33 /* ambientlayer.cpp in Sources */,
+ 9268578711F1435F00A28C33 /* copynpaste.cpp in Sources */,
+ 9268578811F1435F00A28C33 /* mkdir.cpp in Sources */,
+ 9268578911F1435F00A28C33 /* specialfolder.cpp in Sources */,
+ 9268581311F15F3900A28C33 /* adminhandler.cpp in Sources */,
+ 9268581411F15F3A00A28C33 /* beinghandler.cpp in Sources */,
+ 9268581511F15F3B00A28C33 /* buysellhandler.cpp in Sources */,
+ 9268581611F15F3C00A28C33 /* charhandler.cpp in Sources */,
+ 9268581711F15F3D00A28C33 /* chathandler.cpp in Sources */,
+ 9268581811F15F3E00A28C33 /* connection.cpp in Sources */,
+ 9268581911F15F3F00A28C33 /* effecthandler.cpp in Sources */,
+ 9268581A11F15F4000A28C33 /* gamehandler.cpp in Sources */,
+ 9268581B11F15F4000A28C33 /* generalhandler.cpp in Sources */,
+ 9268581C11F15F4200A28C33 /* guildhandler.cpp in Sources */,
+ 9268581D11F15F4300A28C33 /* internal.cpp in Sources */,
+ 9268581E11F15F4400A28C33 /* inventoryhandler.cpp in Sources */,
+ 9268581F11F15F4500A28C33 /* itemhandler.cpp in Sources */,
+ 9268582011F15F4600A28C33 /* loginhandler.cpp in Sources */,
+ 9268582111F15F4600A28C33 /* messagehandler.cpp in Sources */,
+ 9268582211F15F4700A28C33 /* messagein.cpp in Sources */,
+ 9268582311F15F4800A28C33 /* messageout.cpp in Sources */,
+ 9268582411F15F4A00A28C33 /* network.cpp in Sources */,
+ 9268582511F15F4A00A28C33 /* npchandler.cpp in Sources */,
+ 9268582611F15F4C00A28C33 /* partyhandler.cpp in Sources */,
+ 9268582711F15F4C00A28C33 /* playerhandler.cpp in Sources */,
+ 9268582811F15F4E00A28C33 /* specialhandler.cpp in Sources */,
+ 9268582911F15F4E00A28C33 /* stats.cpp in Sources */,
+ 9268582A11F15F5000A28C33 /* tradehandler.cpp in Sources */,
+ 9268583011F15F6800A28C33 /* changeemaildialog.cpp in Sources */,
+ 9268583111F15F6900A28C33 /* changepassworddialog.cpp in Sources */,
+ 9268583211F15F7100A28C33 /* quitdialog.cpp in Sources */,
+ 9268583311F15F7300A28C33 /* serverdialog.cpp in Sources */,
+ 9268583411F15F7600A28C33 /* skilldialog.cpp in Sources */,
+ 9268583511F15F7900A28C33 /* statuswindow.cpp in Sources */,
+ 9268583611F15F7B00A28C33 /* textdialog.cpp in Sources */,
+ 9268583711F15F7E00A28C33 /* unregisterdialog.cpp in Sources */,
+ 9268583A11F15FAC00A28C33 /* guild.cpp in Sources */,
+ 9268583B11F15FC200A28C33 /* position.cpp in Sources */,
+ 9268583C11F15FC900A28C33 /* sha256.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ C0E91AC608A95435008D54AB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
+ ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
+ COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)\"";
+ FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"/System/Library/Frameworks\"";
+ GCC_DEBUGGING_SYMBOLS = default;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_OPTIMIZATION_LEVEL = s;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ EATHENA_SUPPORT,
+ USE_OPENGL,
+ );
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL_ttf.framework/Headers,
+ /Library/Frameworks/SDL_net.framework/Headers,
+ /Library/Frameworks/SDL_image.framework/Headers,
+ /Library/Frameworks/SDL_mixer.framework/Headers,
+ guichan.framework/Headers,
+ /Library/Frameworks/libpng.framework/Headers,
+ /usr/include/libxml2,
+ /Library/Frameworks/SDL.framework/Headers,
+ /opt/local/include/SDL,
+ /opt/local/include,
+ );
+ INFOPLIST_FILE = Info.plist;
+ LIBRARY_SEARCH_PATHS = (
+ /usr/lib,
+ "\"$(SRCROOT)\"",
+ /opt/local/lib,
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.5;
+ OTHER_LDFLAGS = (
+ "-lz",
+ "-lxml2",
+ "-lcurl",
+ "-lenet",
+ );
+ PREBINDING = NO;
+ PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
+ PRODUCT_NAME = "The Mana World";
+ SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+ USER_HEADER_SEARCH_PATHS = src;
+ };
+ name = Debug;
+ };
+ C0E91AC708A95435008D54AB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
+ ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
+ COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"/System/Library/Frameworks\"";
+ GCC_DEBUGGING_SYMBOLS = full;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ EATHENA_SUPPORT,
+ USE_OPENGL,
+ );
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_VERSION = 4.2;
+ GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = NO;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL_ttf.framework/Headers,
+ /Library/Frameworks/SDL_net.framework/Headers,
+ /Library/Frameworks/SDL_image.framework/Headers,
+ /Library/Frameworks/SDL_mixer.framework/Headers,
+ guichan.framework/Headers,
+ /Library/Frameworks/libpng.framework/Headers,
+ /usr/include/libxml2,
+ /Library/Frameworks/SDL.framework/Headers,
+ /opt/local/include/SDL,
+ /opt/local/include,
+ );
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LIBRARY_SEARCH_PATHS = (
+ /usr/lib,
+ "\"$(SRCROOT)\"",
+ /opt/local/lib,
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.5;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = (
+ "-lz",
+ "-lxml2",
+ "-lcurl",
+ "-lenet",
+ );
+ PREBINDING = NO;
+ PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES;
+ PRESERVE_DEAD_CODE_INITS_AND_TERMS = NO;
+ PRODUCT_NAME = "The Mana World";
+ SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+ SEPARATE_STRIP = NO;
+ SKIP_INSTALL = YES;
+ USER_HEADER_SEARCH_PATHS = src;
+ };
+ name = Release;
+ };
+ C0E91ACA08A95435008D54AB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ C0E91ACB08A95435008D54AB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ ppc,
+ i386,
+ );
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_OPTIMIZATION_LEVEL = 2;
+ GCC_PREPROCESSOR_DEFINITIONS = "";
+ SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+ SEPARATE_STRIP = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ C0E91AC508A95435008D54AB /* Build configuration list for PBXNativeTarget "themanaworld" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C0E91AC608A95435008D54AB /* Debug */,
+ C0E91AC708A95435008D54AB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C0E91AC908A95435008D54AB /* Build configuration list for PBXProject "mana" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C0E91ACA08A95435008D54AB /* Debug */,
+ C0E91ACB08A95435008D54AB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 20286C28FDCF999611CA2CEA /* Project object */;
+}
diff --git a/manaplus.desktop b/manaplus.desktop
new file mode 100644
index 000000000..1905ca9b5
--- /dev/null
+++ b/manaplus.desktop
@@ -0,0 +1,17 @@
+
+[Desktop Entry]
+Version=1.0
+Name=ManaPlus
+Comment=A 2D MMORPG client
+Comment[fr]=Un jeu en ligne dans un univers fantastique
+Comment[de]=ein Online Fantasy Spiel
+Comment[it]=Un gioco fantasy online
+Comment[nl]=Een online role playing game
+Comment[sv]=Ett fantasyrollspel online
+Comment[ru]=Клиент к 2D MMORPG игре
+Exec=manaplus
+StartupNotify=false
+Terminal=false
+Type=Application
+Icon=manaplus
+Categories=Application;Game;
diff --git a/manaplus.menu b/manaplus.menu
new file mode 100644
index 000000000..cc17fbeb0
--- /dev/null
+++ b/manaplus.menu
@@ -0,0 +1,4 @@
+?package(manaplus):needs="X11" section="Games/Adventure"\
+ title="ManaPlus"\
+ description="ManaPlus is a 2D MMORPG client."\
+ command="/usr/games/manaplus" icon="/usr/share/pixmaps/manaplus.xpm"
diff --git a/packaging/debian/changelog b/packaging/debian/changelog
new file mode 100644
index 000000000..bc5b75799
--- /dev/null
+++ b/packaging/debian/changelog
@@ -0,0 +1,77 @@
+tmw (0.0.24-1) unstable; urgency=low
+
+ * New upstream release.
+ * Wrapped configure script options line to a more human readable
+ format.
+ * Bumped Standards-Version to 3.7.3.
+ * Changed description in debian/tmw.menu, it is now called as an
+ adventure instead of an arcade game.
+ * Removed the ugly hyphen in the description of debian/tmw.desktop.
+ * Removed debian/tmw.6 manpage, because it is in upstream now.
+ * Removed 01-set-gl-texture-zero and 02-guichan_0.7 patches,
+ because they are fixed in the current upstream release.
+ * Removed now useless calls of dh_link and dh_installman in
+ debian/rules.
+ * Removed debian/tmw-data.docs, because the NEWS and AUTHORS file
+ is already in the tmw package.
+ * Removed deprecated encoding flag from debian/tmw.desktop.
+ * Added debian/watch file.
+ * Added homepage field to debian/control and removed the one from
+ the long descriptions.
+ * Added a break to the long description of tmw-data. It looks now
+ realy better.
+ * Added the tmw-dbg package, which provides the debugging symbols.
+
+ -- Patrick Matthäi <patrick.matthaei@web.de> Mon, 24 Dec 2007 17:10:00 +0100
+
+tmw (0.0.23-3) unstable; urgency=low
+
+ * Added missing files data/graphics/images/ambient/*.png to
+ release.
+ Closes: #439861
+ * Added guichan_0.7 patch to build tmw against guichan 0.7.1.
+ * debian/control: Changed guichan version to libguichan2 and
+ changed build dependencie from libcurl3-dev to libcurl4-gnutls-dev.
+ * debian/tmw.menu: Corrected menu entry categorie to Games/Adventure.
+ Thanks lintian.
+ * Fixed clean rule. Thanks lintian.
+
+ -- Patrick Matthäi <patrick.matthaei@web.de> Thu, 6 Sep 2007 18:36:00 +0100
+
+tmw (0.0.23-2) unstable; urgency=low
+
+ * Added set-gl-texture-zero patch to set GL texture index
+ to zero when an image uses the SDL backend.
+ Closes: #427915
+ * debian/control: Removed dependencie of tmw-data to tmw.
+ Closes: #427920
+ * debian/control: Set tmw as recommends to tmw-data.
+ * debian/control: Added dpatch to the build dependencies.
+ * debian/control: Changed guichan version to libguichan1.
+ Closes: #435065
+ * debian/tmw.docs: Added upstream ChangeLog to package.
+ * debian/rules: Removed now unneeded '--with-opengl'
+ configure flag.
+
+ -- Patrick Matthäi <patrick.matthaei@web.de> Wed, 20 Jun 2007 08:55:12 +0100
+
+tmw (0.0.23-1) unstable; urgency=low
+
+ * Uploaded tmw to unstable.
+ Closes: #418725, #423275
+ * New upstream release.
+ * debian/rules: No longer needed the tmw-icon rename
+ hack. Upstream renamed the icon files.
+ * debian/tmw.xpm: Added xpm icon file, because upstream
+ has forgotten it in the newest release.
+
+ -- Patrick Matthäi <patrick.matthaei@web.de> Mon, 5 Jun 2007 21:05:36 +0100
+
+tmw (0.0.22.2-1) experimental; urgency=low
+
+ * Initial release.
+ * Uploading to experimental because we need libguichan0-dev (>= 0.6.1).
+ * src/main.cpp:
+ Moved tmw-icon.png to /usr/share/icons/tmw.png.
+
+ -- Patrick Matthäi <patrick.matthaei@web.de> Tue, 6 Mar 2007 09:08:21 +0100
diff --git a/packaging/debian/compat b/packaging/debian/compat
new file mode 100644
index 000000000..7ed6ff82d
--- /dev/null
+++ b/packaging/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/packaging/debian/control b/packaging/debian/control
new file mode 100644
index 000000000..a5696ca5d
--- /dev/null
+++ b/packaging/debian/control
@@ -0,0 +1,27 @@
+Source: mana
+Section: games
+Priority: optional
+Homepage: http://manasource.org/
+Maintainer: Patrick Matthäi <patrick.matthaei@web.de>
+Build-Depends: debhelper (>= 5), dpkg-dev (>= 1.13.19), dpatch, autotools-dev, libcurl4-gnutls-dev, libgl1-mesa-dev, libguichan2-dev (>= 0.7.1), libsdl1.2-dev, libsdl-image1.2-dev, libsdl-net1.2-dev, libsdl-mixer1.2-dev, libphysfs-dev, libpng12-dev, libxml2-dev, zlib1g-dev
+Standards-Version: 3.7.3
+
+Package: mana
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, mana-data (= ${source:Version})
+Description: Mana is a 2D MMORPG client
+
+Package: mana-dbg
+Architecture: any
+Priority: extra
+Depends: mana (= ${binary:Version})
+Description: Mana is a 2D MMORPG client (debugging symbols)
+ .
+ This package provides debugging symbols for the mana package.
+
+Package: mana-data
+Architecture: all
+Recommends: mana
+Description: Mana is a 2D MMORPG client
+ .
+ This package contains the data files.
diff --git a/packaging/debian/copyright b/packaging/debian/copyright
new file mode 100644
index 000000000..a6a2b687a
--- /dev/null
+++ b/packaging/debian/copyright
@@ -0,0 +1,49 @@
+This package was debianized by Patrick Matthäi <patrick.matthaei@web.de> on
+Wed, 6 Feb 2007 09:16:23 +0100.
+
+It was downloaded from <http://www.themanaworld.org/>.
+
+Upstream Author: Eugenio Favalli <elvenprogrammer@gmail.com>
+
+License (src/utils/base64.h, src/utils/base64.cpp):
+
+ Copyright (C) 1997-1998 PHP Development Team
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of one of the following licenses:
+
+ A) the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option)
+ any later version.
+
+ B) the PHP License as published by the PHP Development Team and
+ included in the distribution in the file: LICENSE
+
+ 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.
+
+On Debian systems, the complete text of the GNU General Public License
+can be found in /usr/share/common-licenses/GPL file.
+
+License (everything else):
+
+ Copyright (C) 2004-2007 The The Mana World Development Team
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+On Debian systems, the complete text of the GNU General Public License
+can be found in /usr/share/common-licenses/GPL file.
diff --git a/packaging/debian/mana-data.install b/packaging/debian/mana-data.install
new file mode 100644
index 000000000..82a37bb34
--- /dev/null
+++ b/packaging/debian/mana-data.install
@@ -0,0 +1,5 @@
+data/graphics/gui/*.png usr/share/games/mana/data/graphics/gui
+data/graphics/images/*.png usr/share/games/mana/data/graphics/images
+data/graphics/images/ambient/*.png usr/share/games/mana/data/graphics/images/ambient
+data/graphics/tiles/*.png usr/share/games/mana/data/graphics/tiles
+data/help/*.txt usr/share/games/mana/data/help
diff --git a/packaging/debian/mana.desktop b/packaging/debian/mana.desktop
new file mode 100644
index 000000000..ec24a2fc6
--- /dev/null
+++ b/packaging/debian/mana.desktop
@@ -0,0 +1,16 @@
+
+[Desktop Entry]
+Version=1.0
+Name=Mana
+Comment=A 2D MMORPG client
+Comment[fr]=Un jeu en ligne dans un univers fantastique
+Comment[de]=ein Online Fantasy Spiel
+Comment[it]=Un gioco fantasy online
+Comment[nl]=Een online role playing game
+Comment[sv]=Ett fantasyrollspel online
+Exec=mana
+StartupNotify=false
+Terminal=false
+Type=Game
+Icon=mana.png
+Categories=Game
diff --git a/packaging/debian/mana.docs b/packaging/debian/mana.docs
new file mode 100644
index 000000000..d622a5279
--- /dev/null
+++ b/packaging/debian/mana.docs
@@ -0,0 +1,6 @@
+AUTHORS
+NEWS
+README
+ChangeLog
+docs/progression.txt
+docs/FAQ.txt
diff --git a/packaging/debian/mana.install b/packaging/debian/mana.install
new file mode 100644
index 000000000..da45ec4a9
--- /dev/null
+++ b/packaging/debian/mana.install
@@ -0,0 +1,5 @@
+debian/manaplus.desktop usr/share/applications
+debian/manaplus.xpm usr/share/pixmaps
+data/icons/manaplus.png usr/share/icons
+docs/manaplus.6 usr/share/man/man6
+src/manaplus usr/games
diff --git a/packaging/debian/mana.sgml b/packaging/debian/mana.sgml
new file mode 100644
index 000000000..257c948d6
--- /dev/null
+++ b/packaging/debian/mana.sgml
@@ -0,0 +1,149 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+ page: `docbook-to-man manpage.sgml > manpage.1'. You may view
+ the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+ less'. A typical entry in a Makefile or Makefile.am is:
+
+manpage.1: manpage.sgml
+ docbook-to-man $< > $@
+
+
+ The docbook-to-man binary is found in the docbook-to-man package.
+ Please remember that if you create the nroff version in one of the
+ debian/rules file targets (such as build), you will need to include
+ docbook-to-man in your Build-Depends control field.
+
+ -->
+
+ <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+ <!ENTITY dhfirstname "<firstname>FERREIRA</firstname>">
+ <!ENTITY dhsurname "<surname>Yohann</surname>">
+ <!-- Please adjust the date whenever revising the manpage. -->
+ <!ENTITY dhdate "<date>avril 13, 2005</date>">
+ <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+ allowed: see man(7), man(1). -->
+ <!ENTITY dhsection "<manvolnum>6</manvolnum>">
+ <!ENTITY dhemail "<email>bertram@cegetel.net</email>">
+ <!ENTITY dhusername "FERREIRA Yohann">
+ <!ENTITY dhucpackage "<refentrytitle>Mana</refentrytitle>">
+ <!ENTITY dhpackage "mana">
+
+ <!ENTITY debian "<productname>Debian</productname>">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+ <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ &dhemail;
+ </address>
+ <author>
+ &dhfirstname;
+ &dhsurname;
+ </author>
+ <copyright>
+ <year>2003</year>
+ <holder>&dhusername;</holder>
+ </copyright>
+ &dhdate;
+ </refentryinfo>
+ <refmeta>
+ &dhucpackage;
+
+ &dhsection;
+ </refmeta>
+ <refnamediv>
+ <refname>&dhpackage;</refname>
+
+ <refpurpose>Mana is the abreviation of The Mana World : A Fantasy Online Game</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&dhpackage;</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This manual page documents briefly the
+ <command>&dhpackage;</command> ingame
+ commands.</para>
+ <para><command>&dhpackage;</command> is a Great Online Game based upon the Seiken Densetsu Serie.
+It has its own universe, and and its own character management system, which will
+give you the opportunity to play in a 2D heroic-fantasy world forever.</para>
+
+ </refsect1>
+ <refsect1>
+ <title>COMMON KEYS</title>
+
+ <para>Arrow Keys, Key Pad Keys (Diagonals Supported).
+Move your character around.
+
+Left Ctrl :
+Make your character attack.
+
+G :
+Get Items on the ground or in a chest.
+
+Alt + 1...9 :
+Shows an Emoticon above your character.
+
+Alt + I :
+Shows / Hide Inventory Window.
+
+Alt + K :
+Shows / Hide Skills Window.
+
+Alt + E :
+Shows / Hide Equipment Window.
+
+Alt + C :
+Shows Configuration Window.
+</para>
+
+ </refsect1>
+ <refsect1>
+ <title>SEE ALSO</title>
+
+ <para>libguichan (2).</para>
+
+ <para>The program is documented fully by <citetitle>The Mana World Team</citetitle> available via the
+ website http://www.manaworld.org/</para>
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+
+ <para>This manual page was written by &dhusername; &dhemail; for
+ the &debian; system (but may be used by others). Permission is
+ granted to copy, distribute and/or modify this document under
+ the terms of the &gnu; General Public License, Version 2 any
+ later version published by the Free Software Foundation.
+ </para>
+ <para>
+ On Debian systems, the complete text of the GNU General Public
+ License can be found in /usr/share/common-licenses/GPL.
+ </para>
+
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
+
+
diff --git a/packaging/debian/patches/00list b/packaging/debian/patches/00list
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/packaging/debian/patches/00list
diff --git a/packaging/debian/rules b/packaging/debian/rules
new file mode 100644
index 000000000..df2e08d6f
--- /dev/null
+++ b/packaging/debian/rules
@@ -0,0 +1,69 @@
+#!/usr/bin/make -f
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+include /usr/share/dpatch/dpatch.make
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+config.status: patch
+ dh_testdir
+ CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) \
+ --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr \
+ --datadir=/usr/share/games --bindir=/usr/games --mandir=/usr/share/man
+
+build: build-stamp
+build-stamp: config.status
+ dh_testdir
+ $(MAKE)
+ touch build-stamp
+
+clean: unpatch
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+ [ ! -f Makefile ] || $(MAKE) distclean
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+binary-indep: build install
+ dh_testdir -i
+ dh_testroot -i
+ dh_installchangelogs -i ChangeLog
+ dh_installdocs -i
+ dh_install -i
+ dh_compress -i
+ dh_fixperms -i
+ dh_installdeb -i
+ dh_gencontrol -i
+ dh_md5sums -i
+ dh_builddeb -i
+
+binary-arch: build install
+ dh_testdir -a
+ dh_testroot -a
+ dh_installchangelogs -a ChangeLog
+ dh_installdocs -a
+ dh_install -a
+ dh_desktop -a
+ dh_installmenu -a
+ dh_strip -a --dbg-package=mana-dbg
+ dh_compress -a
+ dh_fixperms -a
+ dh_installdeb -a
+ dh_shlibdeps -a
+ dh_gencontrol -a
+ dh_md5sums -a
+ dh_builddeb -a
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/packaging/debian/watch b/packaging/debian/watch
new file mode 100644
index 000000000..01aa13f7e
--- /dev/null
+++ b/packaging/debian/watch
@@ -0,0 +1,2 @@
+version=3
+http://sf.net/themanaworld/tmw-(.*)\.tar\.gz
diff --git a/packaging/windows/make-translations.sh b/packaging/windows/make-translations.sh
new file mode 100755
index 000000000..1d4132397
--- /dev/null
+++ b/packaging/windows/make-translations.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+for i in `grep -v ^# ../../po/LINGUAS`; do
+ mkdir -p ../../translations/$i/LC_MESSAGES
+ msgfmt -c -o ../../translations/$i/LC_MESSAGES/manaplus.mo ../../po/$i.po
+done
diff --git a/packaging/windows/make-translations.vbs b/packaging/windows/make-translations.vbs
new file mode 100644
index 000000000..339a0299e
--- /dev/null
+++ b/packaging/windows/make-translations.vbs
@@ -0,0 +1,42 @@
+Set fso = CreateObject("Scripting.FileSystemObject")
+Set WshShell = CreateObject("WScript.Shell")
+Dim s, infile, outfile, command
+
+Function CreateFolderIfNonexistent(folder)
+ if not fso.FolderExists(folder) then
+ fso.CreateFolder(folder)
+ end if
+end Function
+
+'check for existence of msgfmt
+if not fso.FileExists("msgfmt.exe") then
+ WScript.echo "msgfmt.exe not found. Please get gettext for windows from http://gnuwin32.sourceforge.net/packages/gettext.htm and copy the files msgfmt.exe and all dll files from the gettext/bin directory into this directory and run this script again."
+ WScript.Quit(1)
+end if
+
+CreateFolderIfNonexistent("..\..\translations\")
+
+'open translation list
+Set stream = fso.GetFile("..\..\po\LINGUAS").OpenAsTextStream(1, 0)
+
+'iterate contents of translations file
+translations = 0
+do while not stream.AtEndOfStream
+ s = stream.ReadLine()
+ if inStr(s, "#") = false then
+ 'create the output directory
+ CreateFolderIfNonexistent("..\..\translations\" + s)
+ CreateFolderIfNonexistent("..\..\translations\" + s + "\LC_MESSAGES")
+ 'build the translate command
+ infile = "../../po/" + s + ".po"
+ outfile = "../../translations/" + s +"/LC_MESSAGES/mana.mo"
+ command = "msgfmt -c -o " + outfile + " " + infile
+ 'execute translate command
+ errval = WshShell.run(command, 0, true)
+ if errval = 0 then
+ translations = translations + 1
+ end if
+ end if
+loop
+
+WScript.echo translations, " translations compiled."
diff --git a/packaging/windows/portable.xml b/packaging/windows/portable.xml
new file mode 100644
index 000000000..0059d1094
--- /dev/null
+++ b/packaging/windows/portable.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<configuration>
+ <option name="dataDir" value="logs"/>
+ <option name="configDir" value="configs"/>
+ <option name="screenshotDir" value="screenshots"/>
+</configuration>
diff --git a/packaging/windows/readme.txt b/packaging/windows/readme.txt
new file mode 100644
index 000000000..4a10fef49
--- /dev/null
+++ b/packaging/windows/readme.txt
@@ -0,0 +1,6 @@
+HOW TO BUILD THE INSTALLER
+
+See the following wiki page, which also deals with the steps needed to produce
+the Windows installer:
+
+ http://wiki.themanaworld.org/index.php/Making_a_new_release
diff --git a/packaging/windows/setup.nsi b/packaging/windows/setup.nsi
new file mode 100644
index 000000000..f4cecdf22
--- /dev/null
+++ b/packaging/windows/setup.nsi
@@ -0,0 +1,336 @@
+; This script allows the following parameters being overwritten from
+; command line. When called without any parameters it behaves exactly
+; like the old install script.
+;
+; DLLDIR - directory containing required dlls
+; EXEDIR - directory containing manaplus.exe
+; EXESUFFIX - offset to SRCDIR pointing to a directory containing manaplus.exe
+; PRODUCT_VERSION - software version
+; UPX - upx binary name
+;
+; For a cmake build on UNIX the following should give you a working installer:
+; makensis -DDLLDIR=/path/to/dlls \
+; -DPRODUCT_VERSION=0.1.`date +%Y%m%d`
+; -DUPX=upx
+; -DEXESUFFIX=/src
+
+CRCCheck on
+SetCompress off
+SetCompressor /SOLID lzma
+
+!define SRCDIR "..\.."
+!ifndef UPX
+ !define "UPX upx\upx.exe"
+!endif
+
+!ifdef EXESUFFIX
+ !define EXEDIR ${SRCDIR}/${EXESUFFIX}
+!endif
+
+!ifndef EXEDIR
+ !define EXEDIR ${SRCDIR}
+!endif
+
+!ifndef DLLDIR
+ !define DLLDIR ${SRCDIR}/dll
+!endif
+
+;--- (and without !defines ) ---
+!System "${UPX} --best --crp-ms=999999 --compress-icons=0 --nrv2d ${EXEDIR}\manaplus.exe"
+
+; HM NIS Edit helper defines
+!define PRODUCT_NAME "ManaPlus"
+!ifndef PRODUCT_VERSION
+ !define PRODUCT_VERSION "0.0.29.1"
+!endif
+!define PRODUCT_PUBLISHER "Mana Development Team"
+!define PRODUCT_WEB_SITE "http://manasource.org"
+!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\manaplus.exe"
+!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
+!define PRODUCT_UNINST_ROOT_KEY "HKLM"
+
+; MUI 1.67 compatible ------
+!include "MUI.nsh"
+
+; MUI Settings
+!define MUI_ABORTWARNING
+;!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\win-install.ico"
+!define MUI_ICON "${SRCDIR}\data\icons\manaplus.ico"
+;!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\win-uninstall.ico"
+!define MUI_UNICON "${SRCDIR}\data\icons\manaplus.ico"
+
+;Language Selection Dialog Settings
+;Remember the installer language
+!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
+!define MUI_LANGDLL_REGISTRY_KEY "Software\Mana"
+!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
+
+!define MUI_WELCOMEFINISHPAGE_BITMAP "setup_welcome.bmp"
+!define MUI_UNWELCOMEFINISHPAGE_BITMAP "setup_welcome.bmp"
+
+; Welcome page
+
+!define MUI_WELCOMEPAGE_TITLE_3LINES
+!insertmacro MUI_PAGE_WELCOME
+; License page
+!insertmacro MUI_PAGE_LICENSE "${SRCDIR}\COPYING"
+; Directory page
+!insertmacro MUI_PAGE_DIRECTORY
+; Components page
+!insertmacro MUI_PAGE_COMPONENTS
+; Instfiles page
+!insertmacro MUI_PAGE_INSTFILES
+; Finish page
+!define MUI_FINISHPAGE_RUN
+!define MUI_FINISHPAGE_RUN_FUNCTION RunMana
+!define MUI_FINISHPAGE_SHOWREADME 'notepad.exe "$\"$INSTDIR\README$\""'
+!define MUI_PAGE_CUSTOMFUNCTION_PRE changeFinishImage
+!define MUI_FINISHPAGE_LINK "Visit Mana website for the latest news, FAQs and support"
+!define MUI_FINISHPAGE_LINK_LOCATION "http://themanaworld.org"
+!insertmacro MUI_PAGE_FINISH
+
+Function RunMana
+SetOutPath $INSTDIR
+Exec "$INSTDIR\manaplus.exe"
+FunctionEnd
+
+Function changeFinishImage
+!insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "Field 1" "Text" "$PLUGINSDIR\setup_finish.bmp"
+FunctionEnd
+
+; Uninstaller pages
+
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+!define MUI_FINISHPAGE_TITLE_3LINES
+!insertmacro MUI_UNPAGE_FINISH
+
+;Languages
+!insertmacro MUI_LANGUAGE "English" # first language is the default language
+!insertmacro MUI_LANGUAGE "French"
+!insertmacro MUI_LANGUAGE "German"
+!insertmacro MUI_LANGUAGE "Spanish"
+!insertmacro MUI_LANGUAGE "SimpChinese"
+!insertmacro MUI_LANGUAGE "TradChinese"
+!insertmacro MUI_LANGUAGE "Japanese"
+!insertmacro MUI_LANGUAGE "Korean"
+!insertmacro MUI_LANGUAGE "Italian"
+!insertmacro MUI_LANGUAGE "Dutch"
+!insertmacro MUI_LANGUAGE "Danish"
+!insertmacro MUI_LANGUAGE "Swedish"
+!insertmacro MUI_LANGUAGE "Norwegian"
+!insertmacro MUI_LANGUAGE "Finnish"
+!insertmacro MUI_LANGUAGE "Greek"
+!insertmacro MUI_LANGUAGE "Russian"
+!insertmacro MUI_LANGUAGE "Portuguese"
+!insertmacro MUI_LANGUAGE "PortugueseBR"
+!insertmacro MUI_LANGUAGE "Polish"
+!insertmacro MUI_LANGUAGE "Ukrainian"
+!insertmacro MUI_LANGUAGE "Czech"
+!insertmacro MUI_LANGUAGE "Slovak"
+!insertmacro MUI_LANGUAGE "Croatian"
+!insertmacro MUI_LANGUAGE "Bulgarian"
+!insertmacro MUI_LANGUAGE "Hungarian"
+!insertmacro MUI_LANGUAGE "Thai"
+!insertmacro MUI_LANGUAGE "Romanian"
+!insertmacro MUI_LANGUAGE "Latvian"
+!insertmacro MUI_LANGUAGE "Macedonian"
+!insertmacro MUI_LANGUAGE "Estonian"
+!insertmacro MUI_LANGUAGE "Turkish"
+!insertmacro MUI_LANGUAGE "Lithuanian"
+!insertmacro MUI_LANGUAGE "Catalan"
+!insertmacro MUI_LANGUAGE "Slovenian"
+!insertmacro MUI_LANGUAGE "Serbian"
+!insertmacro MUI_LANGUAGE "SerbianLatin"
+!insertmacro MUI_LANGUAGE "Arabic"
+!insertmacro MUI_LANGUAGE "Farsi"
+!insertmacro MUI_LANGUAGE "Hebrew"
+!insertmacro MUI_LANGUAGE "Indonesian"
+!insertmacro MUI_LANGUAGE "Mongolian"
+!insertmacro MUI_LANGUAGE "Luxembourgish"
+!insertmacro MUI_LANGUAGE "Albanian"
+!insertmacro MUI_LANGUAGE "Breton"
+!insertmacro MUI_LANGUAGE "Belarusian"
+!insertmacro MUI_LANGUAGE "Icelandic"
+!insertmacro MUI_LANGUAGE "Malay"
+!insertmacro MUI_LANGUAGE "Bosnian"
+!insertmacro MUI_LANGUAGE "Kurdish"
+
+!insertmacro MUI_RESERVEFILE_LANGDLL
+
+ReserveFile "setup_finish.bmp"
+
+; MUI end ------
+
+Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
+OutFile "manaplus-${PRODUCT_VERSION}-win32.exe"
+InstallDir "$PROGRAMFILES\Mana"
+InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
+ShowInstDetails show
+ShowUnInstDetails show
+
+Function .onInit
+ !insertmacro MUI_LANGDLL_DISPLAY
+ InitPluginsDir
+ File /oname=$PLUGINSDIR\setup_finish.bmp "setup_finish.bmp"
+FunctionEnd
+
+Section "Core files (required)" SecCore
+ SectionIn RO
+ SetOutPath "$INSTDIR"
+ SetOverwrite ifnewer
+ CreateDirectory "$INSTDIR\data"
+ CreateDirectory "$INSTDIR\data\fonts"
+ CreateDirectory "$INSTDIR\data\graphics"
+ CreateDirectory "$INSTDIR\data\help"
+ CreateDirectory "$INSTDIR\data\icons"
+ CreateDirectory "$INSTDIR\data\graphics\gui"
+ CreateDirectory "$INSTDIR\data\graphics\images"
+ CreateDirectory "$INSTDIR\data\graphics\sprites"
+ CreateDirectory "$INSTDIR\data\sfx"
+ CreateDirectory "$INSTDIR\data\sfx\system"
+ CreateDirectory "$INSTDIR\data\themes"
+ CreateDirectory "$INSTDIR\data\themes\blackwood"
+ CreateDirectory "$INSTDIR\data\themes\classic"
+ CreateDirectory "$INSTDIR\data\themes\enchilado"
+ CreateDirectory "$INSTDIR\data\themes\redandblack"
+ CreateDirectory "$INSTDIR\data\themes\wood"
+ CreateDirectory "$INSTDIR\docs"
+
+ SetOverwrite ifnewer
+ SetOutPath "$INSTDIR"
+
+ File "${EXEDIR}\manaplus.exe"
+ File "${DLLDIR}\*.dll"
+ File "${SRCDIR}\AUTHORS"
+ File "${SRCDIR}\COPYING"
+ File "${SRCDIR}\NEWS"
+ File "${SRCDIR}\README.txt"
+ SetOutPath "$INSTDIR\data\fonts"
+ File "${SRCDIR}\data\fonts\*.ttf"
+ SetOutPath "$INSTDIR\data\graphics"
+ File "${SRCDIR}\data\graphics\*.png"
+ SetOutPath "$INSTDIR\data\graphics\gui"
+ File "${SRCDIR}\data\graphics\gui\*.png"
+ File "${SRCDIR}\data\graphics\gui\*.xml"
+ SetOutPath "$INSTDIR\data\graphics\images"
+ File /x minimap_*.png ${SRCDIR}\data\graphics\images\*.png
+ File "${SRCDIR}\data\graphics\images\error.png"
+ SetOutPath "$INSTDIR\data\graphics\sprites"
+ File "${SRCDIR}\data\graphics\sprites\*.gif"
+ File "${SRCDIR}\data\graphics\sprites\*.png"
+ File "${SRCDIR}\data\graphics\sprites\*.xml"
+ SetOutPath "$INSTDIR\data\sfx\system"
+ File "${SRCDIR}\data\sfx\system\*.ogg"
+ SetOutPath "$INSTDIR\data\themes\blackwood"
+ File "${SRCDIR}\data\themes\blackwood\*.png"
+ File "${SRCDIR}\data\themes\blackwood\*.xml"
+ SetOutPath "$INSTDIR\data\themes\classic"
+ File "${SRCDIR}\data\themes\classic\*.png"
+ File "${SRCDIR}\data\themes\classic\*.xml"
+ SetOutPath "$INSTDIR\data\themes\enchilado"
+ File "${SRCDIR}\data\themes\enchilado\*.png"
+ File "${SRCDIR}\data\themes\enchilado\*.xml"
+ SetOutPath "$INSTDIR\data\themes\redandblack"
+ File "${SRCDIR}\data\themes\redandblack\*.png"
+ File "${SRCDIR}\data\themes\redandblack\*.xml"
+ SetOutPath "$INSTDIR\data\themes\wood"
+ File "${SRCDIR}\data\themes\wood\*.png"
+ File "${SRCDIR}\data\themes\wood\*.xml"
+ SetOutPath "$INSTDIR\data\help"
+ File "${SRCDIR}\data\help\*.txt"
+ SetOutPath "$INSTDIR\data\icons\"
+ File "${SRCDIR}\data\icons\manaplus.ico"
+ SetOutPath "$INSTDIR\docs"
+ File "${SRCDIR}\docs\FAQ.txt"
+SectionEnd
+
+Section "Create Shortcuts" SecShortcuts
+ SetOutPath "$INSTDIR"
+ SetOverwrite ifnewer
+ CreateDirectory "$SMPROGRAMS\Mana"
+ CreateShortCut "$SMPROGRAMS\Mana\ManaPlus.lnk" "$INSTDIR\manaplus.exe"
+ CreateShortCut "$SMPROGRAMS\Mana\ManaPlus (no opengl).lnk" "$INSTDIR\manaplus.exe" --no-opengl
+ CreateShortCut "$SMPROGRAMS\Mana\ManaPlus (safemode).lnk" "$INSTDIR\manaplus.exe" --safemode
+ CreateShortCut "$DESKTOP\ManaPlus.lnk" "$INSTDIR\manaplus.exe"
+SectionEnd
+
+Section /o "Music" SecMusic
+ AddSize 17602
+ CreateDirectory "$INSTDIR\data\music"
+ SetOutPath "$INSTDIR\data\music"
+ NSISdl::download "http://downloads.sourceforge.net/themanaworld/tmwmusic-0.2.tar.gz" "$TEMP\tmwmusic-0.2.tar.gz"
+ ;Requires an additional plugin from http://nsis.sourceforge.net/UnTGZ_plug-in Place untgz.dll in your nsis/plugin dir
+ untgz::extract -j -d "$INSTDIR\data\music" "$TEMP\tmwmusic-0.2.tar.gz"
+ Delete "$TEMP\tmwmusic-0.2.tar.gz"
+SectionEnd
+
+Section /o "Portable" SecPortable
+ SetOutPath "$INSTDIR"
+ File "portable.xml"
+SectionEnd
+
+Section "Translations" SecTrans
+ SetOutPath "$INSTDIR"
+ File /nonfatal /r "${SRCDIR}\translations"
+SectionEnd
+
+;Package descriptions
+!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "The core program files."
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcuts} "Create game shortcuts."
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecMusic} "Background music. (If selected the music will be downloaded from the internet.)"
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecPortable} "Portable client. (If selected client will work as portable client.)"
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecTrans} "Translations for the user interface into 23 different languages. Uncheck this component to leave it in English."
+!insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+
+
+Section -AdditionalIcons
+ WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
+ CreateShortCut "$SMPROGRAMS\Mana\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
+ CreateShortCut "$SMPROGRAMS\Mana\Readme.lnk" "notepad.exe" "$INSTDIR\README.txt"
+ CreateShortCut "$SMPROGRAMS\Mana\FAQ.lnk" "$INSTDIR\docs\FAQ.txt"
+ CreateShortCut "$SMPROGRAMS\Mana\Uninstall.lnk" "$INSTDIR\uninst.exe"
+SectionEnd
+
+Section -Post
+ WriteUninstaller "$INSTDIR\uninst.exe"
+ WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\manaplus.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\manaplus.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
+SectionEnd
+
+Function un.onInit
+ !insertmacro MUI_UNGETLANGUAGE
+FunctionEnd
+
+Section Uninstall
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mana"
+
+ Delete "$INSTDIR\*.*"
+
+ Delete "$SMPROGRAMS\Mana\Uninstall.lnk"
+ Delete "$DESKTOP\ManaPlus.lnk"
+ Delete "$SMPROGRAMS\Mana\ManaPlus.lnk"
+ Delete "$SMPROGRAMS\Mana\ManaPlus (no opengl).lnk"
+ Delete "$SMPROGRAMS\Mana\Website.lnk"
+ Delete "$SMPROGRAMS\Mana\Readme.lnk"
+ Delete "$SMPROGRAMS\Mana\FAQ.lnk"
+
+ RMDir "$SMPROGRAMS\Mana"
+
+ RMDir /r "$INSTDIR\data"
+ RMDir /r "$INSTDIR\docs"
+ RMDir /r "$INSTDIR\translations"
+ RMDir /r "$INSTDIR\updates"
+ RMDir "$INSTDIR"
+
+ DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
+ DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
+ SetAutoClose true
+SectionEnd
diff --git a/packaging/windows/setup_finish.bmp b/packaging/windows/setup_finish.bmp
new file mode 100644
index 000000000..c23770b9f
--- /dev/null
+++ b/packaging/windows/setup_finish.bmp
Binary files differ
diff --git a/packaging/windows/setup_welcome.bmp b/packaging/windows/setup_welcome.bmp
new file mode 100644
index 000000000..c23770b9f
--- /dev/null
+++ b/packaging/windows/setup_welcome.bmp
Binary files differ
diff --git a/packwin b/packwin
new file mode 100755
index 000000000..a5e2307eb
--- /dev/null
+++ b/packwin
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+dir=`pwd`
+
+cd packaging/windows
+./make-translations.sh
+makensis -DDLLDIR=$dir/../mana_win/libs/dll/ \
+ -DPRODUCT_VERSION="4144-1.0.12.26" \
+ -DEXESUFFIX=/src \
+ -DUPX=true \
+ setup.nsi
+
diff --git a/pmake b/pmake
new file mode 100755
index 000000000..6a636ba28
--- /dev/null
+++ b/pmake
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+dir=`pwd`
+
+export CC=gcc-4.5
+export CXX=g++-4.5
+
+export LANG=C
+export CXXFLAGS="-pg -fno-inline -Wunreachable-code -Wmissing-field-initializers \
+-Wabi -Wdisabled-optimization -Wuninitialized \
+-Wvolatile-register-var -Winvalid-pch -Wredundant-decls \
+-Wnormalized=nfkc -Wmissing-format-attribute -Wmissing-noreturn \
+-Wswitch-default -Wsign-promo -Waddress -Wmissing-declarations \
+-Wctor-dtor-privacy -Wstrict-null-sentinel \
+-Wunused-parameter -Wredundant-decls -Wlogical-op \
+-Wempty-body -Wsign-compare -Wclobbered -Wcast-align -Wcast-qual \
+-Wtype-limits -Wpointer-arith -Wundef -Wmissing-include-dirs \
+-Wignored-qualifiers -Winit-self -pedantic -Wall -ggdb3 -O2 -pipe"
+
+autoreconf -i
+./configure --prefix=$dir/run \
+ --datadir=$dir/run/share/games \
+ --bindir=$dir/run/bin \
+ --mandir=$dir/run/share/man
+
+make -j5 2>make.log
+
diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
new file mode 100644
index 000000000..de35788eb
--- /dev/null
+++ b/po/CMakeLists.txt
@@ -0,0 +1,42 @@
+FIND_PACKAGE(Gettext REQUIRED)
+
+# based on the CMake 2.6.3 GETTEXT_CREATE_TRANSLATIONS
+# we need our own version because the upstream one contains
+# a call to msgmerge (updating po files) which can't be
+# disabled
+MACRO(MANAPLUS_GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg)
+ # make it a real variable, so we can modify it here
+ SET(_firstPoFile "${_firstPoFileArg}")
+
+ SET(_gmoFiles)
+ GET_FILENAME_COMPONENT(_potBasename ${_potFile} NAME_WE)
+ GET_FILENAME_COMPONENT(_absPotFile ${_potFile} ABSOLUTE)
+
+ SET(_addToAll)
+ IF(${_firstPoFile} STREQUAL "ALL")
+ SET(_addToAll "ALL")
+ SET(_firstPoFile)
+ ENDIF(${_firstPoFile} STREQUAL "ALL")
+
+ FOREACH (_currentPoFile ${_firstPoFile} ${ARGN})
+ GET_FILENAME_COMPONENT(_absFile ${_currentPoFile} ABSOLUTE)
+ GET_FILENAME_COMPONENT(_abs_PATH ${_absFile} PATH)
+ GET_FILENAME_COMPONENT(_lang ${_absFile} NAME_WE)
+ SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo)
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_gmoFile}
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile}
+ DEPENDS ${_absPotFile} ${_absFile}
+ )
+
+ INSTALL(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo)
+ SET(_gmoFiles ${_gmoFiles} ${_gmoFile})
+
+ ENDFOREACH (_currentPoFile )
+
+ ADD_CUSTOM_TARGET(translations ${_addToAll} DEPENDS ${_gmoFiles})
+ENDMACRO(MANAPLUS_GETTEXT_CREATE_TRANSLATIONS )
+
+FILE(GLOB POFILES *.po)
+MANAPLUS_GETTEXT_CREATE_TRANSLATIONS(manaplus.pot ALL ${POFILES})
diff --git a/po/LINGUAS b/po/LINGUAS
new file mode 100644
index 000000000..7900f7602
--- /dev/null
+++ b/po/LINGUAS
@@ -0,0 +1,38 @@
+# Set of available languages.
+#ar # Disabled because of current client limitations (shaping, RTL)
+#bg # Not enough translations
+#ca # Not enough translations
+#cs # Not enough translations
+da
+de
+en_GB
+#eo # Not enough translations
+es
+#et # Not enough translations
+#fa # Disabled because of current client limitations (shaping, RTL)
+#fi # Not enough translations
+fr
+#he # Disabled because of current client limitations (RTL)
+hr
+hu
+#id # Not enough translations
+it
+#ja # Disabled because of current client limitations (font fallbacking)
+#ka # Not enough translations
+#nb # Not enough translations
+#nds # Not enough translations
+nl
+pl
+pt
+pt_BR
+ru
+#sk # Not enough translations
+#sq # Not enough translations
+sv
+#te # Disabled because of current client limitations (font fallbacking)
+#th # Disabled because of current client limitations (font fallbacking)
+#tr # Not enough translations
+#uk # Not enough translations
+#zh_CN # Disabled because of current client limitations (font fallbacking)
+#zh_HK # Disabled because of current client limitations (font fallbacking)
+#zh_TW # Disabled because of current client limitations (font fallbacking)
diff --git a/po/Makevars b/po/Makevars
new file mode 100644
index 000000000..91536b33f
--- /dev/null
+++ b/po/Makevars
@@ -0,0 +1,41 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = manaplus
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER = The Mana Developers
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS =
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 000000000..5b66fc2d4
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1,102 @@
+# List of source files which contain translatable strings.
+# Generated using: grep "_(" -Irl src | sort
+
+src/client.cpp
+src/commandhandler.cpp
+src/commandhandler.h
+src/game.cpp
+src/gui/beingpopup.cpp
+src/gui/botcheckerwindow.cpp
+src/gui/buy.cpp
+src/gui/buysell.cpp
+src/gui/changeemaildialog.cpp
+src/gui/changepassworddialog.cpp
+src/gui/charcreatedialog.cpp
+src/gui/charselectdialog.cpp
+src/gui/chat.cpp
+src/gui/confirmdialog.cpp
+src/gui/connectiondialog.cpp
+src/gui/debugwindow.cpp
+src/gui/editdialog.cpp
+src/gui/equipmentwindow.cpp
+src/gui/help.cpp
+src/gui/inventorywindow.cpp
+src/gui/itemamount.cpp
+src/gui/itempopup.cpp
+src/gui/killstats.cpp
+src/gui/login.cpp
+src/gui/minimap.cpp
+src/gui/ministatus.cpp
+src/gui/npcdialog.cpp
+src/gui/npcpostdialog.cpp
+src/gui/okdialog.cpp
+src/gui/outfitwindow.cpp
+src/gui/popupmenu.cpp
+src/gui/quitdialog.cpp
+src/gui/register.cpp
+src/gui/sdlinput.cpp
+src/gui/sdlinput.h
+src/gui/sell.cpp
+src/gui/serverdialog.cpp
+src/gui/setup_audio.cpp
+src/gui/setup_chat.cpp
+src/gui/setup_colors.cpp
+src/gui/setup.cpp
+src/gui/setup_joystick.cpp
+src/gui/setup_keyboard.cpp
+src/gui/setup_other.cpp
+src/gui/setup_players.cpp
+src/gui/setup_theme.cpp
+src/gui/setup_video.cpp
+src/gui/shopwindow.cpp
+src/gui/skilldialog.cpp
+src/gui/socialwindow.cpp
+src/gui/specialswindow.cpp
+src/gui/statuswindow.cpp
+src/gui/textcommandeditor.cpp
+src/gui/textdialog.cpp
+src/gui/trade.cpp
+src/gui/unregisterdialog.cpp
+src/gui/updatewindow.cpp
+src/gui/userpalette.cpp
+src/gui/whoisonline.cpp
+src/gui/widgets/channeltab.cpp
+src/gui/widgets/chattab.cpp
+src/gui/widgets/tradetab.cpp
+src/gui/widgets/whispertab.cpp
+src/gui/windowmenu.cpp
+src/gui/worldselectdialog.cpp
+src/keyboardconfig.cpp
+src/localplayer.cpp
+src/log.h
+src/main.cpp
+src/net/manaserv/attributes.cpp
+src/net/manaserv/beinghandler.cpp
+src/net/manaserv/charhandler.cpp
+src/net/manaserv/chathandler.cpp
+src/net/manaserv/guildhandler.cpp
+src/net/manaserv/loginhandler.cpp
+src/net/manaserv/partyhandler.cpp
+src/net/manaserv/playerhandler.cpp
+src/net/manaserv/tradehandler.cpp
+src/net/tmwa/adminhandler.cpp
+src/net/tmwa/buysellhandler.cpp
+src/net/tmwa/charserverhandler.cpp
+src/net/tmwa/chathandler.cpp
+src/net/tmwa/gamehandler.cpp
+src/net/tmwa/generalhandler.cpp
+src/net/tmwa/gui/guildtab.cpp
+src/net/tmwa/guildhandler.cpp
+src/net/tmwa/gui/partytab.cpp
+src/net/tmwa/inventoryhandler.cpp
+src/net/tmwa/loginhandler.cpp
+src/net/tmwa/network.cpp
+src/net/tmwa/partyhandler.cpp
+src/net/tmwa/playerhandler.cpp
+src/net/tmwa/specialhandler.cpp
+src/net/tmwa/tradehandler.cpp
+src/playerrelations.cpp
+src/resources/itemdb.cpp
+src/resources/monsterdb.cpp
+src/utils/gettext.h
+src/utils/stringutils.h
diff --git a/po/ar.po b/po/ar.po
new file mode 100644
index 000000000..5e4a85dce
--- /dev/null
+++ b/po/ar.po
@@ -0,0 +1,3631 @@
+# Arabic translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-06-08 22:01+0000\n"
+"Last-Translator: Thorbjørn Lindeijer <bjorn@lindeijer.nl>\n"
+"Language-Team: Arabic <ar@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=6; plural= n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
+"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "تثبيت"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "جارِ الاتّصال..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "ولوج"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "إنتقاء الشخصيّة"
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "خطأ"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "كلمة السرّ:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "تغيير"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "إلغاء التسجيل"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr ""
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr ""
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "شراء"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "مغادرة"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "بيع"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "إلغاء"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "يجب أن يكون طول اسم المستخدم على الأقل %d محارف."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "يجب أن يكون طول اسم المستخدم أقل من %d محارف."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "كلمة السرّ:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "يجب أن تكون طول كلمة السرّ على الأقل %d محارف."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "يجب أن يكون طول كلمة السرّ أقل من %d محارف."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "إنشاء شخصيّة"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "الاسم:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "لون الشعر:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "قصّة الشعر:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "إنشاء"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "رجاء أن توزّع %d نقطة"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "يجب أن يكون طول اسمك على الأقل 4 محارف."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "إحصائيات الشخصيّة جيّدة"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "رجاء حذف %d نقطة"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "هل أنت متأكّد من حذف هذه الشخصيّة؟"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "إلغاء التسجيل"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "تغيير"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "حذف"
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "نعم"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "لا"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "الاسم: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "خارطة صغيرة"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, fuzzy, c-format
+msgid "Ambient FX: %s"
+msgstr "مؤثّرات محيطة"
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "العتاد"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "تجريد من العتاد"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "الجردة"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "استعمال العتاد"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "استخدام"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "إسقاط"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "قسم"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "إسقاط"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "انتقاء كمّيّة من المواد للمتاجرة بها."
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "انتقاء كمّيّة من المواد لإسقاطها."
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "انتقاء كمّيّة من المواد لقسمها."
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "التأثير: %s"
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "ولوج"
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "تسجيل"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "تغيير"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "التّالي"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "التّالي"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "تجريد من العتاد"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "@@تجارة|متاجرة مع %s@@"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "مهاجمة %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "تبديل الخادوم"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "تبديل الشخصيّة"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "تأكيد:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "البريد الإلكترونيّ:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "يجب أن يكون طول اسم المستخدم على الأقل %d محارف."
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "يجب أن يكون طول اسم المستخدم أقل من %d محارف."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "يجب أن تكون طول كلمة السرّ على الأقل %d محارف."
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "يجب أن يكون طول كلمة السرّ أقل من %d محارف."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "كلمات السرّ غير متطابقة."
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "الخادوم:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "المنفذ:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "الخادوم:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "جارِ الاتّصال..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "مؤشّر مخصّص"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "رجاء طباعة عنوان ومنفذ الخادوم."
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "صوت"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "سمعيّ"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "حجم صوت المؤثرّات"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "حجم صوت الموسيقا"
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "تطبيق"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "تصفير النوافذ"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "إضغط على الزرّ لبدأ المعايرة"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "معايرة"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "تفعيل عصا الألعاب"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "عصا الألعاب"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "إيقاف"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "تدوير العصا"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "واقف"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "منخفض"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "مرتفع"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "ملء الشاشة"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "مؤشّر مخصّص"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "حدّ FPS:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "مرئية"
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "عتمة واجهة المستخدم"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr "مؤثّرات محيطة"
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "لا"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "جارِ ملء الشاشة"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "يجب إعادة التشغيل لتفعّل التغييرات."
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "تغيير OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "تطبيق التغيير على OpenGL يحتاج لإعادة تشغيل."
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "مهارات"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "مهارات"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "المستوى: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "المستوى: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "هل أنت متأكّد من حذف هذه الشخصيّة؟"
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "هل أنت متأكّد من حذف هذه الشخصيّة؟"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "إنشاء شخصيّة"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "المستوى: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "النقود: %d"
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "إحصائيات الشخصيّة جيّدة"
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "المستوى: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "اقتراح متاجرة"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "إضافة"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "أنت تقدّم:"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "أنت تقدّم:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "تغيير"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "الاسم: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "جارِ الاتّصال..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "الحالة"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "اختصار"
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "تغيير"
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "القوّة:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "خفّة الحركة:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "نشاط:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "ذكاء:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "المهارة:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "الاسم:"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "دفاع %+d"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "مهاجمة %+d"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "دفاع %+d"
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+msgid "Unknown error."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "إلغاء التسجيل"
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "أنت تقدّم:"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "إحصائيات الشخصيّة جيّدة"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "إحصائيات الشخصيّة جيّدة"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "انتقاء كمّيّة من المواد للمتاجرة بها."
+
+#: src/net/manaserv/charhandler.cpp:202
+#, c-format
+msgid "Unknown error (%d)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "قوّة الذات:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+msgid "Unknown channel event."
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "قوّة الذات:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "مهاجمة %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "دفاع %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Description: %s"
+#~ msgstr "الوصف: %s"
+
+#~ msgid "Previous"
+#~ msgstr "السّابق"
+
+#~ msgid "New"
+#~ msgstr "جديد"
+
+#~ msgid "Ok"
+#~ msgstr "موافق"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@مهاجمة|هاجم %s@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@إلغاء|إلغاء@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@استخدام|استخدام العتاد@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@استخدم|استخدم@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@إسقاط|إسقاط@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@قسم|قسم@@"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@اقتطاف|اقتطاف %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "نصف قطر اللفّ"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "كسل اللفّ"
diff --git a/po/bg.po b/po/bg.po
new file mode 100644
index 000000000..88618c95e
--- /dev/null
+++ b/po/bg.po
@@ -0,0 +1,3559 @@
+# Bulgarian translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-10-21 13:06+0000\n"
+"Last-Translator: Mila <Unknown>\n"
+"Language-Team: Bulgarian <bg@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr ""
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+msgid "Password Change"
+msgstr ""
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Непозната команда."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- Помощ --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr ""
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:134
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:123
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+msgid "Change Email"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, c-format
+msgid "Map: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+msgid "None"
+msgstr ""
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:416
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+msgid "Create Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+msgid "Level"
+msgstr ""
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Game"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+msgid "Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Непозната команда."
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Непозната команда."
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Непозната команда."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
diff --git a/po/ca.po b/po/ca.po
new file mode 100644
index 000000000..1722d9db7
--- /dev/null
+++ b/po/ca.po
@@ -0,0 +1,3566 @@
+# Catalan translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-06-08 22:01+0000\n"
+"Last-Translator: Thorbjørn Lindeijer <bjorn@lindeijer.nl>\n"
+"Language-Team: Catalan <ca@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr ""
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+msgid "Password Change"
+msgstr ""
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "canvi"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr ""
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr ""
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "sortir"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:134
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:123
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "nom"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "canvi"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "si"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "no"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, c-format
+msgid "Map: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "canvi"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "no"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:416
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+msgid "Create Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+msgid "Level"
+msgstr ""
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "canvi"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "canvi"
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "nom"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+msgid "Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+msgid "Unknown error."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, c-format
+msgid "Unknown error (%d)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+msgid "Unknown channel event."
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Ok"
+#~ msgstr "ok"
diff --git a/po/cs.po b/po/cs.po
new file mode 100644
index 000000000..06a9fb632
--- /dev/null
+++ b/po/cs.po
@@ -0,0 +1,3720 @@
+# Czech translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-12-04 15:16+0000\n"
+"Last-Translator: David Kolibáč <david@kolibac.cz>\n"
+"Language-Team: Czech <cs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "Nastavení"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Čeká se na server"
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "Přihlášení"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Vyber postavu"
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Chyba"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Heslo:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "Změnit"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Zrušit registraci"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Neznámý příkaz."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- Nápověda --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/help > Zobrazit tuto nápovědu"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > Zobrazit jméno mapy"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > Zobrazit počet uživatelů on-line"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > Říct něco o sobě"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > Vyčistit toto okno"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Odeslat soukromou zprávu uživateli"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Jiné označení pro msg"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > Jiné označení pro msg"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Založit kartu pro soukromé zprávy jinému uživateli"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q > Jiné označení pro query"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > Zobrazit seznam všech veřejných kanálů"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/join > Připojit se, nebo vytvořit kanál"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/party >Pozvat uživatele do party"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "/party >Pozvat uživatele do party"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/record > Spustit nahrávání záznamu chatu do externího souboru"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Globální oznámení (jen GM)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "Pro bližší informace zadejte /help <command>."
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "Příkaz: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "Tento příkaz zobrazí seznam všech příkazů, které jsou k dispozici."
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "Příkaz: /help <command>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "Tento příkaz zobrazí nápovědu k <command>."
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "Příkaz: /announce <msg>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** K dispozici pouze pro GM ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Tento příkaz odešle zprávu <msg> všem hráčům, kteří jsou on-line."
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "Příkaz: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "Tento příkaz vyčistí záznam předchozího chatu."
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Příkaz: /join <channel>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Tento příkaz zobrazí počet hráčů, kteří jsou momentálně online."
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "Příkaz: /join <channel>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "Tento příkaz vás připojí ke kanálu <channel>."
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Pokud <channel> neexistuje, bude vytvořen."
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "Příkaz: /list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "Tento příkaz zobrazí seznam všech kanálů."
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "Příkaz: /me <message>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "Příkaz: /msg <nick> <message>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "Příkaz: /whisper <nick> <message>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "Příkaz: /w <nick> <message>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "Tento příkaz odešle zprávu <message> uživateli <nick>."
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Pokud <nick> obsahuje mezeru, uzavřete jej do uvozovek (\")."
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "Příkaz: /query <nick>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "Příkaz: /q <nick>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Příkaz: /party <nick>"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Tento příkaz vás připojí ke kanálu <channel>."
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "Příkaz: /party <nick>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "Příkaz: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "Příkaz: /record <filename>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "Příkaz: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr "Příkaz: /toggle <state>"
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr "Příkaz: /toggle"
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Příkaz: /announce <msg>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "Tento příkaz zobrazí název aktuální mapy."
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "Tento příkaz zobrazí počet hráčů, kteří jsou momentálně online."
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Snímek obrazovky uložen do ~/"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "Ukládání snímku obrazovky selhalo!"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Připojení k serveru bylo ztraceno, program nyní bude ukončen"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "Chyba sítě"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr "Ignorovat příchozí žádosti o obchodování"
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "Akceptovat příchozí žádosti o obchodování"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Nelze nahrát mapu"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "Chyba při načítání %s"
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Parta (%s)"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "Nákup"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Ukončit"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "Vše"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "Obchod"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Prodej"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "Zrušit"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Změnit e-mail"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Účet: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Zadejte dvakrát nový e-mail:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Uživatelské jméno musí být nejméně %d znaků dlouhé."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Uživatelské jméno musí být kratší než %d znaků."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "Změnit heslo"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Heslo:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Zadejte dvakrát nové heslo:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Heslo musí být dlouhé nejméně %d znaků."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Heslo musí být kratší než %d znaků."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Vytvořit postavu"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "Jméno:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Barva vlasů:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Účes:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "Vytvořit"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "Muž"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "Žena"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Rozdělte prosím %d bodů"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Vaše jméno musí mít nejméně 4 znaky."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Odstraňte prosím %d bodů."
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "Potvrďte smazání postavy"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Jste si jistí, že chcete smazat tuto postavu?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "Správa účtu a postavy"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Zrušit registraci"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Změnit e-mail"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Smazat"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "Barvy"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:287
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d hráči jsou přítomni."
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Ano"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Ne"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "Jméno: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "Peníze: %s"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Účet: %s"
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Vybavení"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "Odstranit z vybavení"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "Pomoc"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "Inventář"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "Vybavit"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Použít"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "Upustit"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "Rozdělit"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr "Sloty:"
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "Hmotnost:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "Upustit"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "Vše"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "Vyberte množství předmětů, se kterými budete obchodovat."
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "Vyberte množství předmětů, které chcete upustit."
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Hmotnost: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "Přihlášení"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "Zapamatovat uživatelské jméno"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Registrace"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "Mapa"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "Čeká se na server"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Další"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "Reset"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Další"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "Odeslat"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "Odstranit z vybavení"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "Text"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "Pozadí"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr "Zvýraznit"
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "Předmět je příliš drahý"
+
+#: src/gui/palette.cpp:94
+#, fuzzy
+msgid "Item Is Equipped"
+msgstr "Předmět je ve vybavení"
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr "GM"
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "Hráč"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr "Šeptat"
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr "Je"
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "Parta"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr "Guilda"
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "Server"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "Jména ostatních hráčů"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "Jména GM"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "Monstra"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "Klobouky"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+#, fuzzy
+msgid "One Handed Weapons"
+msgstr "Jednoruční zbraně"
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "Kalhoty"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "Boty"
+
+#: src/gui/palette.cpp:122
+#, fuzzy
+msgid "Two Handed Weapons"
+msgstr "Jednoruční zbraně"
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "Štíty"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "Prsteny"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "Náhrdelníky"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "Munice"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr "Kritický zásah"
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "Útok %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "Šeptat"
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "%s vás zve ke vstupu do své party."
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "Monstra"
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "Přepněte postavu"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "Potvrdit:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "E-mail:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Uživatelské jméno musí být nejméně %d znaků dlouhé."
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Uživatelské jméno musí být kratší než %d znaků."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Heslo musí být dlouhé nejméně %d znaků."
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Heslo musí být kratší než %d znaků."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Hesla se neshodují."
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Vyberte si server"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "Připojuji se..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Vlastní kurzor"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "Prosím zadejte adresu a port serveru."
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Čeká se na server"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "Zvuk"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Hlasitost efektů"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Hlasitost hudby"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "Bez textu"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "Barvy"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "Typ: "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "Puls"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "Duha"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "Spektrum"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "Hrát"
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "Červená: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "Zelená: "
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Použít"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "Stiskněte tlačítko pro zahájení kalibrace"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "Kalibrovat"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Zapnout joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "Zastavit"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Klávesnice"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "Výchozí"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "Jméno"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "Neutrální"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "Povolit obchodování"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "Hráči"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "Malý"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "Střední"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "Velký"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "Bez textu"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "vypnout"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "nízký"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "vysoký"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "střední"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "Celá obrazovka"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "Vlastní kurzor"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "Velikost písma"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Ne"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Přepnout na celou obrazovku"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "Pro uplatnění změn je potřeba restart."
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Přepnout OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "Změny v OpenGL vyžadují restart."
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr "Změny se projeví až po změně mapy."
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Dovednosti"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Dovednosti"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Úroveň: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Úroveň: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Vytvořit guildu"
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Opravdu chcete skončit?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party >Pozvat uživatele do party"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party >Pozvat uživatele do party"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Opravdu chcete skončit?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr "Vytvořit guildu"
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Vytvořit postavu"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "Pozvat uživatele"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "Velký"
+
+#: src/gui/socialwindow.cpp:394
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Přijmout pozvání od %s."
+
+#: src/gui/socialwindow.cpp:400
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Odmítnout pozvání od %s."
+
+#: src/gui/socialwindow.cpp:413
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Přijmout pozvání od %s."
+
+#: src/gui/socialwindow.cpp:419
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Odmítnout pozvání od %s."
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "Guilda"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Vyberte si server"
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s vás zve ke vstupu do party: %s"
+
+#: src/gui/socialwindow.cpp:507
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Přijmout pozvání do party"
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s vás zve ke vstupu do své party."
+
+#: src/gui/socialwindow.cpp:533
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s vás zve ke vstupu do party: %s"
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s vás zve ke vstupu do své party."
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s vás zve ke vstupu do party: %s"
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr "Přijmout pozvání do party"
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "Parta"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Vyberte si server"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Úroveň: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "Peníze: %s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+#, fuzzy
+msgid "Exp"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Peníze: %d"
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Úroveň: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "Nabídnout obchod"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr "Souhlasit s obchodem"
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "Obchod"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "Přidat"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "Změnit"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "Nemáte dost peněz."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Jméno: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "Aktualizuje se..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "Připojuji se..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr "Hrát"
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Pokud jste poslední osobou v kanálu, kanál bude smazán."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "Globální oznámení:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Globální oznámení od %s:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr "Nelze poslat prázdný chat!"
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Příkaz: /record"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Tento příkaz zobrazí počet hráčů, kteří jsou momentálně online."
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "Stav"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "Zkratka"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "Vyberte server"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "Změnit"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "Vyberte si server"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr "Útok"
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr "Cíl & Útok"
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr "Smajlíky"
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr "Zastavit Útok"
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "Monstra"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr "Sednout si"
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "Snímek obrazovky"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr "Nastavení:"
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "/help > Zobrazit tuto nápovědu"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr "Děkuji za nákup."
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr "Děkuji za prodej."
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+#, fuzzy
+msgid "Access denied."
+msgstr "Přístup zamítnut"
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr "Info"
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "Síla:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "Hbitost:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "Vitalita:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "Inteligence:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "Obratnost:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr "Štěstí:"
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "Hráč"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "Jméno"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "Síla"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "Hbitost"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "Vitalita"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "Inteligence"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "Obratnost"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "Štěstí"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Obrana:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "M.Útok:"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "M.Obrana:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Přesnost:"
+
+#: src/net/ea/generalhandler.cpp:228
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Únik:"
+
+#: src/net/ea/generalhandler.cpp:229
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Kritický zásah"
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/party >Pozvat uživatele do party"
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Tento příkaz odešle zprávu <message> uživateli <nick>."
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Neznámý předmět"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Zrušit registraci"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "Špatné heslo"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Odmítnout pozvání od %s."
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Vyberte množství předmětů, se kterými budete obchodovat."
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Neznámý příkaz."
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Příkaz: /join <channel>"
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Neznámý příkaz."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "Šeptat"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Zadejte dvakrát nové heslo:"
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Zadejte dvakrát nový e-mail:"
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Chybné uživatelské jméno nebo heslo"
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Chybné uživatelské jméno, heslo nebo e-mail"
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "Odmítnout pozvání od %s."
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "Útok %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "Obrana %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr "Neznámý předmět"
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "no"
+#~ msgstr "ne"
+
+#~ msgid "Buddy"
+#~ msgstr "Kamarád"
+
+#~ msgid "Buddy List"
+#~ msgstr "Seznam kamarádů"
+
+#~ msgid "Description: %s"
+#~ msgstr "Popis: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Účinek: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Předchozí"
+
+#~ msgid "New"
+#~ msgstr "Nová"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Úroveň povolání: %d"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Obouruční zbraně"
+
+#~ msgid "fullscreen"
+#~ msgstr "celá obrazovka"
+
+#~ msgid "Weapons"
+#~ msgstr "Zbraně"
+
+#~ msgid "Crafts"
+#~ msgstr "Řemesla"
+
+#~ msgid "Cost"
+#~ msgstr "Cena"
+
+#~ msgid "Attack:"
+#~ msgstr "Útok:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Reakce:"
+
+#~ msgid "Guilds"
+#~ msgstr "Gildy"
+
+#~ msgid "Unarmed"
+#~ msgstr "Neozbrojený"
+
+#~ msgid "Knife"
+#~ msgstr "Nůž"
+
+#~ msgid "Sword"
+#~ msgstr "Meč"
+
+#~ msgid "Staff"
+#~ msgstr "Hůl"
+
+#~ msgid "Whip"
+#~ msgstr "Bič"
+
+#~ msgid "Bow"
+#~ msgstr "Luk"
+
+#~ msgid "Mace"
+#~ msgstr "Palcát"
+
+#~ msgid "Axe"
+#~ msgstr "Sekera"
+
+#~ msgid "mana"
+#~ msgstr "mana"
diff --git a/po/da.po b/po/da.po
new file mode 100644
index 000000000..a06bdd149
--- /dev/null
+++ b/po/da.po
@@ -0,0 +1,5711 @@
+# Danish translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2009-07-25 17:33+0000\n"
+"Last-Translator: Niels L Ellegaard <niels.ellegaard@gmail.com>\n"
+"Language-Team: Danish <none@none.none>\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Opsætning"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Opretter forbindelse til kort-serveren..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Log Ind"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Vælg Karakter"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Opretter forbindelse til kort-serveren..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Server"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Fejl"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Adgangskode:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Ændre"
+
+#: src/client.cpp:1093
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Frameld"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Ugyldig opdaterings host: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Fejl under oprettelsen af opdateringen mappen!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Ukendt kommando"
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "--Hjælp--"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Vis denne hjælpebesked"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Vis dine koordinater på kortet"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Vis antallet af spillere der er online"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Vis en beskrivelse af dig"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Sletter text i chat-vinduet."
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Send en privat besked til en spiller"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Samme som msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Samme som msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Starter en privat samtale med en spiller"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Samme som query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Lukker hviskesamtale-tabben"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+msgid "/desregard > Disregard a player"
+msgstr ""
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Vis alle offentlige chat-kanaler"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Deltag i en chat-kanal"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Opret en ny gruppe"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Opret en ny gruppe"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Inviter en spiller til din gruppe"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Afgør om et tryk på retur-knappen skal aktivere chatvinduet."
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Vis en liste af alle spillere på serveren (Sendes til chat-loggen "
+"hvis den er slået til)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Send en besked til allle spillere (Kun for GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Lukker hviskesamtale-tabben"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Send en privat besked til en spiller"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "/help <kommando> > Vis en detaljeret beskrivelse af <kommando>"
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Kommando: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Denne kommando viser en liste over alle tilgængelige kommandoer"
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Kommando: /help <kommando>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Denne kommando viser hjælp for <kommando>"
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Kommando: /announce <besked>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** kun tilgængelig for en GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Denne kommando sender beskeden <besked> til alle brugere online."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Kommando: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Denne kommando rydder chat loggen"
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Kommand: /item <regel>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+"Denne kommando viser det antal af online brugere, der er online lige nu."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Kommando: : /join <chat-kanal>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Denne kommando tilmelder dig til <chat-kanal>"
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Hvis <chat-kanal> ikke eksisterer, så bliver den oprettet."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Kommando: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Denne kommando viser en liste over alle chat-kanaler."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Kommando: /me <besked>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Denne kommando fortæller andre at du er (eller gør) <besked>"
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Kommando: /msg <spiller> <besked>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Kommando: /whisper <spiller> <besked>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Kommando: /w <spiller> <besked>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Denne kommando sender <besked> til <spiller>"
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Hvis <spilller> (altså spillerens navn) indeholder mellemrum, så kan du "
+"sætter gåseøjne (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Kommando: /query <spilller>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Kommando: /q <spiller>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Denne kommando opretter en ny tab med privat samtale mellem dig og <nick>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Kommando: /w <spiller> <besked>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Kommando: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Denne kommando sætter kanalens emne til <besked>"
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Kommando: /create <gruppe>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Disse kommandoer opretter en gruppe ved navn <gruppe>"
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Kommando: /create <gruppe>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Disse kommandoer opretter en gruppe ved navn <gruppe>"
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Denne kommando inviterer <spiller> til din gruppe."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Kommando: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Denne kommando finder en liste over brugere, der er inden for en "
+"lytteradius, og sender listen til enten record loggen, hvis du optager, "
+"ellers er det chat loggen."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Kommando /toggle <tilstand>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Denne kommando bestemmer om retur, skal bruges til at fokusere på chat "
+"loggen, ellerom chat om chat loggen, automatisk skal slå fra."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<tilstand> kan være en ud af \"1\", \"yes\", \"true\" for at slå fokusering "
+"af chat vindue til, eller \"0\", \"no\", \"false\" for at slå fokusering af "
+"chat vindue fra."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Kommando: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Denne kommando viser fokusering af chat vinduets status."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Kommand: /item <regel>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "kommando: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Denne kommando viser det nuværende bane navn."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Kommando: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr ""
+"Denne kommando viser det antal af online brugere, der er online lige nu."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Skriv /help for at få en liste med kommandoer"
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "du kan ikke sende en hviskebesked uden tekst!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Du glemte at skrive et navn på dit party."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Du glemte at skrive et navn på dit party."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Retur bringer focus på chatten."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Besked lukker chat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Enter bringer nu focus på chatten."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Besked lukker nu chat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Ven"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Se bort fra"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutral"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Beskeden blev ikke læst. Modtageren ignorerer den."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Du har nu oprettet gruppen."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Beskeden blev ikke læst. Modtageren ignorerer den."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Beskeden blev ikke læst. Modtageren ignorerer den."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Beskeden blev ikke læst. Modtageren ignorerer den."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Du har nu oprettet gruppen."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Beskeden blev ikke læst. Modtageren ignorerer den."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Skærmbillede gemt under ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Gemningen af skærmbilledet fejlede!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Forbindelsen til serveren er tabt, programmet vil nu lukke"
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Netværksfejl"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignorerer indkomne handels anmodninger"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Accepterer indkomne handels anmodninger"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Kunne ikke loade kortet"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Kunne ikke loade %s."
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Gruppe (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Guilds"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Chat-vindue"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Navn"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Angrib"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Snak"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Flyt op"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Nulstil"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Køb"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Pris: %s / Total: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Afslut"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Maks"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "butik"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Sælg"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Fortryd"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Skift e-mail adresse"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Konto: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Skriv den nye email-adresse to gange"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Brugernavnet skal mindst være %d bogstaver langt."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Brugernavnet skal være mindre end %d bogstaver langt."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Den nye email-adresse eksisterer allerede."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Skift adgangskode"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Adgangskode:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Skriv den nye email-adresse to gange"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Adgangskoden skal mindst være %d bogstaver langt."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Adgangskoden skal være mindre end %d bogstaver langt."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Lav en ny karakter."
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Navn:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Hårfarve:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Frisure:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Opret"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Mand"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Kvinde"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Du mangler at fordele %d points"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Dit navn skal være mindst 4 bogstaver langt."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Du har brugt alle dine points"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Du skal fjerne %d points"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Bekræft sletning af karakter"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Er du sikker på at du vil slette denne karakter?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Ret konto og karakter"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Frameld"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Skift e-mail adresse"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Slet"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Luk"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Standard"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Ven"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Grøn: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Blå: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "lav"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Hyperlink"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Kastevåben"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Regnbuefarvet"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Regnbuefarvet"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Regnbuefarvet"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "Der er %d spillere til stede"
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Hvisker til %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Ja"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Nej"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignorer"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Lydstyrke på musik"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Navn: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "MiniKort"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Partikeleffekter"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Du har brugt alle dine points"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Spiller rammer monster"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Flyt til venstre"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Vælg spiller som ny modstander"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Vælg spiller som ny modstander"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Vælg spiller som ny modstander"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Vælg spiller som ny modstander"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Brugerdefineret cursor"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Udstyr"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Tag af"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Hjælp"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Luk"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventarliste"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Opbevaret"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Tag på"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Brug"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Smid"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Opdel"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Vægt:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Gem på lager"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Hent fra lager"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Smid"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Alle"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Vælg hvor mange genstande du vil bytte."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Vælg hvor mange genstande du vil smide."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Vælg hvor mange genstande du vil lagre"
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Vælg hvor mange genstande du vil opdele."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Ukendt fejl"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Vægt: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Statsvindue"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Nulstil"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Nulstil"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Niveau: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Flyt til venstre"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Luk"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Log Ind"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Husk Brugernavn"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registrer"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Kort"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Venter på serveren"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Næste"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Send forespørgsel"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Hellebard"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Næste"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Til:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Send"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Kunne ikke sende brevet. Afsender eller brev er ugyldigt."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Penge: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Tag af"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Handl med %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Angrib %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Brug@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Annuller@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Hent fra lager@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+msgid "@@disregard|Disregard@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignorer %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Brug@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Hold op med at ignorere %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore||Ignorer %s fuldstændigt@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Inviter en spiller til din gruppe"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Spark spiller ud@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Spark spiller ud@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Inviter en spiller til din gruppe"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Spark spiller ud@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Hold op med at ignorere %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Brug@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Angrib %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Spark spiller ud@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Tilføj navn til chat@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Annuller@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Saml %s op@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Tilføj til chat@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Brug@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Fremhæv tab"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Fremhæv tab"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Ændre"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Gem på lager"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Gem på lager"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Gem på lager"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Hent fra lager"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Hent fra lager"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Hent fra lager"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Tilføj til chat@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Skift server"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Skift karakter"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Bekræft:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "E-mail:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Brugernavnet skal mindst være %d bogstaver langt."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Brugernavnet skal være mindre end %d bogstaver langt."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Adgangskoden skal mindst være %d bogstaver langt."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Adgangskoden skal være mindre end %d bogstaver langt."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "De indtastede adgangskoder stemmer ikke overens."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Vælg din server"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Opretter forbindelse..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Brugerdefineret cursor"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Skriv både adressen og porten på serveren."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Venter på serveren"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Aktiver joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Aktiver joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Lyd"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Lydstyrke på effekter"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Lydstyrke på musik"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Ingen tekst"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Du kan ikke købe."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Du kan ikke købe."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Vis navn"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Sådan ser farven ud."
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Farver"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Type: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Fastlåst"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulserende"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Regnbuefarvet"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Spektrum"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Forsinkelse: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Rød: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Grøn: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Blå: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Anvend"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Nulstil Vinduer"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Tryk på knappen for at starte justeringen."
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Justering"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Aktiver joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Stop"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Rotere joysticket"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Tastatur"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Tildel"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Tildel"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Standard"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Tast Konfikt(er) Opdaget."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Fremhæv"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Vis navn"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Aktiver joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Fremhæv"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Slå handler fra/til"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Du kan ikke købe."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Du kan ikke købe."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Aktiver joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "som partikeleffekt"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relation"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutral"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Ven"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Se bort fra"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignorer"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Tillad handel"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Tillad hviskere"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Placer alle hviskesamtaler i en tab"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Vis navn"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Brugere"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Når ignorer:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Vis navn"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Vis navn"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Vælg spiller som ny modstander"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Partikeleffekter"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Hjælp"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Ændre"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Ændringerne kræver at du genstarter klienten."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Meget lille"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Lille"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Middel"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Stor"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Ingen tekst"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Tekst"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Bobler uden navne"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Bobler med navne"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "deaktiveret"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "lav"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "høj"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "mellem"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "maks"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Fuld Skærm"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relation"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Brugerdefineret cursor"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Synlige navne"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Partikeleffekter"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Vis besked når noget samles op"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "i chat"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "som partikeleffekt"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Aktiver joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Baggrund"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS-grænse:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "FPS-grænse:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Gennemsigtighed"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Omgivende FX"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Partikeldetaljer"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Skriftstørrelse"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Nej"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "opsætning og genoprettelse af gammel opsætning fejlede også!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "opsætning og genoprettelse af gammel opsætning fejlede også!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Skifter til fuld skærm"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Ændringerne kræver at du genstarter klienten."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Skrifter til OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Ændringerne til OpenGL kræver at du genstarter klienten."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Skærmopløsning ændret"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Ændrede Partikeleffekter."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Ændringerne træder i kraft når du er går til et nyt kort."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Tilføj"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Anmodning om byttehandel."
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s vil gerne handle med dig. Accepterer du?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Færdigheder"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Op"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Færdigheds-points: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Færdigheds-points: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Færdigheder"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Niveau: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Niveau: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Opret en guild"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Oprettede en ny guild"
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Opret en guild"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "ER du sikker på at du vil afslutte programmet?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Gruppe"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Inviter en spiller til din gruppe"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Inviter en spiller til din gruppe"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "ER du sikker på at du vil afslutte programmet?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Opret en guild"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Lav en ny karakter."
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Inviter en spiller"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Stor"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Du har accepteret en invitation fra %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Du har ignoreret en invitation fra %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Du har accepteret en invitation fra %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Du har ignoreret en invitation fra %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Der opstod en fejl. Guilden kunne ikke oprettes"
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Opret en guild"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Vælg din server"
+
+#: src/gui/socialwindow.cpp:1108
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s har inviteret med i %s's gruppe."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Accepter invitationen"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s har inviteret med i sin gruppe"
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s har inviteret med i %s's gruppe."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s har inviteret med i sin gruppe"
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s har inviteret med i %s's gruppe."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Accepter invitationen"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Gruppe"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Vælg din server"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Niveau: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Penge: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr ""
+"Copy text \t\r\n"
+"Job: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Job:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Du har brugt alle dine points"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Niveau: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Færdigheds-points: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Flyt til venstre"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Tillad handel"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Flyt til venstre"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Alment formål"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magi"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magi"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Kommando: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magi"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Kommando: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Vælg spiller som ny modstander"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Maks. level"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Vis navn"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Foreslå handel"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Bekræftet. Venter..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Accepter handel"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Godkendt. Venter..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Handel: Dig"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Handl"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Du får %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Du giver:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Ændre"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Fejlede i at tilføje genstand. Du kan ikke overlappe en slags genstand på "
+"vinduet."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Du har ikke penge nok."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Navn: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Updatere..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Opretter forbindelse..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Spil"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Opdateringsprocessen er ikke færdiggjort"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Det er varmt anbefalet at"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 du prøver igen senere"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Udført"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Skabning"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Ven"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Se bort fra"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignorer"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "GM-navne"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Andre spilleres navne"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Eget navn"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "GM-navne"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPC'er"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monstre"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monster rammer spiller"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Gruppe"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Opret en guild"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Partikeleffekter"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Opsamlingsnotits"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "XP-notits"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Spiller rammer monster"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Monster rammer spiller"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Andre spilleres navne"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Kritisk sår"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Spiller rammer monster"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Spiller rammer monster"
+
+#: src/gui/userpalette.cpp:137
+#, fuzzy
+msgid "Local Player Miss"
+msgstr "Gem bruger liste"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Rammer forbi"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Fremhæv tab"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Fremhæv"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Fremhæv tab"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monster rammer spiller"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Vis alle brugere på kanalen"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Vælg emne for denne kanal"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Forlad denne kanal"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Udnævn en bruger til operator"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Spark en bruger ud af kanalen"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Kommando: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Denne kommando viser alle brugere på kanalen"
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Kommando: /topic <besked>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Denne kommando sætter kanalens emne til <besked>"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Kommando: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Denne kommando forlader kanalen"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Hvis du er den sidste person på kanalen vil den blive slettet."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Kommando: /op <navn>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Denne kommando gør <navn> til operator"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"En operator kan gøre andre brugere til operators eller sparke dem ud af "
+"kanalen."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Kommando: /kick <navn>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Denne kommando sparker <navn> ud af kanalen"
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Du glemte at skrive navnet på den bruger der skal blive operator"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+"Du glemte at skrive navnet på den bruger der skal sparkes ud af kanalen"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Besked til alle."
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Besked fra %s til alle:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s hvisker: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Lukker hviskesamtale-tabben"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Kommando: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Denne kommando lukker den aktuelle hviskesamtale-tab"
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Kommando: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+"Denne kommando viser det antal af online brugere, der er online lige nu."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Denne kommando starter med at \"optage\" chat-loggen. Den gemmer en kopi i "
+"<filnavn>"
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Chat-vindue"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Smiley"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Genvej"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Vælg OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Ændre"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Vælg din server"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Flyt op"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Flyt ned"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Flyt til venstre"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Flyt til højre"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Vælg modstander og angrib"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Flyt til venstre"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Smiley"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Stop angreb"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Vælg nærmeste monster som ny modstander"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Vælg NPC som ny modstander"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Vælg spiller som ny modstander"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Saml op"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Gem vinduer"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Sid"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Gem skærmbillede som fil"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Slå handler fra/til"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Skift e-mail adresse"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Shortcut %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Shortcut %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Hjælpevindue"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Statsvindue"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Færdigheds-vindue"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Minikort"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Chat-vindue"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Opsætnings-vindue"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Debug-vindue"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Færdigheds-vindue"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Statsvindue"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Opsætnings-vindue"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Gem vinduer"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Statsvindue"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Kommando: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Chat-vindue"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Gå til sidste chat tab"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Gå til næste chat tab"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Slå chat til eller fra"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Scroll chat op"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Scroll chat ned"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Gå til sidste chat tab"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Gå til næste chat tab"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Gå til sidste chat tab"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Gå til næste chat tab"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Vælg OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Flyt ned"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Flyt til venstre"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Flyt til højre"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Skift karakter"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Server"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Vælg modstander og angrib"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Skift adgangskode"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Skift e-mail adresse"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Slå handler fra/til"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Løs problemet, ellers kan spillet risikere at opfører sig ustabilt."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Du samlede %s [@@%d|%s@@] op."
+msgstr[1] "Du samlede %s [@@%d|%s@@] op."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Du får %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Indstillinger:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Ønsket konfigurationsfil"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Ønsket konfigurationsfil"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Vis versionsnummer"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Vis denne hjælpebesked"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Ønsket konfigurationsfil"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Anvend dette brugernavn"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Anvend dette password"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Log på som denne karakter"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Login server navn or IP"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Login server port"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -u --skip-update : Undlad at hente updateringer"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Vælg karakter-server og karakter"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Undlad at hente updateringer"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Directory med data til spillet"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Directory der skal bruges som hjemmekatalog"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Directory der skal bruges som hjemmekatalog"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Start mana uden OpenGL"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Styrke"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Styrke %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Adræthed"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Adræthed %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Behændighed"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Behændighed %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Helbred"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Helbred %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligens"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligens %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Viljestyrke:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Viljestyrke:"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Du er død."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+"Vi beklager at måtte informere dig, om at din karakter var dræbt i kamp."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Du er ikke så levende som du engang har været."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Manden med leen griber ud efter din sjæl."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Game Over!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Nej, børn. Din karakter døde ikke rigtigt. Den.. err... tog til et bedre "
+"sted."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr "Din plan om at smadre fjendens våben, ved at benytte din hals fejlede."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Jeg går ud fra at dette ikke gik alt for godt."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Du vil gerne have dine ejendele identificeret?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Desværre, blev der aldrig fundet noget spor efter dig..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Udslettet."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Det ser ud til at du fik du hoved udleveret til dig."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "Du kvajede dig igen, smid din krop ned i kloakken og find dig en ny."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Tryk OK for at genopstå"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Du er død"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Allerede logget ind"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Brugernavnet er allerede benyttet af en anden bruger."
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Du har brugt alle dine points"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Du har brugt alle dine points"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Ukendt fejl"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Info"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Karakteren er slettet"
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Vælg hvor mange genstande du vil bytte."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Ukendt fejl"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Der er ingen tilgængelige spilservere."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Spiller rammer monster"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Kommando: : /join <chat-kanal>"
+
+#: src/net/manaserv/chathandler.cpp:213
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s blev medlem af gruppen."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Ukendt kommando"
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Oprettede en ny guild"
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Der opstod en fejl. Guilden kunne ikke oprettes"
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Invitationen er afsendt."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Forkert magic_token"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Allerede logget ind"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Kontoen er slettet"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "De nye password stemmer ikke overens."
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Det gamle password var ikke korrekt."
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Kontoen er ikke tilsluttet. Du skal først logge ind."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Den nye email-adresse er ikke gyldig."
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Den gamle email-adresse er ikke gyldig."
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Den nye email-adresse eksisterer allerede."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Du bruger en for gammel version af klienten."
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Forkert brugernavn eller password"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Kontoen er slettet"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Forkert brugernavn, password eller email-adresse."
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Brugernavnet er allerede benyttet af en anden bruger."
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "email-adressen er allerede benyttet af en anden bruger."
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s blev medlem af gruppen."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s afviste din invitation."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Kan modtager anmodninger om byttehandler."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignorerer anmodninger om byttehandler."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s vil gerne handle med dig. Accepterer du?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Handler med %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Handel annulleret."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Handel er komplet."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Du kunne ikke sparke denne bruger af kanalen"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Brugeren er sparket ud af kanalen"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Du har intet at sælge."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Tak for købet."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Du kan ikke købe."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Tak for en god handel."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Kunne ikke sælge."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Kan ikke bruge denne ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Ukendt fejl"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Karakteren kunne ikke oprettes. Måske er navnet allerede brug."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Karakteren er slettet"
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Kunne ikke slette karakteren."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Styrke:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Adræthed:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Helbred:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligens:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Behændighed:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Held:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Beskeden kunne ikke sendes. Modtageren er ikke logget på."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Beskeden blev ikke læst. Modtageren ignorerer den."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Bruger"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Bruger"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Serveren understøtter ikke kanaler!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Navn"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Anmodning om byttehandel."
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Styrke %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Adræthed %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Helbred %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligens %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Behændighed %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Held %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Godkendelse fejlede"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Der er ingen tilgængelige servere"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "En anden bruger forsøger at logge ind på denne brugerkonto"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Der er allerede logget en bruger ind på denne brugerkonto"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Dit hastighedshack blev opdaget af serveren."
+
+#: src/net/tmwa/generalhandler.cpp:151
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Kunne ikke forbinde til serveren"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Blev smidt af serveren!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Held"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Forsvar:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "M.Angreb:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "M.Forsvar:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% præcission:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Undgå angreb."
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Kritisk sår"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Angreb %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Angreb %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monster rammer spiller"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Vis denne hjælpebesked."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Inviter en spiller med i din gruppe"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/invite > Forlad den gruppe du er med i"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Spark en spiller ud a din gruppe"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Kommand: /invite <spiller>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Denne kommando inviterer <spiller> til din gruppe."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Kommando: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Denne kommando får dig til at forlade din gruppe"
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Der opstod en fejl. Guilden kunne ikke oprettes"
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Ukendt invitations-svar fra %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Opret en guild"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Opret en guild"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Niveau: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Maks. level"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Opret en guild"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Oprettede en ny guild"
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Oprettede en ny guild"
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s er nu medlem af din gruppe."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Ukendt invitations-svar fra %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Du har foradt gruppen."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s har forladt gruppen."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s er nu medlem af din gruppe."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Inviter en spiller med i din gruppe"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/invite > Forlad den gruppe du er med i"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Spark en spiller ud a din gruppe"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Vis/ret hvordan gruppen deler fundne tin"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/item > Vis/ret hvordan partyet deler exp"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Denne kommando får dig til at forlade din gruppe"
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Kommand: /item <regel>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Denne kommando ændrer hvordan gruppen deler fundne ting."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"Hvis <regel> er \"1\", \"yes\", eller \"true\" så deler gruppen alle fundne "
+"ting, men hvis <regel> er \"0\", \"no\", eller \"false\" deler gruppen ikke."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Kommando: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "Denne kommando viser hvorvidt gruppen deler fundne ting."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Kommando: /exp <regel>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Denne kommando viser hvorvidt gruppen deler experience points."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"Hvis <regel> er \"1\", \"yes\", eller \"true\" så deler gruppen experience, "
+"men hvis <regel> er \"0\", \"no\", eller \"false\" deler gruppen ikke "
+"experience."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Kommando: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr "Denne kommando hvorvidt gruppen deler experience points."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Fra nu af deler partyet fundne ting."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Fra nu af deler partyet ikke fundne ting."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Deling af fundne ting kunne ikke slås til."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Fra nu af deler partyet fundne ting."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Fra nu af deler partyet experience points."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Fra nu af deler gruppen ikke experience points."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Deling af exp kunne ikke slås til."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Fra nu af deler partyet experience points."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Du kunne ikke bruge denne genstand."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Brugernavnet eksisterer ikke. log venligst ind igen."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Det nye password er for kort."
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Frameld"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Forkert brugernavn eller password"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Kontoen er slettet"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Adgang til serveren blev nægtet."
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "Du er blevet bandlyst permanent fra spillet. Kontakt en GM."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Du er blevet bandlyst fra spillet indtil %s. Kontakt venligst en GM i "
+"forummet."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Dette brugernavn er allerede taget."
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Kunne ikke sælge."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Opretter forbindelse til kort-serveren..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Kunne ikke oprette gruppe."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Du har nu oprettet gruppen."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s er allerede medlem af en gruppe."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s afviste din invitation."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s er nu medlem af din gruppe."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Ukendt invitations-svar fra %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Du har foradt gruppen."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s har forladt gruppen."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Et ukendt medlem forsøgte at sige: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s er ikke medlem af din gruppe!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Indsæt en mønt for at fortsætte."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Du er ikke død endnu. Du hviler dig bare."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Du er ikke mere."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Du er holdt op med at være til."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Du er udløbet og er gået hen for at møde din skaber."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Du er en hård nød at knække, men desværre død."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Du siver langtsomt ud af din krop, du kan nu endelig slappe af."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+"Hvis det ikke var fordi du var så animeret, kunne du sikker imponere Chuck "
+"Norris."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Din tid er ovre."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Drik noget syre."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Du har stillet træskoene."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr "Du har spist af dødens pølse for den sidste gang."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Du er en forhenværende spiller."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Du er tabt bag en vogn."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Besked"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:337
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Du samlede op "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Du får %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Handel fejlede!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Emote fejlede!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Sæt dig fejlede!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Det lykkedes ikke at starte en chat."
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Kunne ikke tilslutte sig gruppen!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Kan ikke råbe!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Du er ikke nået til det rette Niveau endnu!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Utilstrækkelig HP!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Utilstrækkelig SP!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Du har ingen memorandaer!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Det kan du ikke gøre lige nu!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Det ser ud til at du ikke har nok penge... :-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Du kan ikke bruge denne færdighed med dette slags våben!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Du har behov for en rød krystal mere"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Du har behov for en blå krystal mere"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Du har for meget på dig, til at kunne gøre dette"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Hmm? Hvad er det?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Warp mislykkede..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Kunne ikke stjæle noget som helst..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Giften havde ingen effekt..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Du kan ikke handle. Handle partneren er for langt væk."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Du kan ikke handle. Karakteren findes ikke."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Handlen blev annulleret af en ukendt grund."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Byttehandel: %s og dig."
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Byttehandel med %s blev afbrudt."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "En besked om at afbryde byttehandlen blev ikke opfattet."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Fejlede i at tilføje genstand. Handels partneren bære på for meget."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+"Fejlede i at tilføje genstand. Handels partneren har ikke flere frie pladser."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Fejlede i at tilføje genstand af en ukendt grund."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore||Ignorer %s fuldstændigt@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Angreb %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Forsvar %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Ukendt genstand"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "unavngivet"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Partikeldetaljer"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Omgivende FX"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Shortcut %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Spiller rammer monster"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Navn: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "MiniKort"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Gem/ chat i en lokal fil"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Kommando: /record <filnamn>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Denne kommando starter med at \"optage\" chat-loggen. Den gemmer en kopi "
+#~ "i <filnavn>"
+
+#~ msgid "Command: /record"
+#~ msgstr "Kommando: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Denne kommando stopper med at optage chatten."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Fremmøde skrives til loggen"
+
+#~ msgid "Finishing recording."
+#~ msgstr "Stop med at optage chat"
+
+#~ msgid "Not currently recording."
+#~ msgstr "Du er ikke igang med at optage"
+
+#~ msgid "Already recording."
+#~ msgstr "Du er allerede igang med at optage"
+
+#~ msgid "Starting to record..."
+#~ msgstr "Start optagelse"
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Fejl. Klienten kan ikke optage chat."
+
+#~ msgid "Recording..."
+#~ msgstr "Optager..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Stop optagelse"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Gå hen hvor musen peger"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Penge: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Job:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Niveau: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Du har nu oprettet gruppen."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Beskeden blev ikke læst. Modtageren ignorerer den."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Ønsket konfigurationsfil"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Ønsket konfigurationsfil"
+
+#~ msgid "Sound"
+#~ msgstr "Lyd"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Adgang nægtet"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Der opstod en ukendt fejl da du valgte karakter"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Serveren understøtter ikke denne type invitationer endnu."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s har inviteret med i sin gruppe"
+
+#~ msgid "Willpower:"
+#~ msgstr "Viljestyrke:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Serveren er fuld"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Handler med %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Hvisk"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Bliv ven med %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Se bort fra"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore||Ignorer %s fuldstændigt@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Inviter %s med i din guild@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Inviter %s med i din gruppe@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Du kunne ikke sparke denne bruger af kanalen"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Tal til %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Spark monstret ud@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Saml op"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Du kan ikke sende en tom chat-besked"
+
+#~ msgid "Text Shadow"
+#~ msgstr "Skygger"
+
+#~ msgid "Text Outline"
+#~ msgstr "Kontur"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Du har ikke penge nok"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Du har udrustet dig"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Bruger"
+
+#~ msgid "Whisper"
+#~ msgstr "Hvisk"
+
+#~ msgid "Is"
+#~ msgstr "Er"
+
+#~ msgid "Server"
+#~ msgstr "Server"
+
+#~ msgid "Logger"
+#~ msgstr "Logger"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Ukendt genstand"
+
+#~ msgid "Hats"
+#~ msgstr "Hatte"
+
+#~ msgid "Usables"
+#~ msgstr "Forbrugsvarer"
+
+#~ msgid "Shirts"
+#~ msgstr "Trøjer"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Ethåndsvåben"
+
+#~ msgid "Pants"
+#~ msgstr "Bukser"
+
+#~ msgid "Shoes"
+#~ msgstr "Sko"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Ethåndsvåben"
+
+#~ msgid "Shields"
+#~ msgstr "Skjolde"
+
+#~ msgid "Rings"
+#~ msgstr "Ringe"
+
+#~ msgid "Necklaces"
+#~ msgstr "Halskæder"
+
+#~ msgid "Arms"
+#~ msgstr "Våben"
+
+#~ msgid "Ammo"
+#~ msgstr "Ammunition"
+
+#~ msgid "HP Bar"
+#~ msgstr "HP tabel"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "HP tabel 3/4 fuld"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "HP tabel 1/2 fuld"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "HP tabel 1/4 fuld"
+
+#~ msgid "no"
+#~ msgstr "nej"
+
+#~ msgid "Buddy"
+#~ msgstr "Ven"
+
+#~ msgid "Buddy List"
+#~ msgstr "Venner"
+
+#~ msgid "Description: %s"
+#~ msgstr "Beskrivelse: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effekt: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Forrige"
+
+#~ msgid "New"
+#~ msgstr "Opret"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Jobniveau: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Til stede: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Forlad guild"
+
+#~ msgid "Ok"
+#~ msgstr "O.K."
+
+#~ msgid "Recent:"
+#~ msgstr "Seneste:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Kast test-formular 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Kast test-formular 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Kast test-formular 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Tohåndsvåben"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Hold op med at bruge@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Tag på@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Smid@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Opdel@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Gem på lager@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Vælg server"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Fejlede i at skifte til "
+
+#~ msgid "windowed"
+#~ msgstr "som vindue"
+
+#~ msgid "fullscreen"
+#~ msgstr "fuld skærm"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Mystisk færdighed."
+
+#~ msgid "Weapons"
+#~ msgstr "Våben"
+
+#~ msgid "Crafts"
+#~ msgstr "Håndværk"
+
+#~ msgid "Stats"
+#~ msgstr "Egenskaber"
+
+#~ msgid "Total"
+#~ msgstr "Total"
+
+#~ msgid "Cost"
+#~ msgstr "Pris"
+
+#~ msgid "Attack:"
+#~ msgstr "Angreb:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Refleks:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Tilgode Status Points: %d"
+
+#~ msgid "curl error "
+#~ msgstr "curl fejl "
+
+#~ msgid " host: "
+#~ msgstr " host: "
+
+#~ msgid "Buddys"
+#~ msgstr "Venner"
+
+#~ msgid "Party Window"
+#~ msgstr "Party-vindue"
+
+#~ msgid "Unarmed"
+#~ msgstr "Ubevæbnet"
+
+#~ msgid "Knife"
+#~ msgstr "Kniv"
+
+#~ msgid "Sword"
+#~ msgstr "Sværd"
+
+#~ msgid "Staff"
+#~ msgstr "Stav"
+
+#~ msgid "Whip"
+#~ msgstr "Pisk"
+
+#~ msgid "Bow"
+#~ msgstr "Bue"
+
+#~ msgid "Shooting"
+#~ msgstr "Missil-våben"
+
+#~ msgid "Mace"
+#~ msgstr "Kølle"
+
+#~ msgid "Axe"
+#~ msgstr "Økse"
+
+#~ msgid "Craft"
+#~ msgstr "Håndværk"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Ukendt evne"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " kan ikke laves, men det findes ikke! Lukker."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Kunne ikke definere "
+
+#~ msgid " video mode: "
+#~ msgstr " skærm opsætning: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Opretter forbindelse til karakter-serveren..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Opretter forbindelse til bruger-serveren..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Samme som /create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Kommando: /new <gruppe>"
+
+#~ msgid "a"
+#~ msgstr "en/et"
+
+#~ msgid "Unnamed"
+#~ msgstr "Unavngivet"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Følsomhed på mus"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Acceleration på mus"
+
+#~ msgid "Unable to load selection.png"
+#~ msgstr "Kan ikke loade valgte-billede.png"
+
+#~ msgid "Emote"
+#~ msgstr "Emote"
+
+#~ msgid "inc"
+#~ msgstr "inc"
+
+#~ msgid " -D --default : Bypass the login process with default settings"
+#~ msgstr ""
+#~ " -D --default : Overskriv login processen med normale indstillinger"
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 000000000..960d37839
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,6558 @@
+# German translation of The Mana World.
+# Copyright (C) 2007-2009 The Mana World Development Team
+# Copyright (C) 2010 The Mana Development Team
+# This file is distributed under the same license as the The Mana World package.
+#
+# Matthias Hartmann <hartmann.matthias@gmail.com>, 2007.
+# Jonathan Raphael Joachim Kolberg, 2009, 2010.
+# seeseekey <seeseekey@googlemail.com>, 2009.
+# Andrej, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: The Mana World 0.1.0\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-01-02 15:26+0000\n"
+"Last-Translator: Jonathan Raphael Joachim Kolberg\n"
+"Language-Team: Deutsch <kde-i18n-de@kde.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2009-06-02 17:48+0000\n"
+"X-Generator: Lokalize 1.0\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Einstellungen"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Verbinde mit [Benutzerdatenserver]..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Anmelden"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Spielfigur auswählen"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Verbinde mit [Charakterserver]..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Wechsle den Server"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Fehler"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+msgid "Password Change"
+msgstr "Passwort ändern:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr "Passwort erfolgreich geändert!"
+
+#: src/client.cpp:1092
+msgid "Email Change"
+msgstr "E-Mail ändern"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Mitglied wurde erfolgreich Befördert."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Abmelden"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr "Leb wohl und komme jeder Zeit wieder..."
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Ungültiger Updateserver: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Fehler beim Erstellen des Verzeichnisses für Updates!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Unbekannter Befehl."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Hilfe --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > diese Hilfe anzeigen"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Zeige den Namen der aktuellen Karte"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Zeige Anzahl der angemeldeten Spieler"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Erzähle etwas über Dich"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Löscht den Inhalt dieses Fensters"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Sende eine private Nachricht an einen Benutzer"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Ersatz für msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Ersatz für msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+"/query > Öffnet einen Tab für private Nachrichten mit einem anderen Benutzer"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Ersatz für query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Schließe einen privaten Tab"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+msgid "/desregard > Disregard a player"
+msgstr ""
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Zeige alle öffentlichen Kanäle"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Trete einem Kanal bei oder erstelle einen neuen Kanal"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Erstelle eine neue Party"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Erstelle eine neue Party"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Lade einen Benutzer zu deiner Party ein"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Entscheide, ob <return> den Chat-Dialog schließt"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Liste anwesender Spieler (wird im Chat-log aufgezeichnet, falls "
+"das Log aktiviert ist)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Globale Ansage (Nur von GMs nutzbar)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Schließe einen privaten Tab"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Sende eine private Nachricht an einen Benutzer"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Für mehr Informationen, gib /help <Befehl> ein."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Befehl: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Dieser Befehl zeigt alle möglichen Befehle an"
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Befehl: /help <Befehl>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Dieser Befehl zeigt die Hilfe für <Befehl>."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Befehl: /announce <Nachricht>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** Nur für GMs verfügbar ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"Dieser Befehl versendet die Nachricht <Nachricht> an alle Spieler die gerade "
+"online sind."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Befehl: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Dieser Befehl bereinigt den Chatlog des vorherigen Chats."
+
+#: src/commandhandler.cpp:379
+msgid "Command: /ignore <player>"
+msgstr "Befehl: /item <Wert>"
+
+#: src/commandhandler.cpp:380
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Dieser Befehl zeigt die Anzahl der Spieler an, die gerade online sind."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Befehl: /join <Kanal>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Dieser Befehl lässt dich dem Kanal <Kanal> beitreten."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Falls Kanal <Kanal> nicht existiert, wird er erstellt."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Befehl: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Dieser Befehl zeigt eine liste aller Kanäle an."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Befehl: /me <Nachricht>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Dieser Befehl zeigt eine Aktion <Nachricht> an."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Befehl: /msg <Name> <Nachricht>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Befehl: /whisper <Name> <Nachricht>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Befehl: /w <Name> <Nachricht>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Dieser Befehl sendet den Text <Nachricht> an den Spieler <Name>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Wenn im Namen <Name> Leerzeichen vorkommen, setze ihn in Anführungszeichen "
+"(\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Befehl: /query <Name>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Befehl: /q <Name>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Dieser Befehl erstellt einen neuen Tab für private Nachrichten zwischen Dir "
+"und Spieler <Name>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Befehl: /w <Name> <Nachricht>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Befehl: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Dieser Befehl setzt das Theme auf <Thema>."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Befehl: /create <Party-Name>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Dieser Befehl erstellt eine neue Party mit dem Namen <Party-Name>"
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Befehl: /create <Party-Name>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Dieser Befehl erstellt eine neue Party mit dem Namen <Party-Name>"
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Befehl: /party <Name>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Dieser Befehl lädt Spieler <Name> zu einer Party mit Dir ein."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Befehl: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Dieser Befehl erstellt eine Liste mit allen Spielern in Hörreichweite und "
+"sendet sie entweder an das Chatlog, falls aktiviert, oder zeigt sie im "
+"Chatfenster an."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Befehl: /toggle <Status>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Mit diesem Befehl kannst Du entscheiden, ob die Chatzeile schließt, sobald "
+"eine Nachricht gesendet wurde, oder erst nachdem die Enter-Taste erneut "
+"gedrückt wurde."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<Status> \"1\",\"yes\",\"true\" aktiviert das Schließen durch Enter, \"0\","
+"\"no\",\"false\" deaktiviert es."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Befehl: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Dieser Befehl zeigt, wann sich die Chatzeile schließt."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Befehl: /item <Wert>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Befehl: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Dieser Befehl zeigt den Namen der aktuellen Karte an."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Befehl: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Dieser Befehl zeigt die Anzahl der Spieler an, die gerade online sind."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Gib /help ein, um eine Liste der Befehle zu erhalten."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Kann keine leeren Nachrichten versenden!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Kann keinen tab für Spieler \"%s\" erstellen! Entweder existiert bereits "
+"einer, oder der Spieler bist du."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Erbitte Erlaubnis, Kanal %s betreten zu dürfen."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Name der Party fehlt."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Name der Party fehlt."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Enter-Taste schließt Chatzeile."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Nachricht schließt Chatzeile."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Jetzt schließt Enter die Chatzeile."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Jetzt schließt jede Nachricht die Chatzeile."
+
+#: src/commandhandler.cpp:700
+msgid "friend"
+msgstr "Freund"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Unbeachtet"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutral"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "%s ist bereits hier"
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Party erfolgreich erstellt."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr ""
+"Nachricht konnte nicht gesendet werden, sie wurde vom Spieler ignoriert."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr "Spieler wurde nicht ignoriert!"
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr "Spieler wird nicht länger ignoriert!"
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr ""
+"Nachricht konnte nicht gesendet werden, sie wurde vom Spieler ignoriert."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "%s ist bereits hier"
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Party erfolgreich erstellt."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr ""
+"Nachricht konnte nicht gesendet werden, sie wurde vom Spieler ignoriert."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Gültige Optionen für /%s sind \"yes\",\"no\",\"true\",\"false\",\"1\",\"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Öffentlich"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Bildschirmfoto wurde nach ~/ gespeichert."
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Bildschirmfoto konnte nicht gespeichert werden!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr ""
+"Die Verbindung zum Server wurde getrennt, das Programm wird jetzt beendet"
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Netzwerkfehler"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignoriere eingehende Handelsanfragen"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Akzeptiere eingehende Handelsanfragen"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Karte konnte nicht geladen werden"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Fehler beim Laden von %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Party (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Gilden"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Gefühlsfenster"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Name"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Angriff"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Sprechen"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Laufe Hoch"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Zurücksetzten"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Kaufen"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Preis: %s / Gesamt: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr "+"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr "-"
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Beenden"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Max"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Geschäft"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Verkaufen"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "E-MailAdresse ändern"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Account: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr "Gib die neue E-Mailadresse zweimal ein:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Die neue E-Mailadresse muss aus mindestens %d Zeichen bestehen."
+
+#: src/gui/changeemaildialog.cpp:136
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Die neue E-Mailadresse muss kürzer als %d Zeichen sein."
+
+#: src/gui/changeemaildialog.cpp:143
+msgid "The email address entries mismatch."
+msgstr "Die neuen E-Mailadresse stimmen nicht überein."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Passwort ändern"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Passwort:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr "Gib dein neues Passwort zweimal ein:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Das neue Passwort muss aus mindestens %d Zeichen bestehen."
+
+#: src/gui/changepassworddialog.cpp:124
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Das neue Passwort muss kürzer als %d Zeichen sein."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr "Die neues Passwörter stimmen nicht überein."
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Charakter erstellen"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Name:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr "Haarfarbe:"
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr "Frisur:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Erstellen"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Männlich"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Weiblich"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Bitte verteile %d Punkte"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Dein Name muss aus mindestens 4 Zeichen bestehen."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Spielfigurattribute OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Bitte entferne %d Punkte"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Bestätige Charakter-Löschung"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Bist Du sicher, dass du diesen Charakter löschen möchtest?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Account- und Charakterverwaltung"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr "Login wechseln"
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Abmelden"
+
+#: src/gui/charselectdialog.cpp:155
+msgid "Change Email"
+msgstr "E-Mailadresse ändern"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Löschen"
+
+#: src/gui/charselectdialog.cpp:425
+msgid "Choose"
+msgstr "Wähle"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+msgid "default"
+msgstr "Standard"
+
+#: src/gui/chat.cpp:92
+#, fuzzy
+msgid "black"
+msgstr "Glück"
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Freund"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Grün: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Blau: "
+
+#: src/gui/chat.cpp:96
+#, fuzzy
+msgid "gold"
+msgstr "Gilde"
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "Niedrig"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Verknüpfung"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+#, fuzzy
+msgid "grey"
+msgstr "Ignoriere"
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Bogen"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Regenbogen"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Regenbogen"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Regenbogen"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr "Anwesend: %s ;%d Spieler sind anwesend."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Flüsternd zu %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Ja"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Nein"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignoriert"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Lautstärke der Musik: "
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Karte: "
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Übersichtskarte"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, c-format
+msgid "Particle count: %d"
+msgstr "Partikelzählung: %d"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Spielfigurattribute OK"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Spieler trifft Monster"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Laufe nach Links"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Spieler anvisieren"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Spieler anvisieren"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Spieler anvisieren"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Spieler anvisieren"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Benutzerdefinierter Zeiger"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "Ok"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Ausrüstung"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Ablegen"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Hilfe"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Schließen"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventar"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Lager"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Plätze:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Ausrüsten"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Benutzen"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+msgid "Drop..."
+msgstr "Wegwerfen"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Aufteilen"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Gewicht:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Einlagern"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Abholen"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Wegwerfen"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Alle"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Wähle aus, wie viele Gegenstände Du tauschen möchtest."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Wähle aus, wie viele Gegenstände Du wegwerfen möchtest."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Wähle aus, wie viele Gegenstände Du einlagern möchtest."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Wähle aus, wie viele Gegenstände Du wieder haben möchtest."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Wähle aus, wie viel Gegenstände Du aufteilen möchtest."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Unbekannter Gegenstand"
+
+#: src/gui/itempopup.cpp:145
+#, fuzzy
+msgid ", "
+msgstr "; "
+
+#: src/gui/itempopup.cpp:152
+#, c-format
+msgid "Weight: %s"
+msgstr "Gewicht: %s"
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Statusfenster"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Zurücksetzten"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Zurücksetzten"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Stufe: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Laufe nach Links"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Schließen"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Anmelden"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/login.cpp:92
+#, fuzzy
+msgid "Custom update host"
+msgstr "Updateserver: "
+
+#: src/gui/login.cpp:106
+msgid "Remember username"
+msgstr "Benutzername merken"
+
+#: src/gui/login.cpp:107
+#, fuzzy
+msgid "Update:"
+msgstr "Ungültiger Updateserver: "
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registrieren"
+
+#: src/gui/login.cpp:117
+msgid "Change Server"
+msgstr "Wechsle den Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Karte"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Warte auf den Server"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Weiter"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Absenden"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Waffenarm"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+"\n"
+"Weiter\n"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Nach:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Senden"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Es misslang den Brief zu senden oder er war ungültig."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Geld: %s"
+
+#: src/gui/outfitwindow.cpp:83
+msgid "Unequip first"
+msgstr "erstes ausziehen"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+msgid "@@trade|Trade@@"
+msgstr ""
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+msgid "@@attack|Attack@@"
+msgstr ""
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+msgid "@@whisper|Whisper@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+msgid "@@heal|Heal@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+msgid "@@friend|Befriend@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+msgid "@@disregard|Disregard@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+msgid "@@ignore|Ignore@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+msgid "@@erase|Erase@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+msgid "@@unignore|Unignore@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Ignoriere %s komplett@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Lade einen Benutzer zu deiner Party ein"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+msgid "@@kick party|Kick from party@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+msgid "@@guild-kick|Kick from guild@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Lade einen Benutzer zu deiner Party ein"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+msgid "@@undress|Undress@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+msgid "@@sell|Sell@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:226
+msgid "@@talk|Talk@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:240
+msgid "@@admin-kick|Kick@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "Füge Namen zu Chat hinzu"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+msgid "@@pickup|Pick up@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "Zu Chat hinzufügen"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+msgid "@@edit spell|Edit spell@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Hervorgehobener Tab"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Hervorgehobener Tab"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Ändern"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Einlagern"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Einlagern"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Einlagern"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Abholen"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Abholen"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Abholen"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+msgid "Add to chat"
+msgstr "Zu Chat hinzufügen"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Server wechseln"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Spielfigur wechseln"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Bestätigen:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "eMail:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Der Nutzername muss aus mindestens %d Zeichen bestehen."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Der Nutzername muss kürzer als %d Zeichen sein."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Das Passwort muss aus mindestens %d Zeichen bestehen."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Das Passwort muss kürzer als %d Zeichen sein."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Passwörter stimmen nicht überein."
+
+#: src/gui/serverdialog.cpp:207
+msgid "Choose Your Server"
+msgstr "Wähle deinen Server"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+msgid "Connect"
+msgstr "Verbinde..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Benutzerdefinierter Zeiger"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Bitte die Adresse und den Port eines Servers eingeben."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr "Lade Serverliste herunter...%2.2f%%"
+
+#: src/gui/serverdialog.cpp:488
+msgid "Waiting for server..."
+msgstr "Warte auf den Server"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr "Download wird vorbereitet"
+
+#: src/gui/serverdialog.cpp:496
+#, fuzzy
+msgid "Error retreiving server list!"
+msgstr "Fehler beim empfangen der Serverliste: %s\n"
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Joystick aktivieren"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Joystick aktivieren"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr "Lade Musik herunter"
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Lautstärke der Klangeffekte"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Lautstärke der Musik"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Kein Text"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+"Der Client muss neugestartet werden, wenn die neue Musik heruntergeladen "
+"werden soll"
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr "Soundengine"
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Kauf fehlgeschlagen."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Kauf fehlgeschlagen."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Geschlecht"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "So wird die Farbe aussehen"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Farben"
+
+#: src/gui/setup_colors.cpp:72
+msgid "Type:"
+msgstr "Typ: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statisch"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulsierend"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Regenbogen"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Spektrum"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+msgid "Delay:"
+msgstr "Verzögerung: "
+
+#: src/gui/setup_colors.cpp:109
+msgid "Red:"
+msgstr "Rot: "
+
+#: src/gui/setup_colors.cpp:124
+msgid "Green:"
+msgstr "Grün: "
+
+#: src/gui/setup_colors.cpp:139
+msgid "Blue:"
+msgstr "Blau: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Anwenden"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Fenster zurücksetzen"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Knopf drücken, um die Kalibrierung zu starten"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Kalibrieren"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Joystick aktivieren"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Stopp"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Kreise den Steuerknüppel"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Tastatur"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Zuordnen"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Zuordnen"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Standard"
+
+#: src/gui/setup_keyboard.cpp:130
+#, fuzzy
+msgid "Key Conflict(s) Detected."
+msgstr "Tastenkonflikte entdeckt."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Hervorgehoben"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Eigener Name"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Joystick aktivieren"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Hervorgehoben"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Handeln erlauben/verbieten"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Kauf fehlgeschlagen."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Kauf fehlgeschlagen."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Joystick aktivieren"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "als Partikeleffekt"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Beziehung"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutral"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Freund"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Unbeachtet"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignoriert"
+
+#: src/gui/setup_players.cpp:69
+#, fuzzy
+msgid "Erased"
+msgstr "Senden"
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Handeln erlauben"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Flüstern erlauben"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Alle privaten Nachrichten in Tabs öffnen"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Geschlecht"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Spieler"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Wenn ignorierend:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Geschlecht"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Eigener Name"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Spieler anvisieren"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Partikelzählung: %d"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Hilfe"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "E-Mail ändern"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Starte das Spiel neu um die Änderungen zu übernehmen."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Winzig"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Klein"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Mittel"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Groß"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Kein Text"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Text"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Blasen, keine Namen"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Blasen mit Namen"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "Aus"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "Niedrig"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "Hoch"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "Mittel"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "Maximal"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Vollbild"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Beziehung"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Benutzerdefinierter Zeiger"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Sichtbare Namen"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Partikeleffekte"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Benachrichtigung beim Aufheben"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "im Chatfenster"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "als Partikeleffekt"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+#, fuzzy
+msgid "Show job"
+msgstr "Zeigen"
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Joystick aktivieren"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Hintergrund"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS-Limit:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "FPS-Limit:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Chat über Spielern"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "GUI-Transparenz"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Hintergrundeffekte"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Partikeldetail"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Schriftgröße"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Nein"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "Auflösung und Wiederherstellung der alten Auflösung schlug fehl!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "Auflösung und Wiederherstellung der alten Auflösung schlug fehl!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Wechsle zum Vollbildmodus"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Änderungen treten erst nach einem Neustart des Programms in Kraft."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Ändere OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+"Änderungen an OpenGL werden erst nach einem Neustart der Anwendung "
+"übernommen."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Auflösung geändert"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+"Einige Fenster können verschoben werden um sich an die geänderte Auflösung "
+"anzupassen."
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Partikeleffekteinstellungen geändert."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Änderung werden beim nächsten Kartenwechsel übernommen."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Hinzufügen"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+#, fuzzy
+msgid "Announce"
+msgstr "ankündigen"
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Erbitte einen Handel"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s möchte mit dir handeln, stimmst Du zu?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Fertigkeiten"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Erhöhen"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Fähigkeitspunkte: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Fähigkeitspunkte: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Fertigkeiten"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Stufe: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Stufe: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Gilde"
+
+#: src/gui/socialwindow.cpp:143
+#, fuzzy, c-format
+msgid "Invited user %s to guild %s."
+msgstr "Spieler %s einladen"
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Gilde %s wurde aufgelöst."
+
+#: src/gui/socialwindow.cpp:184
+#, fuzzy
+msgid "Member Invite to Guild"
+msgstr "Spieler einladen"
+
+#: src/gui/socialwindow.cpp:185
+#, fuzzy, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr "Wen möchtest du einladen?"
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Gilde erstellen"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Bist Du sicher, dass Du das Spiel verlassen möchtest?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Party"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "Spieler %s einladen"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "Spieler einladen"
+
+#: src/gui/socialwindow.cpp:282
+#, fuzzy, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr "Wen möchtest du einladen?"
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Bist Du sicher, dass Du das Spiel verlassen möchtest?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Gilde erstellen"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Charakter erstellen"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+#, fuzzy
+msgid "Social"
+msgstr "Special"
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "einladen"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Stufe: %d"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Partyeinladung von %s angenommen."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Partyeinladung von %s abgelehnt."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Partyeinladung von %s angenommen."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Partyeinladung von %s abgelehnt."
+
+#: src/gui/socialwindow.cpp:1056
+#, c-format
+msgid "Creating guild called %s."
+msgstr "Erstelle der Gilde %s."
+
+#: src/gui/socialwindow.cpp:1079
+#, fuzzy, c-format
+msgid "Creating party called %s."
+msgstr "Erstelle der Gilde %s."
+
+#: src/gui/socialwindow.cpp:1093
+msgid "Guild Name"
+msgstr "Gildenname"
+
+#: src/gui/socialwindow.cpp:1094
+msgid "Choose your guild's name."
+msgstr "Wähle den Namen deiner Gilde"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Anfrage für eine Party erhalten, aber du bist bereits in einer Party."
+
+#: src/gui/socialwindow.cpp:1114
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s hat Dich eingeladen, seiner Gilde %s beizutreten."
+
+#: src/gui/socialwindow.cpp:1120
+msgid "Accept Guild Invite"
+msgstr "Nehme Gildeneinladung an"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Anfrage für eine Party erhalten, aber du bist bereits in einer Party."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s hat dich in seine Party eingeladen."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s hat dich eingeladen, an der Party %s teilzunehmen."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s hat dich in seine Party eingeladen."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s hat dich eingeladen, an der Party %s teilzunehmen."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Nehme Partyeinladung an"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Party"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Wähle den Namen deiner Gilde"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr "Special"
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Stufe: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Geld: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Beruf: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Beruf:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Spielfigurattribute OK"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Stufe: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Fähigkeitspunkte: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Laufe nach Links"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Handeln erlauben"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "NPC anvisieren"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Öffentlich"
+
+#: src/gui/textcommandeditor.cpp:117
+msgid "Life Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:118
+msgid "War Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Befehl: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+msgid "magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr "andere"
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Befehl: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+#, fuzzy
+msgid "Mana:"
+msgstr "Mana"
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Spieler anvisieren"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Max Level"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Geschlecht"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Handel vorschlagen"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Bestätigt. Warten..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Handel zustimmen"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Zugestimmt. Warten..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Handel: Du"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Handeln"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Du erhältst %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Du gibst:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Ändern"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Gegenstand konnte nicht hinzugefügt werden. Du kannst keinen weiteren dieser "
+"Gegenstände hinzufügen."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Du hast nicht genügend Geld."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Name : %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Aktualisiere..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Verbinde..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Los!"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Update wurde nicht erfolgreich abgeschlossen."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Es wird dringend empfohlen,"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 es später erneut zu versuchen."
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Fertig"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Aktionen"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Freund"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Unbeachtet"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignoriere %s"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "Senden"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Namen anderer Spieler"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Eigener Name"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Namen von GM"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monster"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monster trifft Spieler"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Party"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Gildenname"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Partikeleffekte"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "aufgehobene Gegenstände"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Anzeige der Erfahrungspunkte"
+
+#: src/gui/userpalette.cpp:127
+msgid "Player Hits Monster"
+msgstr "Spieler trifft Monster"
+
+#: src/gui/userpalette.cpp:128
+msgid "Monster Hits Player"
+msgstr "Monster trifft Spieler"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Namen anderer Spieler"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Kritischer Treffer"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Spieler trifft Monster"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Spieler trifft Monster"
+
+#: src/gui/userpalette.cpp:137
+#, fuzzy
+msgid "Local Player Miss"
+msgstr "Spielerliste sichern"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Verfehlt"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Hervorgehobener Tab"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Hervorgehoben"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Hervorgehobener Tab"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monster trifft Spieler"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+#, fuzzy
+msgid "Update"
+msgstr "Ungültiger Updateserver: "
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Zeigt eine Liste der Spieler im aktuellen Kanal"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Setze das Thema des aktuellen Kanals"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Verlasse einen Kanal"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Ernenne einen Spieler zum Kanalmoderator"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Werfe einen Spieler aus dem Kanal"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Befehl: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Dieser Befehl zeigt eine Liste der Spieler im aktuellen Kanal."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Befehl: /topic <Thema>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Dieser Befehl setzt das Theme auf <Thema>."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Befehl: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Mit diesem Befehl verlässt Du den aktuellen Kanal"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Wenn Du die letzte Person im Kanal bist, wird dieser gelöscht."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Befehl: /op <Name>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Dieser Befehl macht Spieler <Name> zu einem Moderator des Kanals"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Moderatoren können andere Spieler aus dem Kanal werfen oder ihnen ebenfalls "
+"Moderatorrechte verleihen."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Befehl: /kick <Name>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Diese Befehl wirft Spieler <Name> aus dem Kanal"
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Gib einen Spieler an, der Moderator werden soll!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Gib einen Spieler an, der aus dem Kanal geworfen werden soll"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Globale Ansage:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Globale Ansage von %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s flüstert: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Schließe einen privaten Tab"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Befehl: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Dieser Befehl schließt den aktuellen privaten Tab."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Befehl: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Dieser Befehl zeigt die Anzahl der Spieler an, die gerade online sind."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Dieser Befehl startet den Mitschnitt des Chats (Chatlog) in die Datei "
+"<Dateiname>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Gefühlsfenster"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Grinsen"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Tastenkürzel"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "OK auswählen"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Ändern"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Wähle deinen Server"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Laufe Hoch"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Laufe Runter"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Laufe nach Links"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Laufe nach Rechts"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Zielen & Angreifen"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Laufe nach Links"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Grinsen"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Angriff abbrechen"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Nächstes Ziel anvisieren"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "NPC anvisieren"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Spieler anvisieren"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Aufheben"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Fenster ausblenden"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Sitzen"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Bildschirmfoto"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Handeln erlauben/verbieten"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "E-MailAdresse ändern"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Kurztaste %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Kurztaste %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Hilfefenster"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Statusfenster"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Inventarfenster"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Ausrüstungsfenster"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Fertigkeitenfenster"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Kartenfenster"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Chatfenster"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Kurztastenfenster"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Einstellungen"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Debugfenster"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Fertigkeitenfenster"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Kurztasten für Gefühle"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Statusfenster"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Einstellungen"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Fenster ausblenden"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Statusfenster"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Befehl: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Gefühlsfenster"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Voriger Tab"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Nächster Tab"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Gefühlstaste %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Chat ein/aus"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Im Chat hochscrollen"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Im Chat runter scrollen"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Voriger Tab"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Nächster Tab"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Voriger Tab"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Nächster Tab"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "OK auswählen"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignoriere Eingabe 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignoriere Eingabe 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Laufe Runter"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Laufe nach Links"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Laufe nach Rechts"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Spielfigur wechseln"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Wechsle den Server"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Zielen & Angreifen"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Passwort ändern"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "E-MailAdresse ändern"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Handeln erlauben/verbieten"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Bitte beheben, oder es wird zu merkwürdigem Verhalten im Spiel kommen."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Kann Gegenstand nicht aufheben."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Du hast %s [@@%d|%s@@] aufgehoben."
+msgstr[1] "Du hast %s [@@%d|%s@@] aufgehoben."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Du erhältst %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Optionen:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : zu benutzende Konfigurationsdatei"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : zu benutzende Konfigurationsdatei"
+
+#: src/main.cpp:52
+msgid " -v --version : Display the version"
+msgstr " -v --version : Die Version des Spieles anzeigen"
+
+#: src/main.cpp:53
+msgid " -h --help : Display this help"
+msgstr " - --help : Zeigt diesen Hilfstext an"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : zu benutzende Konfigurationsdatei"
+
+#: src/main.cpp:55
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Mit angegebenem Benutzernamen anmelden"
+
+#: src/main.cpp:56
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Angegebenes Passwort benutzen"
+
+#: src/main.cpp:57
+msgid " -c --character : Login with this character"
+msgstr " -c --charakter : Mit angegebenem Spieler anmelden"
+
+#: src/main.cpp:58
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Name oder IP-Adresse des Loginservers"
+
+#: src/main.cpp:59
+msgid " -p --port : Login server port"
+msgstr " -p --port : Port des Loginservers"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Benutze angegebenen Updateserver"
+
+#: src/main.cpp:61
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Wähle zuletzt benutzten Server und Spieler aus"
+
+#: src/main.cpp:63
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Überspringe das Herunterladen von Updates"
+
+#: src/main.cpp:64
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+" -d --data : Datenverzeichnis, aus dem das Spiel geladen werden "
+"soll"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+" -S --home-dir : Verzeichnis, das als Heimatverzeichnis benutzt werden soll"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+" -S --home-dir : Verzeichnis, das als Heimatverzeichnis benutzt werden soll"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : OpenGL-Erweiterungen deaktivieren"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Stärke"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Stärke %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Beweglichkeit"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Beweglichkeit %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Ausdauer"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Ausdauer %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Gesundheit"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Gesundheit %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligenz"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligenz %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+msgid "Willpower"
+msgstr "Willenskraft:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Willensstärke %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Ach ja: Du bist Tot."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+"Es tut uns Leid, Euch mitteilen zu müssen, dass Ihr im Kampfe gefallen seid."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Du bist nicht länger lebendig."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Die kalten Hände des Sensenmanns greifen nach Deiner Seele."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Game Over!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Nein, Kinder. Euer Charakter ist nicht tot. Er... ähm... ist zu einem "
+"besserem Ort gegangen."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Dein Plan, die Waffe deines Feindes mit Deinem Hals zu zerstören, war leider "
+"nicht ganz so genial, wie Du dachtest..."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Ich glaube, das war nicht so gut."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Möchtest du eine Auflistung Deiner Verletzungen?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Leider wurde niemals eine Spur von Dir gefunden..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Vernichtet."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Sieht aus, als würde Dein Kopf Dich anschauen."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+"Du hast schon wieder versagt. Spül Deine Überreste hinunter und hol Dir "
+"einen paar Neue."
+
+#: src/net/manaserv/beinghandler.cpp:336
+msgid "Press OK to respawn."
+msgstr "Drücke \"OK\" um neu anzufangen."
+
+#: src/net/manaserv/beinghandler.cpp:337
+msgid "You Died"
+msgstr "Du bist tot."
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+msgid "Not logged in."
+msgstr "nicht angemeldet"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr "Kein freier Slot."
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr "Ungültiger Name."
+
+#: src/net/manaserv/charhandler.cpp:153
+msgid "Character's name already exists."
+msgstr "Benutzername bereits vorhanden"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr "Ungültiger Haarstil."
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr "Ungültige Haarfarbe."
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr "Ungültiges Geschlecht."
+
+#: src/net/manaserv/charhandler.cpp:165
+msgid "Character's stats are too high."
+msgstr "Spielfigurattribute sind zu groß."
+
+#: src/net/manaserv/charhandler.cpp:168
+msgid "Character's stats are too low."
+msgstr "Spielfigurattribute sind zu klein"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+msgid "Unknown error."
+msgstr "Unbekannter Fehler"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Info"
+
+#: src/net/manaserv/charhandler.cpp:206
+msgid "Player deleted."
+msgstr "Spieler gelöscht"
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Wähle aus, wie viele Gegenstände Du tauschen möchtest."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Unbekannter Fehler"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Kein Server verfügbar"
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Thema: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+msgid "Players in this channel:"
+msgstr "Spieler im Kanal:"
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Error joining channel."
+msgstr "Fehler beim Betreten des Kanals."
+
+#: src/net/manaserv/chathandler.cpp:213
+msgid "Listing channels."
+msgstr "Liste Kanäle"
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, c-format
+msgid "%s entered the channel."
+msgstr "%s ist dem Kanal beigetreten."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Unbekannter Befehl."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Gilde erstellt."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Fehler beim Erstellen der Gilde."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Einladung gesendet."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Mitglied wurde erfolgreich befördert."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Beförderung des Mitglieds gescheitert."
+
+#: src/net/manaserv/loginhandler.cpp:89
+msgid "Wrong magic_token."
+msgstr "Fehlerhaftes Magiemerkmal"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+msgid "Already logged in."
+msgstr "Bereits angemeldet"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Account abgelaufen"
+
+#: src/net/manaserv/loginhandler.cpp:120
+msgid "New password incorrect."
+msgstr "Neues Passwort fehlerhaft"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+msgid "Old password incorrect."
+msgstr "Altes Passwort fehlerhaft"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Account nicht verbunden. Bitte melde Dich zuerst an."
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "New email address incorrect."
+msgstr "Neue E-Mailadresse ist fehlerhaft"
+
+#: src/net/manaserv/loginhandler.cpp:155
+msgid "Old email address incorrect."
+msgstr "Alte E-Mailadresse ist fehlerhaft"
+
+#: src/net/manaserv/loginhandler.cpp:163
+msgid "The new email address already exists."
+msgstr "Die neue E-Mailadresse ist bereits vorhanden."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+msgid "Client version is too old."
+msgstr "Die Version des Spiels ist zu alt"
+
+#: src/net/manaserv/loginhandler.cpp:273
+msgid "Wrong username or password."
+msgstr "Benutzername oder Passwort falsch"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Account abgelaufen"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+msgid "Wrong username, password or email address."
+msgstr "Benutzername, Passwort oder E-Mailadresse falsch"
+
+#: src/net/manaserv/loginhandler.cpp:313
+msgid "Username already exists."
+msgstr "Benutzername bereits vorhanden"
+
+#: src/net/manaserv/loginhandler.cpp:316
+msgid "Email address already exists."
+msgstr "E-Mailadresse bereits vorhanden"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Der Party beigetreten."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s ist der Party beigetreten."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, c-format
+msgid "%s rejected your invite."
+msgstr "%s hat Deine Einladung zurückgewiesen."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Akzeptiere eingehende Handelsanfragen."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignoriere eingehende Handelsanfragen."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s möchte mit dir handeln, stimmst Du zu?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Handele mit %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Handel abgebrochen."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Handel abgeschlossen."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Spieler konnte nicht aus dem Kanal geworfen werden!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Spieler aus dem Kanal geworfen!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Du hast nichts zu verkaufen."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Vielen Dank für den Einkauf."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Kauf fehlgeschlagen."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Vielen Dank für den Verkauf."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Verkauf fehlgeschlagen."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+msgid "Cannot use this ID."
+msgstr "Kann diese ID nicht benutzen"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Unbekannter Fehler"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+"Charakter konnte nicht erstellt werden. Wahrscheinlich ist der Name bereits "
+"vergeben."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Spieler gelöscht."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Spieler konnte nicht gelöscht werden."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Stärke:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agilität:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitalität:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligenz:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Geschicklichkeit:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Glück:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Nachricht konnte nicht gesendet werden, Spieler ist offline."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr ""
+"Nachricht konnte nicht gesendet werden, sie wurde vom Spieler ignoriert."
+
+#: src/net/tmwa/chathandler.cpp:333
+msgid "MVP player."
+msgstr "Spieler"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Spieler"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Kanäle werden nicht unterstützt!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr "Benutzer online: %d"
+
+#: src/net/tmwa/gamehandler.cpp:102
+msgid "Game"
+msgstr "Spiel"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Erbitte einen Handel"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Stärke %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Beweglichkeit %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Gesundheit %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligenz %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Ausdauer %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Glück %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+msgid "Authentication failed."
+msgstr "Authentifizierung fehlgeschlagen"
+
+#: src/net/tmwa/generalhandler.cpp:138
+msgid "No servers available."
+msgstr "Keine Server verfügbar"
+
+#: src/net/tmwa/generalhandler.cpp:142
+msgid "Someone else is trying to use this account."
+msgstr "Jemand anderes versucht diesen Account zu benutzen"
+
+#: src/net/tmwa/generalhandler.cpp:145
+msgid "This account is already logged in."
+msgstr "Dieser Account ist bereits angemeldet"
+
+#: src/net/tmwa/generalhandler.cpp:148
+msgid "Speed hack detected."
+msgstr "Geschwindigkeitsproblem festgestellt"
+
+#: src/net/tmwa/generalhandler.cpp:151
+msgid "Duplicated login."
+msgstr "Mehrfache Anmeldung"
+
+#: src/net/tmwa/generalhandler.cpp:154
+msgid "Unknown connection error."
+msgstr "Unbekannter Verbindungsfehler"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Verbindung zum Server unterbrochen!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Glück"
+
+#: src/net/tmwa/generalhandler.cpp:255
+msgid "Defense"
+msgstr "Verteidigung:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+msgid "M.Attack"
+msgstr "M.Angriff:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+msgid "M.Defense"
+msgstr "M.Verteidigung:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, c-format
+msgid "% Accuracy"
+msgstr "% Accuracy"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, c-format
+msgid "% Evade"
+msgstr "% Evade"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, c-format
+msgid "% Critical"
+msgstr "% Critical"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Angriff %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Angriff %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monster trifft Spieler"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Diese Hilfe anzeigen"
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Lade einen Spieler zu Deiner Party ein"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Verlasse die Party, in der Du Mitglied bist"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Werfe jemanden aus Deiner Party"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Befehl: /invite <Name>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Dieser Befehl lädt Spieler <Name> zu einer Party mit Dir ein."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Befehl: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Dieser Befehl lässt Dich die Party verlassen"
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Fehler beim Erstellen der Gilde."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Unbekannte Reaktion auf die Einladung von %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Gildenname"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Gildenname"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Stufe: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, fuzzy, c-format
+msgid "Online members: %d"
+msgstr "Benutzer online: %d"
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Max Level"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Gildenname"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Gilde erstellt."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Gilde erstellt."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+#, fuzzy
+msgid "User rejected guild invite."
+msgstr "%s hat Deine Einladung zurückgewiesen."
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s ist nun Mitglied Deiner Party."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Unbekannte Reaktion auf die Einladung von %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Du hast die Party verlassen."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s hat Deine Party verlassen."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s ist nun Mitglied Deiner Party."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Lade einen Spieler zu Deiner Party ein"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Verlasse die Party, in der Du Mitglied bist"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Werfe jemanden aus Deiner Party"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+"/item > Zeige oder ändere die Optionen zum Teilen der Gegenstände in der "
+"Party"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+"/exp > Zeige oder ändere die Optionen zum Teilen der Erfahrungspunkte in der "
+"Party"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Dieser Befehl lässt Dich die Party verlassen"
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Befehl: /item <Wert>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+"Dieser Befehl ändert die Einstellungen zum Teilen von Gegenständen in einer "
+"Party."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<Wert> darf enthalten: \"1\",\"yes\" oder \"true\" um das Teilen von "
+"Gegenständen zu erlauben, \"0\",\"no\" oder \"false\" um es zu verbieten."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Befehl: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+"Dieser Befehl zeigt an, ob Gegenstände in der Party geteilt werden, oder "
+"nicht."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Befehl: /exp <Wert>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Dieser Befehl ändert das Teilen der Erfahrungspunkte in einer Party."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"Gültige Werte für <Wert> sind: \"1\",\"yes\",\"true\" um das Teilen zu "
+"erlauben, \"0\",\"no\",\"false\" verbieten es."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Befehl: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+"Dieser Befehl zeigt an, ob das Teilen von Erfahrungspunkten in der Party "
+"aktiviert ist."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Teilen von Gegenständen aktiviert."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Teilen von Gegenständen deaktiviert."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Teilen von Gegenständen nicht möglich."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Teilen von Gegenständen aktiviert."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Teilen der Erfahrungspunkte aktiviert."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Teilen der Erfahrungspunkte deaktiviert."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Teilen der Erfahrungspunkte nicht möglich."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Teilen der Erfahrungspunkte aktiviert."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Gegenstand konnte nicht benutzt werden."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Kann Gegenstand nicht ausrüsten."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Account konnte nicht gefunden werden. Bitte melde dich erneut an."
+
+#: src/net/tmwa/loginhandler.cpp:96
+msgid "New password too short."
+msgstr "Das neue Passwort ist zu kurz"
+
+#: src/net/tmwa/loginhandler.cpp:161
+msgid "Unregistered ID."
+msgstr "Unbekannte ID"
+
+#: src/net/tmwa/loginhandler.cpp:164
+msgid "Wrong password."
+msgstr "Falsches Passwort"
+
+#: src/net/tmwa/loginhandler.cpp:167
+msgid "Account expired."
+msgstr "Account abgelaufen"
+
+#: src/net/tmwa/loginhandler.cpp:170
+msgid "Rejected from server."
+msgstr "Vom Server zurückgewiesen"
+
+#: src/net/tmwa/loginhandler.cpp:173
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Du wurdest permanent vom Spiel ausgeschlossen. Bitte wende Dich an das GM-"
+"Team."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Du wurdest zeitweise, bis %s vom Spiel ausgeschlossen.\n"
+"Bitte wende dich mittels des Forums an das GM-Team."
+
+#: src/net/tmwa/loginhandler.cpp:184
+msgid "This user name is already taken."
+msgstr "Dieser Spielername ist bereits vergeben"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+msgid "Unable to resolve host \""
+msgstr "Nicht möglich den host \" aufzulösen"
+
+#: src/net/tmwa/network.cpp:421
+msgid "Connection to server terminated. "
+msgstr "Verbindung mit Server abgebrochen. "
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Konnte Party nicht erstellen."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Party erfolgreich erstellt."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s ist bereits Mitglied einer Party."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s hat Deine Einladung zurückgewiesen."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s ist nun Mitglied Deiner Party."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Unbekannte Reaktion auf die Einladung von %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Du hast die Party verlassen."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s hat Deine Party verlassen."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Ein unbekanntes Mitglied hat versucht, \"%s\" zu sagen."
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s ist nicht in Deiner Party!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Gib eine Münze ein um weiter zuspielen."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Du bist nicht tot. Du erholst Dich bloß."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Du bist nicht mehr."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Du hast Dich entschieden, dem Irdischen zu entsagen."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Deine Zeit ist abgelaufen. Zeit, deinem Schöpfer gegenüberzutreten."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Du bist ein wenig steif."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Des Lebens beraubt ruhst Du in Frieden."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+"Wenn Du nicht so lebendig wärst, könntest Du die Gänseblümchen von unten "
+"sehen."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Deine Körperfunktionen sind nun Geschichte."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Du kriegst nichts mehr mit."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Jetzt passt Du in 'nen Eimer."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+"Du hast Deine sterbliche Hülle abgelegt, der Schleier legt sich über Dich "
+"und Du trittst dem Chor der blutenden Unsichtbaren bei."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Du warst einmal ein Spieler."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Du schmachtest nach den Fjorden."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Nachricht"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Du trägst mehr als die Hälfte Deiner Tragkraft. Du kannst Dich nicht mehr "
+"heilen."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Du trägst mehr als die Hälfte Deiner Tragkraft. Du kannst Dich nicht mehr "
+"heilen."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, c-format
+msgid "You picked up %s."
+msgstr "Du hast %s aufgehoben "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Du erhältst %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr "Kann Skill nicht erhöhen!"
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Rüste dich zuerst mit Pfeilen aus."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Handel fehlgeschlagen!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Gefühl fehlgeschlagen!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Sitzen fehlgeschlagen!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Chat-Erstellung fehlgeschlagen!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Kann der Gruppe nicht beitreten!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Kann nicht rufen!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Dein Level ist noch nicht hoch genug!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Nicht genug HP!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Nicht genug SP!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Keine Memos vorhanden!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Du kannst dies momentan nicht tun!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Es scheint, als bräuchtest Du mehr Geld... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Du kannst diese Fähigkeit nicht mit dieser Waffenart benutzen!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Du brauchst noch einen roten Edelstein!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Du brauchst noch einen blauen Edelstein!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Du schleppst zu viel herum, um das zu machen!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Huch? Was ist das?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Warp fehlgeschlagen..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Konnte nichts stehlen..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Das Gift hatte keine Wirkung..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Handel nicht möglich. Handelspartner ist zu weit weg."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Handel nicht möglich. Spieler existiert nicht."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Handel aus unbekanntem Grund abgebrochen"
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Handel: Du und %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Handel mit %s abgebrochen."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Übergangenes Handelsabbruchspaket."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+"Gegenstand konnte nicht hinzugefügt werden. Handelspartner ist überladen."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+"Gegenstand konnte nicht hinzugefügt werden. Handelspartner hat keinen freien "
+"Platz mehr."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Gegenstand konnte nicht hinzugefügt werden. Unbekannter Fehler."
+
+#: src/playerrelations.cpp:404
+msgid "Completely ignore"
+msgstr "@@ignore|Ignoriere %s komplett@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Angriff %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Verteidigung %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Unbekannter Gegenstand"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "unbenannt"
+
+#~ msgid "Particle detail: %s"
+#~ msgstr "Partikeldetails: %s"
+
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Hintergrundeffekte: %s"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Spieler trifft Monster"
+
+#~ msgid "Music: %s"
+#~ msgstr "Musik: %s"
+
+#~ msgid "Map: %s"
+#~ msgstr "Karte : %s"
+
+#~ msgid "Minimap: %s"
+#~ msgstr "Übersichtskarte: %s"
+
+#, fuzzy
+#~ msgid "Minimap: ?"
+#~ msgstr "Übersichtskarte: "
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Starte die Aufzeichnung des Chats in eine Datei"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Befehl: /record <Dateiname>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Dieser Befehl startet den Mitschnitt des Chats (Chatlog) in die Datei "
+#~ "<Dateiname>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Befehl: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Dieser Befehl beendet den Mitschnitt des Chats."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Anwesenheitsliste wurde ins Chatprotokol geschrieben."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Aufzeichnung abgeschlossen."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Es läuft keine Aufzeichnung."
+
+#~ msgid "Already recording."
+#~ msgstr "Es läuft bereits eine Aufzeichnung."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Starte Aufzeichnung..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Start der Aufzeichnung fehlgeschlagen."
+
+#~ msgid "Recording..."
+#~ msgstr "Aufzeichnung läuft..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Stoppe Aufzeichnung"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Finde Weg zum Mauszeiger"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Geld: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Job:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Stufe: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Party erfolgreich erstellt."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr ""
+#~ "Nachricht konnte nicht gesendet werden, sie wurde vom Spieler ignoriert."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : zu benutzende Konfigurationsdatei"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : zu benutzende Konfigurationsdatei"
+
+#~ msgid "Sound"
+#~ msgstr "Ton"
+
+#~ msgid "Access denied."
+#~ msgstr "Zugang verweigert"
+
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Unbekannter Fehler bei Auswahl des Charakters"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Einladungen auf diesem Weg werden im Moment nicht unterstützt."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s hat dich in seine Party eingeladen."
+
+#~ msgid "Willpower:"
+#~ msgstr "Willenskraft:"
+
+#~ msgid "Server is full."
+#~ msgstr "Server ist voll"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Handele mit %s"
+
+#~ msgid "Whisper %s"
+#~ msgstr "flüstere %s"
+
+#~ msgid "Befriend %s"
+#~ msgstr "Sei Freund von %s"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Unbeachtet"
+
+#~ msgid "Unignore %s"
+#~ msgstr "Ignoriere %s nicht mehr"
+
+#~ msgid "Completely ignore %s"
+#~ msgstr "Ignoriere %s komplett"
+
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "Lade %s in deine Gilde ein"
+
+#~ msgid "Invite %s to join your party"
+#~ msgstr "Lade %s in deine Party ein"
+
+#~ msgid "Talk to %s"
+#~ msgstr "Rede mit %s"
+
+#~ msgid "Kick monster"
+#~ msgstr "Monster töten"
+
+#~ msgid "Pick up %s"
+#~ msgstr "Hebe %s auf"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Kann keine leere Nachricht senden!"
+
+#, fuzzy
+#~ msgid "Target Monster"
+#~ msgstr "Nächstes Ziel anvisieren"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Kann Gegenstand nicht ablegen."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Textschatten"
+
+#~ msgid "Text Outline"
+#~ msgstr "Textaußenlinie"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Fortschrittsbalkenbeschriftungen"
+
+#~ msgid "Buttons"
+#~ msgstr "Buttons"
+
+#~ msgid "Disabled Buttons"
+#~ msgstr "Deaktivierte Buttons"
+
+#~ msgid "Tabs"
+#~ msgstr "Tabs"
+
+#~ msgid "Item Too Expensive"
+#~ msgstr "Gegenstand ist zu teuer"
+
+#~ msgid "Item Is Equipped"
+#~ msgstr "Gegenstand ist in Verwendung"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Spieler"
+
+#~ msgid "Whisper"
+#~ msgstr "geflüsterte Nachricht"
+
+#~ msgid "Is"
+#~ msgstr "Handlungen"
+
+#~ msgid "Server"
+#~ msgstr "Server"
+
+#~ msgid "Logger"
+#~ msgstr "Logger"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Unbekannter Gegenstand"
+
+#~ msgid "Generics"
+#~ msgstr "Allgemeiner Gegenstand"
+
+#~ msgid "Hats"
+#~ msgstr "Hüte"
+
+#~ msgid "Usables"
+#~ msgstr "Benutzbare Gegenstände"
+
+#~ msgid "Shirts"
+#~ msgstr "Hemden"
+
+#~ msgid "One Handed Weapons"
+#~ msgstr "Einhänder"
+
+#~ msgid "Pants"
+#~ msgstr "Hosen"
+
+#~ msgid "Shoes"
+#~ msgstr "Schuhe"
+
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Zweihänder"
+
+#~ msgid "Shields"
+#~ msgstr "Schilde"
+
+#~ msgid "Rings"
+#~ msgstr "Ringe"
+
+#~ msgid "Necklaces"
+#~ msgstr "Halsketten"
+
+#~ msgid "Arms"
+#~ msgstr "Waffen"
+
+#~ msgid "Ammo"
+#~ msgstr "Munition"
+
+#~ msgid "HP Bar"
+#~ msgstr "HP-Leiste"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 HP-Leiste"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 HP-Leiste"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 HP-Leiste"
+
+#~ msgid "help"
+#~ msgstr "Hilfe"
+
+#~ msgid "where"
+#~ msgstr "Wo"
+
+#~ msgid "who"
+#~ msgstr "Wer"
+
+#~ msgid "whisper"
+#~ msgstr "geflüsterte Nachricht"
+
+#~ msgid "unignore"
+#~ msgstr "nicht ignorieren"
+
+#, fuzzy
+#~ msgid "join"
+#~ msgstr "Anmelden"
+
+#, fuzzy
+#~ msgid "list"
+#~ msgstr "Aufteilen"
+
+#~ msgid "party"
+#~ msgstr "Party"
+
+#~ msgid "me"
+#~ msgstr "ich"
+
+#~ msgid "record"
+#~ msgstr "nehme auf"
+
+#, fuzzy
+#~ msgid "toggle"
+#~ msgstr "Logger"
+
+#~ msgid "present"
+#~ msgstr "Anwesend: "
+
+#~ msgid "n"
+#~ msgstr "Nein"
+
+#~ msgid "N"
+#~ msgstr "Nein"
+
+#~ msgid ", coordinates: "
+#~ msgstr ", Koordinaten: "
+
+#, fuzzy
+#~ msgid "ItemShortcut"
+#~ msgstr "Kurztaste %d"
+
+#, fuzzy
+#~ msgid "EmoteShortcut"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "logToChat"
+#~ msgstr "Chat"
+
+#, fuzzy
+#~ msgid "fpslimit"
+#~ msgstr "Aufteilen"
+
+#, fuzzy
+#~ msgid "Mana_Screenshot_"
+#~ msgstr "Bildschirmfoto"
+
+#, fuzzy
+#~ msgid "cancel"
+#~ msgstr "Abbrechen"
+
+#, fuzzy
+#~ msgid "index"
+#~ msgstr "Im Fenster"
+
+#~ msgid "inc"
+#~ msgstr "Verringern"
+
+#, fuzzy
+#~ msgid "buy"
+#~ msgstr "Kaufen"
+
+#, fuzzy
+#~ msgid "quit"
+#~ msgstr "Beenden"
+
+#~ msgid "Description: %s"
+#~ msgstr "Beschreibung: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effekt: %s"
+
+#, fuzzy
+#~ msgid "BuySell"
+#~ msgstr "Verkaufen"
+
+#~ msgid "change_password"
+#~ msgstr "Passwort ändern"
+
+#~ msgid "create"
+#~ msgstr "Erstellen"
+
+#~ msgid "yes"
+#~ msgstr "Ja"
+
+#, fuzzy
+#~ msgid "unregister"
+#~ msgstr "Abmelden"
+
+#~ msgid "use"
+#~ msgstr "benutze"
+
+#~ msgid "new"
+#~ msgstr "Neu"
+
+#~ msgid "delete"
+#~ msgstr "Löschen"
+
+#~ msgid "Level %d"
+#~ msgstr "Stufe: %d"
+
+#, fuzzy
+#~ msgid "ReturnToggles"
+#~ msgstr "Enter-Taste schließt Chatzeile."
+
+#~ msgid "whispertab"
+#~ msgstr "geflüsterte Nachricht"
+
+#, fuzzy
+#~ msgid " : "
+#~ msgstr " host: "
+
+#~ msgid "no"
+#~ msgstr "Nein"
+
+#~ msgid "Cancel pressed"
+#~ msgstr "Abbrechen wurde gedrückt"
+
+#~ msgid "music"
+#~ msgstr "Musik"
+
+#~ msgid "minimap"
+#~ msgstr "Übersichtskarte"
+
+#, fuzzy
+#~ msgid "_filename"
+#~ msgstr "Sichtbare Namen"
+
+#~ msgid "unequip"
+#~ msgstr "Ausziehen"
+
+#~ msgid "Invite User"
+#~ msgstr "Spieler einladen"
+
+#~ msgid "Quit Guild"
+#~ msgstr "Gilde verlassen"
+
+#~ msgid "close"
+#~ msgstr "Schließen"
+
+#~ msgid "help/"
+#~ msgstr "Hilfe"
+
+#~ msgid "drop"
+#~ msgstr "Wegwerfen"
+
+#~ msgid "split"
+#~ msgstr "Aufteilen"
+
+#~ msgid "%s/%s"
+#~ msgstr "%s: %s"
+
+#~ msgid "all"
+#~ msgstr "alle"
+
+#~ msgid "register"
+#~ msgstr "Registrieren"
+
+#~ msgid "server"
+#~ msgstr "Server"
+
+#~ msgid "login"
+#~ msgstr "Anmelden"
+
+#~ msgid "NpcText"
+#~ msgstr "NpcText"
+
+#~ msgid "reset"
+#~ msgstr "Zurücksetzten"
+
+#~ msgid "previous"
+#~ msgstr "Zurück"
+
+#~ msgid "next"
+#~ msgstr "Weiter"
+
+#~ msgid "OutfitUnequip0"
+#~ msgstr "Ausziehen"
+
+#~ msgid "-1"
+#~ msgstr "-1"
+
+#~ msgid "OutfitUnequip"
+#~ msgstr "Ausziehen"
+
+#~ msgid "Color"
+#~ msgstr "Farbe"
+
+#, fuzzy
+#~ msgid "Gradient"
+#~ msgstr "Handeln"
+
+#~ msgid "Delay"
+#~ msgstr "Verzögerung: "
+
+#~ msgid "talk"
+#~ msgstr "Sprechen"
+
+#~ msgid "trade"
+#~ msgstr "Handeln"
+
+#~ msgid "attack"
+#~ msgstr "Angriff"
+
+#, fuzzy
+#~ msgid "disregard"
+#~ msgstr "Unbeachtet"
+
+#~ msgid "pickup"
+#~ msgstr "Aufheben"
+
+#~ msgid "look"
+#~ msgstr "Schauen "
+
+#~ msgid "chat"
+#~ msgstr "Chat"
+
+#~ msgid "store"
+#~ msgstr "Einlagern"
+
+#~ msgid "retrieve"
+#~ msgstr "Abholen"
+
+#~ msgid "name"
+#~ msgstr "Name"
+
+#~ msgid "PopupMenu: Warning, unknown action '%s'"
+#~ msgstr "PopupMenu: Warnung, unbekannte Aktion '%s'"
+
+#~ msgid "Recorder"
+#~ msgstr "Aufzeichnung"
+
+#~ msgid "sex"
+#~ msgstr "Geschlecht"
+
+#~ msgid "The queue is empty."
+#~ msgstr "Die Warteschlange ist leer."
+
+#~ msgid "sell"
+#~ msgstr "Verkaufen"
+
+#~ msgid "connect"
+#~ msgstr "Verbinde..."
+
+#~ msgid "Add Entry"
+#~ msgstr "Neuer Eintrag"
+
+#~ msgid "type"
+#~ msgstr "Typ: "
+
+#~ msgid "connection"
+#~ msgstr "Verbindung"
+
+#~ msgid "manaserv"
+#~ msgstr "manaserver"
+
+#, fuzzy
+#~ msgid "eathena"
+#~ msgstr "Erstellen"
+
+#~ msgid "hostname"
+#~ msgstr "Servername"
+
+#~ msgid "port"
+#~ msgstr "Port:"
+
+#~ msgid "musicVolume"
+#~ msgstr "Lautstärke der Musik"
+
+#~ msgid "sfxVolume"
+#~ msgstr "Lautstärke der Klangeffekte"
+
+#~ msgid "sound"
+#~ msgstr "Ton"
+
+#~ msgid "calibrate"
+#~ msgstr "Kalibrieren"
+
+#~ msgid "joystickEnabled"
+#~ msgstr "Joystick"
+
+#~ msgid "makeDefault"
+#~ msgstr "stelle Standardeinstellungen her"
+
+#~ msgid "whisper tab"
+#~ msgstr "geflüsterte Nachricht"
+
+#, fuzzy
+#~ msgid "No modes available"
+#~ msgstr "Keine Server verfügbar"
+
+#, fuzzy
+#~ msgid "screen"
+#~ msgstr "Vollbild"
+
+#~ msgid "customcursor"
+#~ msgstr "Benutzerdefinierter Zeiger"
+
+#~ msgid "visiblenames"
+#~ msgstr "Sichtbare Namen"
+
+#~ msgid "particleeffects"
+#~ msgstr "Partikeleffekte"
+
+#~ msgid "showownname"
+#~ msgstr "Zeige eigenen Namen"
+
+#~ msgid "showpickupchat"
+#~ msgstr "Benachrichtigung beim Aufheben"
+
+#, fuzzy
+#~ msgid "showpickupparticle"
+#~ msgstr "als Partikeleffekt"
+
+#, fuzzy
+#~ msgid "fontSize"
+#~ msgstr "Schriftgröße"
+
+#, fuzzy
+#~ msgid "videomode"
+#~ msgstr " Auflösung: "
+
+#, fuzzy
+#~ msgid "pickupchat"
+#~ msgstr "Aufheben"
+
+#, fuzzy
+#~ msgid "pickupparticle"
+#~ msgstr "als Partikeleffekt"
+
+#, fuzzy
+#~ msgid "particledetailslider"
+#~ msgstr "Partikeldetail"
+
+#, fuzzy
+#~ msgid "particledetailfield"
+#~ msgstr "Partikeldetail"
+
+#, fuzzy
+#~ msgid "screenheight"
+#~ msgstr "Bildschirmfoto"
+
+#, fuzzy
+#~ msgid "skills"
+#~ msgstr "Fertigkeiten"
+
+#, fuzzy
+#~ msgid "Error loading skills file: %s"
+#~ msgstr "Fehler beim Laden von %s"
+
+#, fuzzy
+#~ msgid "set"
+#~ msgstr "Zurücksetzten"
+
+#, fuzzy
+#~ msgid "skill"
+#~ msgstr "Fertigkeiten"
+
+#, fuzzy
+#~ msgid "Error loading specials file: %s"
+#~ msgstr "Fehler beim Laden von %s"
+
+#, fuzzy
+#~ msgid " (%+d)"
+#~ msgstr "HP %+d"
+
+#, fuzzy
+#~ msgid "add"
+#~ msgstr "Hinzufügen"
+
+#, fuzzy
+#~ msgid "money"
+#~ msgstr "Gefühle"
+
+#, fuzzy
+#~ msgid "Error loading update file: %s"
+#~ msgstr "Fehler beim Erstellen des Verzeichnisses für Updates!"
+
+#, fuzzy
+#~ msgid "file"
+#~ msgstr "Grinsen"
+
+#, fuzzy
+#~ msgid "description"
+#~ msgstr "Beschreibung: %s"
+
+#, fuzzy
+#~ msgid "play"
+#~ msgstr "Los!"
+
+#, fuzzy
+#~ msgid "Couldn't load news"
+#~ msgstr "Karte konnte nicht geladen werden"
+
+#~ msgid "Warning this server does not have a %s file falling back to %s"
+#~ msgstr ""
+#~ "Dieser Server besitzt keine %s Datei. Benutze stattdessen die Datei %s"
+
+#, fuzzy
+#~ msgid "users"
+#~ msgstr "benutze"
+
+#, fuzzy
+#~ msgid "topic"
+#~ msgstr "Stopp"
+
+#, fuzzy
+#~ msgid "op"
+#~ msgstr "Geschäft"
+
+#, fuzzy
+#~ msgid "kick"
+#~ msgstr "Aufheben"
+
+#~ msgid "Welcome"
+#~ msgstr "Wilkommen"
+
+#~ msgid ":-)"
+#~ msgstr ":-)"
+
+#, fuzzy
+#~ msgid "world"
+#~ msgstr "Schwertpolarm"
+
+#, fuzzy
+#~ msgid "keyMoveUp"
+#~ msgstr "Laufe Hoch"
+
+#, fuzzy
+#~ msgid "keyMoveDown"
+#~ msgstr "Laufe Runter"
+
+#, fuzzy
+#~ msgid "keyMoveLeft"
+#~ msgstr "Laufe nach Links"
+
+#, fuzzy
+#~ msgid "keyMoveRight"
+#~ msgstr "Laufe nach Rechts"
+
+#, fuzzy
+#~ msgid "keyAttack"
+#~ msgstr "Angriff"
+
+#, fuzzy
+#~ msgid "keyTargetAttack"
+#~ msgstr "Zielen & Angreifen"
+
+#, fuzzy
+#~ msgid "keySmilie"
+#~ msgstr "Grinsen"
+
+#, fuzzy
+#~ msgid "keyTalk"
+#~ msgstr "Sprechen"
+
+#, fuzzy
+#~ msgid "keyTargetNPC"
+#~ msgstr "NPC anvisieren"
+
+#, fuzzy
+#~ msgid "keyTargetPlayer"
+#~ msgstr "Spieler anvisieren"
+
+#, fuzzy
+#~ msgid "keyPickup"
+#~ msgstr "Aufheben"
+
+#, fuzzy
+#~ msgid "keyHideWindows"
+#~ msgstr "Fenster ausblenden"
+
+#, fuzzy
+#~ msgid "keyBeingSit"
+#~ msgstr "Aktionen"
+
+#, fuzzy
+#~ msgid "keyScreenshot"
+#~ msgstr "Bildschirmfoto"
+
+#, fuzzy
+#~ msgid "keyTrade"
+#~ msgstr "Handeln"
+
+#, fuzzy
+#~ msgid "keyShortcut1"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut2"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut3"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut4"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut5"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut6"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut7"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut8"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut9"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut10"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut11"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyShortcut12"
+#~ msgstr "Tastenkürzel"
+
+#, fuzzy
+#~ msgid "keyWindowInventory"
+#~ msgstr "Inventar"
+
+#, fuzzy
+#~ msgid "keyWindowEquipment"
+#~ msgstr "Ausrüstung"
+
+#, fuzzy
+#~ msgid "keyWindowSkill"
+#~ msgstr "Unbekannte Fähigkeit"
+
+#, fuzzy
+#~ msgid "keyWindowShortcut"
+#~ msgstr "Tastenkürzel"
+
+#~ msgid "Party Window"
+#~ msgstr "Partyfenster"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut1"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut2"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut3"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut4"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut5"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut6"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut7"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut8"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut9"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut10"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut11"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyEmoteShortcut12"
+#~ msgstr "Gefühlstaste %d"
+
+#, fuzzy
+#~ msgid "keyChat"
+#~ msgstr "Chat"
+
+#, fuzzy
+#~ msgid "keyChatScrollDown"
+#~ msgstr "Im Chat runter scrollen"
+
+#, fuzzy
+#~ msgid "keyQuit"
+#~ msgstr "Beenden"
+
+#, fuzzy
+#~ msgid "keyIgnoreInput1"
+#~ msgstr "Ignoriere Eingabe 1"
+
+#, fuzzy
+#~ msgid "keyIgnoreInput2"
+#~ msgstr "Ignoriere Eingabe 2"
+
+#, fuzzy
+#~ msgid "Error: Invalid update host: %s"
+#~ msgstr "Ungültiger Updateserver: "
+
+#, fuzzy
+#~ msgid "Error: %s can't be made, but doesn't exist!"
+#~ msgstr " konnte nicht erstellt werden, aber existiert auch nicht! Beende."
+
+#, fuzzy
+#~ msgid "Error: %s/%s can't be made, but doesn't exist!"
+#~ msgstr " konnte nicht erstellt werden, aber existiert auch nicht! Beende."
+
+#, fuzzy
+#~ msgid "appName"
+#~ msgstr "Name"
+
+#, fuzzy
+#~ msgid "appShort"
+#~ msgstr "Tastenkürzel"
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#, fuzzy
+#~ msgid "defaultServer"
+#~ msgstr "Server auswählen"
+
+#, fuzzy
+#~ msgid "defaultPort"
+#~ msgstr "Standard"
+
+#, fuzzy
+#~ msgid "hwaccel"
+#~ msgstr "Abbrechen"
+
+#, fuzzy
+#~ msgid "Can't create %s. Using defaults."
+#~ msgstr "Chat-Erstellung fehlgeschlagen!"
+
+#, fuzzy
+#~ msgid "The Mana World"
+#~ msgstr "The Mana World %s"
+
+#~ msgid "Can't find Resources directory\n"
+#~ msgstr "Kann das Ressourcen Verzeichnis nicht finden\n"
+
+#~ msgid "Couldn't set %dx%dx%d video mode: %s"
+#~ msgstr "Kann Videomodus %dx%dx%d nicht setzten: %s"
+
+#~ msgid "The Mana World %s"
+#~ msgstr "The Mana World %s"
+
+#~ msgid "password"
+#~ msgstr "Passwort:"
+
+#~ msgid "character"
+#~ msgstr "Spielfigur"
+
+#~ msgid "username"
+#~ msgstr "Benutztername"
+
+#~ msgid "screenshot-dir"
+#~ msgstr "Bildschirmfotoordner"
+
+#~ msgid "Username is %s"
+#~ msgstr "Benutzername ist %s"
+
+#~ msgid "Mana %s"
+#~ msgstr "Mana: %s"
+
+#~ msgid "loginMusic"
+#~ msgstr "Loginmusik"
+
+#~ msgid "lastCharacter"
+#~ msgstr "letzter Charakter"
+
+#~ msgid "Memorizing selected character %s"
+#~ msgstr "Speichere den gewählten Charakter %s"
+
+#~ msgid "Quitting"
+#~ msgstr "Beenden"
+
+#, fuzzy
+#~ msgid "EnableSync"
+#~ msgstr "Joystick aktivieren"
+
+#, fuzzy
+#~ msgid "agi"
+#~ msgstr "Magie"
+
+#, fuzzy
+#~ msgid "vit"
+#~ msgstr "Sitzen"
+
+#, fuzzy
+#~ msgid "int"
+#~ msgstr "Sitzen"
+
+#~ msgid "Connection problem: %i"
+#~ msgstr "Verbindungsproblem: %i"
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Ersatz für create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Befehl: /new <Party-Name>"
+
+#~ msgid "leave"
+#~ msgstr "verlassen"
+
+#~ msgid "Arrows equipped: %i"
+#~ msgstr "Pfeile ausgerüstet: %i"
+
+#~ msgid "Received update host \"%s\" from login server."
+#~ msgstr "Empfange Updateserver \"%s\" vom Loginserver"
+
+#~ msgid "Network: Server: %s (%s:%d)"
+#~ msgstr "Netzwerk: Server: %s (%s:%d)"
+
+#~ msgid "Unhandled packet: %x"
+#~ msgstr "Nicht behandeltes Paket : %x"
+
+#~ msgid "Network error: %s"
+#~ msgstr "Netzwerkfehler: %s"
+
+#~ msgid "Unknown party exp option: %d\n"
+#~ msgstr "Unbekannte Party exp Option: %d\n"
+
+#~ msgid "Unknown party item option: %d\n"
+#~ msgstr "Unbekannte Party Item Option: %d\n"
+
+#~ msgid "Warping to %s (%d, %d)"
+#~ msgstr "Flüsternd zu %s: (%d ,%d)"
+
+#~ msgid "Adjust scrolling by %d:%d"
+#~ msgstr "Justiere Scrolling %d:%d"
+
+#~ msgid "Chatserver: Unknown error"
+#~ msgstr "Unbekannter Fehler"
+
+#~ msgid "Unknown : "
+#~ msgstr "Unbekannt: "
+
+#, fuzzy
+#~ msgid "will"
+#~ msgstr "Fertigkeiten"
+
+#, fuzzy
+#~ msgid "Invalid guild event"
+#~ msgstr "Ungültiger Updateserver: "
+
+#~ msgid "Accountserver: Not logged in"
+#~ msgstr "nicht angemeldet"
+
+#~ msgid "Accountserver: Unknown error"
+#~ msgstr "Unbekannter Fehler"
+
+#~ msgid "Accountserver: Wrong username or password"
+#~ msgstr "Benutzername oder Passwort falsch"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "Level Progress Update"
+#~ msgstr "Levelaufstiegsfortschritt"
+
+#~ msgid "nop"
+#~ msgstr "Nö"
+
+#, fuzzy
+#~ msgid "emote0"
+#~ msgstr "Gefühle"
+
+#~ msgid "relation"
+#~ msgstr "Beziehung"
+
+#~ msgid "player"
+#~ msgstr "Spieler"
+
+#, fuzzy
+#~ msgid "blinkname"
+#~ msgstr "Unbenannt"
+
+#, fuzzy
+#~ msgid "emote1"
+#~ msgstr "Gefühle"
+
+#~ msgid "defense"
+#~ msgstr "Verteidigung:"
+
+#, fuzzy
+#~ msgid "hp"
+#~ msgstr "Geschäft"
+
+#~ msgid "generic"
+#~ msgstr "Allgemeiner Gegenstand"
+
+#~ msgid "usable"
+#~ msgstr "Benutzbare Gegenstände"
+
+#~ msgid "equip-1hand"
+#~ msgstr "Einhänder"
+
+#~ msgid "equip-2hand"
+#~ msgstr "Zweihänder"
+
+#~ msgid "equip-arms"
+#~ msgstr "Armausrüstung"
+
+#~ msgid "equip-head"
+#~ msgstr "Kopfbedeckung"
+
+#~ msgid "equip-legs"
+#~ msgstr "Beinausrüstung"
+
+#~ msgid "equip-shield"
+#~ msgstr "Schilde"
+
+#~ msgid "equip-ring"
+#~ msgstr "Ring"
+
+#~ msgid "equip-necklace"
+#~ msgstr "Halsketten"
+
+#~ msgid "equip-feet"
+#~ msgstr "Schuhe & Stiefel"
+
+#~ msgid "equip-ammo"
+#~ msgstr "Waffe"
+
+#~ msgid "knife"
+#~ msgstr "Messer"
+
+#~ msgid "sword"
+#~ msgstr "Schwert"
+
+#~ msgid "polearm"
+#~ msgstr "Waffenarm"
+
+#~ msgid "staff"
+#~ msgstr "Stab"
+
+#~ msgid "whip"
+#~ msgstr "Peitsche"
+
+#~ msgid "shooting"
+#~ msgstr "schießen"
+
+#~ msgid "mace"
+#~ msgstr "Irrgarten"
+
+#~ msgid "axe"
+#~ msgstr "Axt"
+
+#~ msgid "thrown"
+#~ msgstr "geworfen"
+
+#~ msgid "ItemDB: Error while loading items.xml!"
+#~ msgstr "Fehler beim Laden von item.xml!"
+
+#~ msgid "weight"
+#~ msgstr "Gewicht:"
+
+#~ msgid "view"
+#~ msgstr "Ansicht"
+
+#~ msgid "image"
+#~ msgstr "Bild"
+
+#~ msgid "weapon-type"
+#~ msgstr "Waffentyp"
+
+#~ msgid "attack-range"
+#~ msgstr "Angriffsreichweite"
+
+#~ msgid "effect"
+#~ msgstr "Effekt:"
+
+#~ msgid "particle-effect"
+#~ msgstr "Partikeleffekte"
+
+#, fuzzy
+#~ msgid "unisex"
+#~ msgstr "benutze"
+
+#~ msgid "male"
+#~ msgstr "Männlich"
+
+#~ msgid "female"
+#~ msgstr "Weiblich"
+
+#, fuzzy
+#~ msgid "event"
+#~ msgstr "Letzter Server:"
+
+#~ msgid "hit"
+#~ msgstr "getroffen"
+
+#~ msgid "monsters"
+#~ msgstr "Monster"
+
+#~ msgid "monster"
+#~ msgstr "Monster"
+
+#~ msgid "small"
+#~ msgstr "klein"
+
+#~ msgid "large"
+#~ msgstr "groß"
+
+#~ msgid "miss"
+#~ msgstr "verfehlt"
+
+#~ msgid "hurt"
+#~ msgstr "verletzten"
+
+#, fuzzy
+#~ msgid "action"
+#~ msgstr "Beziehung"
+
+#~ msgid "particlefx"
+#~ msgstr "als Partikeleffekt"
+
+#~ msgid "Buddy"
+#~ msgstr "Freund"
+
+#~ msgid "Buddy List"
+#~ msgstr "Freundesliste"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Berufsstufe: %d"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Spruch 1 sprechen"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Spruch 2 sprechen"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Spruch 3 sprechen"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "zweihändige Waffen"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Konnte Auflösung nicht ändern zu "
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Unbekannter Skill"
+
+#~ msgid "Weapons"
+#~ msgstr "Waffen"
+
+#~ msgid "Crafts"
+#~ msgstr "Handwerk"
+
+#~ msgid "Stats"
+#~ msgstr "Fähigkeiten"
+
+#~ msgid "Total"
+#~ msgstr "Gesamt"
+
+#~ msgid "Cost"
+#~ msgstr "Preis"
+
+#~ msgid "Attack:"
+#~ msgstr "Angriff:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Reaktion:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Verbleibende Statuspunkte: %d"
+
+#~ msgid "curl error "
+#~ msgstr "curl-Fehler "
+
+#~ msgid "Buddys"
+#~ msgstr "Freunde"
+
+#~ msgid "Unarmed"
+#~ msgstr "Unbewaffnet"
+
+#~ msgid "Bow"
+#~ msgstr "Bogen"
+
+#~ msgid "Axe"
+#~ msgstr "Axt"
+
+#~ msgid "Craft"
+#~ msgstr "Handwerk"
+
+#~ msgid "Couldn't set "
+#~ msgstr "Konnte Einstellung nicht setzen: "
+
+#~ msgid "a"
+#~ msgstr "ein"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Scroll-Radius"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Scroll-Trägheit"
+
+#~ msgid "Unable to load selection.png"
+#~ msgstr "Konnte selection.png nicht laden"
+
+#~ msgid " cancelled"
+#~ msgstr " abgebrochen"
+
+#~ msgid " -D --default : Bypass the login process with default settings"
+#~ msgstr " -D --default : Überspringe die Anmeldung mit den Voreinstellungen"
+
+#~ msgid "NPC Number Request"
+#~ msgstr "NPC Nummer Anfrage"
+
+#~ msgid ""
+#~ "\n"
+#~ "> Cancel\n"
+#~ msgstr ""
+#~ "\n"
+#~ "> Abbrechen\n"
+
+#~ msgid "NPC Text Request"
+#~ msgstr "NPC text Anfrage"
+
+#~ msgid "Slots: "
+#~ msgstr "Plätze: "
diff --git a/po/en_GB.po b/po/en_GB.po
new file mode 100644
index 000000000..dcf54645d
--- /dev/null
+++ b/po/en_GB.po
@@ -0,0 +1,5705 @@
+# English (United Kingdom) translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-03-04 21:01+0000\n"
+"Last-Translator: issyl0 <isabell121@gmail.com>\n"
+"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Setup"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Connecting to map server..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Login"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Select Character"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Connecting to map server..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Server"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Error"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Password:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Change"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Member was promoted successfully."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Unregister"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Invalid update host: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Error creating updates directory!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Unknown command."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Help --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Display this help"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Display map name"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Display number of online users"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Tell something about yourself"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Clears this window"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Send a private message to a user"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alias of msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Alias of msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Makes a tab for private messages with another user"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Alias of query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Close the whisper tab"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Disregard %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Display all public channels"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Join or create a channel"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Create a new party"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Create a new party"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Invite a user to party"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Determine whether <return> toggles the chat log"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr "/present > Get list of players present (sent to chat log, if logging)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Global announcement (GM only)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Close the whisper tab"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Send a private message to a user"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "For more information, type /help <command>."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Command: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "This command displays a list of all commands available."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Command: /help <command>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "This command displays help on <command>."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Command: /announce <msg>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** only available to a GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "This command sends the message <msg> to all players currently online."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Command: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "This command clears the chat log of previous chat."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Command: /item <policy>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "This command displays the number of players currently online."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Command: /join <channel>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "This command makes you enter <channel>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "If <channel> doesn't exist, it's created."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Command: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "This command shows a list of all channels."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Command: /me <message>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "This command tell others you are (doing) <msg>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Command: /msg <nick> <message>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Command: /whisper <nick> <message>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Command: /w <nick> <message>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "This command sends the text <message> to <nick>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "If the <nick> has spaces in it, enclose it in double quotes (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Command: /query <nick>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Command: /q <nick>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr "This command tries to make a tab for whispers between you and <nick>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Command: /w <nick> <message>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Command: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "This command sets the topic to <message>."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Command: /create <party-name>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "These commands create a new party called <party-name>."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Command: /create <party-name>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "These commands create a new party called <party-name>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Command: /party <nick>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "This command invites <nick> to party with you."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Command: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Command: /toggle <state>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Command: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "This command displays the return toggle status."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Command: /item <policy>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Command: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "This command displays the name of the current map."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Command: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "This command displays the number of players currently online."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Type /help for a list of commands."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Cannot send empty whispers!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Requesting to join channel %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Party name is missing."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Party name is missing."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Return toggles chat."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Message closes chat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Return now toggles chat."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Message now closes chat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Friend"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Disregarded"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutral"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Whisper could not be sent, ignored by user."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Party successfully created."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Whisper could not be sent, ignored by user."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Whisper could not be sent, ignored by user."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Whisper could not be sent, ignored by user."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Party successfully created."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Whisper could not be sent, ignored by user."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "General"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Screenshot saved to ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Saving screenshot failed!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "The connection to the server was lost, the program will now quit."
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Network Error"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignoring incoming trade requests"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Accepting incoming trade requests"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Could not load map"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Error while loading %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Party (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Guilds"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Chat Window"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Name"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Attack"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Talk"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Move Up"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Reset"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Buy"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Price: %s / Total: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Exit"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Max"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Shop"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Sell"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Cancel"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Change Email Address"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Account: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Type new email address twice:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "The username needs to be at least %d characters long."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "The username needs to be less than %d characters long."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "The new Email Address already exists."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Change Password"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Password:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Type new password twice:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "The password needs to be at least %d characters long."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "The password needs to be less than %d characters long."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Create Character"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Name:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Hair Colour:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Hair Style:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Create"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Male"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Female"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Please distribute %d points"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Your name needs to be at least 4 characters."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Character stats OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Please remove %d points"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Confirm Character Delete"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Are you sure you want to delete this character?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Account and Character Management"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Unregister"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Change Email Address"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Delete"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Close"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Default"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Friend"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Green: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Blue: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "low"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Hyperlink"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Thrown"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Rainbow"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Rainbow"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Rainbow"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d players are present."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Whispering to %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Yes"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "No"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignored"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Topic: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Name: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "MiniMap"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Particle Effects"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Character stats OK"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Player hits Monster"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Move Left"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Target Player"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Target Player"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Target Player"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Target Player"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Custom cursor"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Equipment"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Unequip"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Help"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Close"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventory"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Storage"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Slots:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Equip"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Use"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Drop"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Split"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Weight:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Store"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Retrieve"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Drop"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "All"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Select amount of items to trade."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Select amount of items to drop."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Select amount of items to store."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Select amount of items to retrieve."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Select amount of items to split."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Unknown error"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Weight: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Status Window"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Reset"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Reset"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Level: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Move Left"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Close"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Login"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Remember Username"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Register"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Map"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Waiting for server"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Next"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Submit"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Polearm"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Next"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "To:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Send"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Failed to send as sender or letter invalid."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Money: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Unequip"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Trade With %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Attack %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Use@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Cancel@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Retrieve@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Disregard %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignore %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Use@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Un-Ignore %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Completely ignore %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Invite a user to party"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Invite a user to party"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Un-Ignore %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Use@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Attack %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Add name to chat@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Cancel@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Pick up %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Add to chat@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Use@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Tab Highlight"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Tab Highlight"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Change"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Store"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Store"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Store"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Retrieve"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Retrieve"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Retrieve"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Add to chat@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Switch server"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Switch character"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Confirm:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "The username needs to be at least %d characters long."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "The username needs to be less than %d characters long."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "The password needs to be at least %d characters long."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "The password needs to be less than %d characters long."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Passwords do not match."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Choose your server"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Connecting..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Custom cursor"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Please type both the address and the port of a server."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Waiting for server"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Enable joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Enable joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Sfx volume"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Music volume"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "No text"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Unable to buy."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Unable to buy."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Show name"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "This is what the colour looks like"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Colours"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Type: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Static"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulse"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Rainbow"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Spectrum"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Delay: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Red: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Green: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Blue: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Apply"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Reset Windows"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Press the button to start calibration"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Calibrate"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Enable joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Stop"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Rotate the stick"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Keyboard"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Assign"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Assign"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Default"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Key Conflict(s) Detected."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Highlight"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Show name"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Enable joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Highlight"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Allow/Disallow Trading"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Unable to buy."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Unable to buy."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Enable joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "as particle"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relation"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutral"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Friend"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Disregarded"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignored"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Allow trading"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Allow whispers"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Put all whispers in tabs"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Show name"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Players"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "When ignoring:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Show name"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Show name"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Target Player"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Particle Effects"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Help"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Change"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Restart your client for the change to take effect."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Tiny"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Small"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Medium"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Large"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "No text"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Text"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Bubbles, no names"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Bubbles with names"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "off"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "low"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "high"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "medium"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Full screen"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relation"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Custom cursor"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Visible names"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Particle effects"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Show pickup notification"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "in chat"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "as particle"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Enable joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Background"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS Limit:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "FPS Limit:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Overhead text"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Gui opacity"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Ambient FX"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Particle Detail"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Font size"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "No"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "mode and restoration of old mode also failed!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "mode and restoration of old mode also failed!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Switching to full screen"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Restart needed for changes to take effect."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Changing OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Applying change to OpenGL requires restart."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Screen resolution changed"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Particle effect settings changed."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Changes will take effect on map change."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Add"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Request for Trade"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s wants to trade with you, do you accept?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Skills"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Up"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Skill points: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Skill points: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Skills"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Level: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Level: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Guild"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Guild created."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Create Guild"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Are you sure you want to quit?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Party"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Invite a user to party"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Invite a user to party"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Are you sure you want to quit?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Create Guild"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Create Character"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Invite User"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Large"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Accepted invite from %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Rejected invite from %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Accepted invite from %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Rejected invite from %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Error creating guild."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Guild"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Choose your server"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Received party request, but one already exists."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s has invited you to join the %s party."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Accept Party Invite"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Received party request, but one already exists."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s has invited you to join their party."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s has invited you to join the %s party."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s has invited you to join their party."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s has invited you to join the %s party."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Accept Party Invite"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Party"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Choose your server"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Level: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Money: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Job: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Job:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Character stats OK"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Level: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Skill points: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Move Left"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Allow trading"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Move Left"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "General"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magic"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magic"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Command: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magic"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Command: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Target Player"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Max level"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Show name"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Propose trade"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Confirmed. Waiting..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Agree trade"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Agreed. Waiting..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Trade: You"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Trade"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "You get %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "You give:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Change"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Failed adding item. You can not overlap one kind of item on the window."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "You don't have enough money."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Name: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Updating..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Connecting..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Play"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 The update process is incomplete."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 It is strongly recommended that"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 you try again later"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Completed"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Being"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Friend"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Disregarded"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignored"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "GM Names"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Other Players' Names"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Own Name"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "GM Names"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monsters"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monster hits Player"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Party"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Guild"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Particle Effects"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Pickup Notification"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Exp Notification"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Player hits Monster"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Monster hits Player"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Other Players' Names"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Critical Hit"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Player hits Monster"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Player hits Monster"
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr ""
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Misses"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Tab Highlight"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Highlight"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Tab Highlight"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monster hits Player"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Lists the users in the current channel"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Set the topic of the current channel"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Leave a channel"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Make a user a channel operator"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Kick a user from the channel"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Command: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "This command shows the users in this channel."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Command: /topic <message>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "This command sets the topic to <message>."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Command: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "This command leaves the current channel."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "If you're the last person in the channel, it will be deleted."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Command: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "This command makes <nick> a channel operator."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr "Channel operators can kick and op other users from the channel."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Command: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "This command makes <nick> leave the channel."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Need a user to op!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Need a user to kick!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Global announcement:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Global announcement from %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s whispers: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Close the whisper tab"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Command: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "This command closes the current whisper tab."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Command: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "This command displays the number of players currently online."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "This command starts recording the chat log to the file <filename>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Chat Window"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Smiley"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Shortcut"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Select OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Change"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Choose your server"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Move Up"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Move Down"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Move Left"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Move Right"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Target & Attack"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Move Left"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Smiley"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Stop Attack"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Target Closest"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Target NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Target Player"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Pick up"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Hide Windows"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Sit"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Screenshot"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Allow/Disallow Trading"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Change Email Address"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Item Shortcut %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Item Shortcut %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Help Window"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Status Window"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Inventory Window"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Equipment Window"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Skill Window"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Minimap Window"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Chat Window"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Item Shortcut Window"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Setup Window"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Debug Window"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Skill Window"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Emote Shortcut Window"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Status Window"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Setup Window"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Hide Windows"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Status Window"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Command: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Chat Window"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Previous Chat Tab"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Next Chat Tab"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Emote Shortcut %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Toggle Chat"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Scroll Chat Up"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Scroll Chat Down"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Previous Chat Tab"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Next Chat Tab"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Previous Chat Tab"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Next Chat Tab"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Select OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignore input 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignore input 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Move Down"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Move Left"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Move Right"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Switch character"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Server"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Target & Attack"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Change Password"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Change Email Address"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Allow/Disallow Trading"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Resolve them, or gameplay may result in strange behaviour."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Unable to pick up item."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "You picked up %s [@@%d|%s@@]."
+msgstr[1] "You picked up %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "You get %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Options:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Configuration file to use"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Configuration file to use"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Display the version"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Display this help"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Configuration file to use"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Login with this username"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Login with this password"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Login with this character"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Login server name or IP"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Login server port"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Use this update host"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Choose default character server and character"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Skip the update downloads"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Directory to load game data from"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Directory to use as home directory"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Directory to use as home directory"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Disable OpenGL for this session"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Strength"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Strength %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Agility"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Agility %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Dexterity"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Dexterity %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Vitality"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Vitality %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligence"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligence %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Willpower:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Willpower %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "You are dead."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "We regret to inform you that your character was killed in battle."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "You are not that alive anymore."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "The cold hands of the grim reaper are grasping for your soul."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Game Over!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Your plan of breaking your enemy's weapon by bashing it with your throat "
+"failed."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "I guess this did not run too well."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Do you want your possessions identified?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Sadly, no trace of you was ever found..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Annihilated."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Looks like you got your head handed to you."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+"You screwed up again, dump your body down the tubes and get yourself another "
+"one."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Press OK to respawn"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "You died"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Already logged in"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Username already exists"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Character stats OK"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Character stats OK"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Unknown error"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Info"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Character deleted."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Select amount of items to trade."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Unknown error"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "No gameservers are available."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Topic: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Player hits Monster"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Command: /join <channel>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Requesting to join channel %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s joined the party."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Unknown command."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Guild created."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Error creating guild."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Invite sent."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Member was promoted successfully."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Failed to promote member."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Wrong magic_token"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Already logged in"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Account expired"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "New password incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Old password incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Account not connected. Please login first."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "New email address incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Old email address incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "The new Email Address already exists."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Client version is too old"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Wrong username or password"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Account expired"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Wrong username, password or email address"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Username already exists"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Email address already exists"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Joined party."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s joined the party."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s refused your invitation."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Accepting incoming trade requests."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignoring incoming trade requests."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s wants to trade with you, do you accept?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Trading with %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Trade canceled."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Trade completed."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Kick failed!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Kick succeeded!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Nothing to sell."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Thanks for buying."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Unable to buy."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Thanks for selling."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Unable to sell."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Cannot use this ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Unknown error"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Failed to create character. Most likely the name is already taken."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Character deleted."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Failed to delete character."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Strength:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agility:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitality:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligence:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Dexterity:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Luck:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Whisper could not be sent, user is offline."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Whisper could not be sent, ignored by user."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Player"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Player"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Channels are not supported!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Name"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Request for Trade"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Strength %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Agility %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Vitality %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligence %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Dexterity %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Luck %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Authentication failed"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "No servers available"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Someone else is trying to use this account"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "This account is already logged in"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Speed hack detected"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Duplicated login"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Unknown connection error"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Disconnected from server!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Luck"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Defense:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "M.Attack:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "M.Defense:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Accuracy:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Evade:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Critical Hit"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Attack %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Attack %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monster hits Player"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Display this help."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Invite a player to your party"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Leave the party you are in"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Kick some one from the party you are in"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Command: /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "This command invites <nick> to party with you."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Command: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "This command causes the player to leave the party."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Error creating guild."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Unknown invite response for %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Guild"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Guild"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Level: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Max level"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Guild"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Guild created."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Guild created."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s is now a member of your party."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Unknown invite response for %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "You have left the party."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s has left your party."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s is now a member of your party."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Invite a player to your party"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Leave the party you are in"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Kick some one from the party you are in"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Show/change party item sharing options"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Show/change party experience sharing options"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "This command causes the player to leave the party."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Command: /item <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "This command changes the party's item sharing policy."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Command: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "This command displays the party's current item sharing policy."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Command: /exp <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "This command changes the party's experience sharing policy."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Command: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr "This command displays the party's current experience sharing policy."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Item sharing enabled."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Item sharing disabled."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Item sharing not possible."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Item sharing enabled."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Experience sharing enabled."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Experience sharing disabled."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Experience sharing not possible."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Experience sharing enabled."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Failed to use item."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Unable to equip."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Account was not found. Please re-login."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "New password too short"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Unregistered ID"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Wrong password"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Account expired"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Rejected from server"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"You have been permanently banned from the game. Please contact the GM Team."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "This user name is already taken"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Unable to sell."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Connecting to map server..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Could not create party."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Party successfully created."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s is already a member of a party."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s refused your invitation."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s is now a member of your party."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Unknown invite response for %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "You have left the party."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s has left your party."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "An unknown member tried to say: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s is not in your party!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Insert coin to continue."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "You're not dead yet. You're just resting."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "You are no more."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "You have ceased to be."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "You've expired and gone to meet your maker."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "You're a stiff."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Bereft of life, you rest in peace."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "If you weren't so animated, you'd be pushing up the daisies."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Your metabolic processes are now history."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "You're off the twig."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "You've kicked the bucket."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "You are an ex-player."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "You're pining for the fjords."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Message"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"You are carrying more than half your maximum load. You are unable to "
+"automatically regain health."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"You are carrying more than half your maximum load. You are unable to "
+"automatically regain health."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "You picked up "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "You get %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Equip arrows first."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Trade failed!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Emote failed!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Sit failed!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Failed to create channel!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Could not join party!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Can not shout!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "You have not yet reached a high enough level!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Insufficient HP!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Insufficient SP!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "You have no memos!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "You can not do that right now!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Seems you need more money... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "You cannot use this skill with that kind of weapon!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "You need another red gem!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "You need another blue gem!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "You're carrying to much to do this!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Huh? What's that?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Warp failed..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Could not steal anything..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Poison had no effect..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Trading isn't possible. Trade partner is too far away."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Trading isn't possible. Character doesn't exist."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Trade cancelled due to an unknown reason."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Trade: You and %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Trade with %s cancelled."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Unhandled trade cancel packet."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Failed to add item. Trade partner is over weighted."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "Failed to add item. Trade partner has no free slot."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Failed to add item for unknown reason."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Completely ignore %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Attack %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Defense %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Unknown item"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "unnamed"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Particle Detail"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Ambient FX"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Emote Shortcut %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Player hits Monster"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Topic: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Name: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "MiniMap"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Start recording the chat to an external file"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Command: /record <filename>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr "This command starts recording the chat log to the file <filename>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Command: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "This command finishes a recording session."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Attendance written to record log."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Finishing recording."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Not currently recording."
+
+#~ msgid "Already recording."
+#~ msgstr "Already recording."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Starting to record..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Failed to start recording."
+
+#~ msgid "Recording..."
+#~ msgstr "Recording…"
+
+#~ msgid "Stop recording"
+#~ msgstr "Stop recording"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Find Path to Mouse"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Money: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Job:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Level: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Party successfully created."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Whisper could not be sent, ignored by user."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Configuration file to use"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Configuration file to use"
+
+#~ msgid "Sound"
+#~ msgstr "Sound"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Access denied"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Unknown failure to select character"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Inviting like this isn't supported at the moment."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s has invited you to join their party."
+
+#~ msgid "Willpower:"
+#~ msgstr "Willpower:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Server is full"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Trading with %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Whisper"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Befriend %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Disregarded"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Completely ignore %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Invite %s to join your guild@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Invite %s to join your party@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Kick failed!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Talk To %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Kick monster@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Pick up"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Cannot send empty chat!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Unable to unequip."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Text Shadow"
+
+#~ msgid "Text Outline"
+#~ msgstr "Text Outline"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Progress Bar Labels"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Item too expensive"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Item is equipped"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Player"
+
+#~ msgid "Whisper"
+#~ msgstr "Whisper"
+
+#~ msgid "Is"
+#~ msgstr "Is"
+
+#~ msgid "Server"
+#~ msgstr "Server"
+
+#~ msgid "Logger"
+#~ msgstr "Logger"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Unknown Item Type"
+
+#~ msgid "Generics"
+#~ msgstr "Generics"
+
+#~ msgid "Hats"
+#~ msgstr "Hats"
+
+#~ msgid "Usables"
+#~ msgstr "Usables"
+
+#~ msgid "Shirts"
+#~ msgstr "Shirts"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "1 Handed Weapons"
+
+#~ msgid "Shoes"
+#~ msgstr "Shoes"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "1 Handed Weapons"
+
+#~ msgid "Shields"
+#~ msgstr "Shields"
+
+#~ msgid "Rings"
+#~ msgstr "Rings"
+
+#~ msgid "Necklaces"
+#~ msgstr "Necklaces"
+
+#~ msgid "Arms"
+#~ msgstr "Arms"
+
+#~ msgid "Ammo"
+#~ msgstr "Ammunition"
+
+#~ msgid "HP Bar"
+#~ msgstr "HP Bar"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 HP Bar"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 HP Bar"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 HP Bar"
+
+#~ msgid "no"
+#~ msgstr "No"
+
+#~ msgid "Buddy"
+#~ msgstr "Friend"
+
+#~ msgid "Buddy List"
+#~ msgstr "Friend list"
+
+#~ msgid "Description: %s"
+#~ msgstr "Description: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effect: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Previous"
+
+#~ msgid "New"
+#~ msgstr "New"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Job Level: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Present: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Quit Guild"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Recent:"
+#~ msgstr "Recent:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Cast Test Spell 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Cast Test Spell 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Cast Test Spell 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "2 Handed Weapons"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Unequip@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Equip@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Drop@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Split@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Store@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Select Server"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Failed to switch to "
+
+#~ msgid "windowed"
+#~ msgstr "windowed"
+
+#~ msgid "fullscreen"
+#~ msgstr "fullscreen"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Mystery Skill"
+
+#~ msgid "Weapons"
+#~ msgstr "Weapons"
+
+#~ msgid "Crafts"
+#~ msgstr "Crafts"
+
+#~ msgid "Stats"
+#~ msgstr "Stats"
+
+#~ msgid "Total"
+#~ msgstr "Total"
+
+#~ msgid "Cost"
+#~ msgstr "Cost"
+
+#~ msgid "Attack:"
+#~ msgstr "Attack:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Reflex:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Remaining Status Points: %d"
+
+#~ msgid "curl error "
+#~ msgstr "curl error "
+
+#~ msgid " host: "
+#~ msgstr " host: "
+
+#~ msgid "Buddys"
+#~ msgstr "Buddys"
+
+#~ msgid "Party Window"
+#~ msgstr "Party Window"
+
+#~ msgid "Unarmed"
+#~ msgstr "Unarmed"
+
+#~ msgid "Knife"
+#~ msgstr "Knife"
+
+#~ msgid "Sword"
+#~ msgstr "Sword"
+
+#~ msgid "Staff"
+#~ msgstr "Staff"
+
+#~ msgid "Whip"
+#~ msgstr "Whip"
+
+#~ msgid "Bow"
+#~ msgstr "Bow"
+
+#~ msgid "Shooting"
+#~ msgstr "Shooting"
+
+#~ msgid "Mace"
+#~ msgstr "Mace"
+
+#~ msgid "Axe"
+#~ msgstr "Axe"
+
+#~ msgid "Craft"
+#~ msgstr "Craft"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Unknown Skill"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " can't be created, but it doesn't exist! Exiting."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Couldn't set "
+
+#~ msgid " video mode: "
+#~ msgstr " video mode: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Connecting to character server..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Connecting to account server..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Alias of create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Command: /new <party-name>"
+
+#~ msgid "a"
+#~ msgstr "a"
+
+#~ msgid "Unnamed"
+#~ msgstr "Unnamed"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Pick Up %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Scroll radius"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Scroll laziness"
diff --git a/po/eo.po b/po/eo.po
new file mode 100644
index 000000000..d428a011a
--- /dev/null
+++ b/po/eo.po
@@ -0,0 +1,3561 @@
+# Esperanto translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-09-10 13:30+0000\n"
+"Last-Translator: Yamiharu <yamiharu84@gmail.com>\n"
+"Language-Team: Esperanto <eo@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr ""
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+msgid "Password Change"
+msgstr ""
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr ""
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "--Helpo--"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "Tiu komando monstras la liston de uzeblaj komandoj"
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "La mapo ne sxa"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr ""
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:134
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:123
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+msgid "Change Email"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, c-format
+msgid "Map: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+msgid "None"
+msgstr ""
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:416
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Ĉu vi vere volas fini la programon?"
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Ĉu vi vere volas fini la programon?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+msgid "Create Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+msgid "Level"
+msgstr ""
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Game"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+msgid "Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+msgid "Unknown error."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, c-format
+msgid "Unknown error (%d)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+msgid "Unknown channel event."
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr "sennoma"
+
+#~ msgid "no"
+#~ msgstr "Ne"
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 000000000..20734cb7c
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,5740 @@
+# Spanish translation for mana
+# Copyright (c) 2007 Rosetta Contributors and Canonical Ltd 2007
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-02-24 20:55+0000\n"
+"Last-Translator: Miguel de Dios <tres.14159@gmail.com>\n"
+"Language-Team: Spanish <es@li.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Configuración"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "conectando al servidor de mapas...."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Iniciar sesión"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Seleccionar personaje"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "conectando al servidor de mapas...."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Servidor"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Error"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Contraseña:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Modificar"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "El miembro ha sido promovido con exito."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Cancelar Cuenta"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "servidor de actualizaciones invalido: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "error al crear directorio de actualizaciones"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Comando desconocido."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "--Ayuda--"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Muestra esta ayuda"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Muestra el nombre del mapa actual"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Mostrar el número de usuarios en linea"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Diga algo de usted"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Vacia la ventana"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Enviar un mensaje privado a un usuario"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alias para un mensaje"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Alias para un mensaje"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Crea una ventana para mensajes privados con otro jugador"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Alias para una demanda"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Cierra la pestaña de susurros"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|ignorar levemente a %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Muestra todos los canales Públicos"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Entrar o crear un canal"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Crear un nuevo grupo"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Crear un nuevo grupo"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Invita a un jugador a entrar en tu grupo"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Determinar si <enter> cambia el registro de chat"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Obtener lista de jugadores presentes (enviar a registro de chat, "
+"si se guarda registro)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Anuncio global (Solo MJ's)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Cierra la pestaña de susurros"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Enviar un mensaje privado a un usuario"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Para más información, ingrese /help <comando>"
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Comando: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Este comando muestra todos los comandos disponibles."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Comando: /help <comando>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Este comando muestra ayuda sobre <otro comando>"
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Comando: /announce <mensaje>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** solo disponible a un GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"Este comando manda un mensaje a todos los jugadores que estén conectados."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Comando: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Este comando limpia el historial de chat de la conversación anterior."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Command: /item <policy>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+"Este comando muestra el número de jugadores que actualmente están conectados."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Comando: /join <canal>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Este comando sirve para ingresar a <canal>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Si <Canal> no existe, lo crea."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Comando: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Este comando muestra la lista de canales disponibles."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Comando: /me <mensaje>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Este comando le dice a los demas que estas (haciendo) <mensaje>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Comando: /msg <apodo> <mensaje>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Comando: /whisper <apodo> <mensaje>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Comando: /w <apodo> <mensaje>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Este comando le envia un <mensaje> a <apodo>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Si el <apodo> incluye espacios, encierralos entre comillas (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Comando: /query <apodo>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Comando : /q <apodo>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Este comando intenta crear una pestaña en el chat de susurros (mensajes "
+"privados) entre <apodo> y tú."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Comando: /w <apodo> <mensaje>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "hace que el tema sea <mensaje>"
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Comando: /create <nombre>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "estos comandos crean un grupo <nombre>"
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Comando: /create <nombre>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "estos comandos crean un grupo <nombre>"
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Comando: /party <apodo>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Este comando invita a <apodo> a un grupo contigo"
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Comando: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Este comando obtiene la lista de los jugadores a tu alcance y la envia al "
+"registro de grabaciones o bien al registro de chat."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Comando: /toogle <estado>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Este comando decide si la tecla de retorno debe alternar el registro de chat "
+"o bien si el registro de chat se oculta de forma automática."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<estado> puede ser \"1\" , \"yes\" o\" true\" para activarlo o bien \"0\" , "
+"\"no\" , \"false\" para desactivarlo"
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Comando: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Este comando muestra el estatus del botón alternar."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Command: /item <policy>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Comando: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Este comando muestra el nombre del mapa actual."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr ""
+"Este comando muestra el número de jugadores que actualmente están conectados."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Ingrese /help para una obtener la lista de comandos."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "No se pueden enviar susurros vacios."
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"No se puede crear una ventana para el nick \"%s\"! Quizás ya existe o eres "
+"tú."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Se te pide reunirte en el channel %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Falta el nombre del grupo."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Falta el nombre del grupo."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "la tecla de retorno alterna el chat"
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "El mensaje cierra el chat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Ahora la tecla de retorno alterna el chat."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "El mensaje ahora cierra el chat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Amigo"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "desestimado"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutral"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "El mensaje privado no se pudo enviar, la persona lo ha ignorado."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "El grupo se creo con éxito."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "El mensaje privado no se pudo enviar, la persona lo ha ignorado."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "El mensaje privado no se pudo enviar, la persona lo ha ignorado."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "El mensaje privado no se pudo enviar, la persona lo ha ignorado."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "El grupo se creo con éxito."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "El mensaje privado no se pudo enviar, la persona lo ha ignorado."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Las opciones para /%s son \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "General"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Captura de pantalla guardada en ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "¡No se pudo crear captura de pantalla!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "La conexión con el servidor se perdió, se cerrara el programa"
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Error de red"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Se están ignorando las peticiones de comercio recibidas"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Se están aceptando las peticiones de comercio"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "No se pudo cargar el mapa"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Error cargando %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Grupo (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "clanes"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "ventana del chat"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Nombre:"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "ataque"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "hablar"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "mover arriba"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Reiniciar"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Comprar"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Precio: %s / Total: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Salir"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Máx"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Tienda"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Vender"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Cambiar dirección de correo electrónico"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Cuenta: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Ingrese la nueva dirección de correo electrónico dos veces:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "El nombre de usuario debe tener al menos %d caracteres."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "El nombre de usuario puede tener como máximo %d caracteres."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "La nueva dirección de E-mail ya existe"
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Cambiar Contraseña"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Contraseña:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Ingresar la contraseña dos veces:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "La contraseña debe tener al menos %d caracteres."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "La contraseña puede tener como máximo %d caracteres."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Crear Personaje"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Nombre:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Color de pelo:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Corte de pelo:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Crear"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Hombre"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Mujer"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Distribuya %d puntos"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "El nombre debe tener al menos 4 caracteres."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Estadisticas del personaje OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Quitar %d puntos"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Confirmar borrado de personaje"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "¿Seguro que quieres eliminar este personaje?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Administración de cuenta y personajes"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Cancelar Cuenta"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Cambiar dirección de correo electrónico"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Eliminar"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Cerrar"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Predeterminado"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Amigo"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "verde: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "azul: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "bajo"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Enlance"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "arrojadizo"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "arcoiris"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "arcoiris"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "arcoiris"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d jugadores estan conectados."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Susurrando a %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Sí"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "No"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ingnorado"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Tema: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Nombre: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Minimapa"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Efectos de Partículas"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Estadisticas del personaje OK"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Jugador golpea al monstruo"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "mover a la izquierda"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "objetivo jugador"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "objetivo jugador"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "objetivo jugador"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "objetivo jugador"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Cursor propio"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "Aceptar"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Equipo"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "quitarselo"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Ayuda"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Cerrar"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventario"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "almacenamiento"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Ranuras:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Equipar"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Usar"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Tirar"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Dividir"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Peso:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "almacenar"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "recuperar"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Tirar"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Todo"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Seleccione cantidad de objetos para comerciar."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Seleccione la cantidad de objetos para tirar."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Seleccionar la cantidad de objetos a guardar."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Seleccionar la cantidad de objetos a recuperar."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Seleccione objetos para dividir."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Error desconocido."
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Peso: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "ventana de estado"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Reiniciar"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Reiniciar"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Nivel: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "EXP:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "mover a la izquierda"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Cerrar"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Iniciar sesión"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Servidor:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Recordar nombre de usuario"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registrar"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Servidor"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Mapa"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Esperando al servidor"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Siguiente"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Enviar"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "arma de palo"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Siguiente"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Para:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Enviar"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "No se pudo enviar puesto que el destino o la letra son invalidos."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Dinero: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "quitarselo"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Comerciar con %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Atacar a %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Cancelar@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Recuperar@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|ignorar levemente a %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignorar del todo a %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|dejar de ignorar a %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|ignorar al maximo %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Invita a un jugador a entrar en tu grupo"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|expulsar jugador@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|expulsar jugador@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Invita a un jugador a entrar en tu grupo"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|expulsar jugador@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|dejar de ignorar a %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Atacar a %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|expulsar jugador@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|añadir nombre al chatt@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Cancelar@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|recoger %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Añadir al chatt@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Resaltar pestaña"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Resaltar pestaña"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Modificar"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "almacenar"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "almacenar"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "almacenar"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "recuperar"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "recuperar"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "recuperar"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Añadir al chatt@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Cambiar servidor"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Cambiar personaje"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Confirmar:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "El nombre de usuario debe tener al menos %d caracteres."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "El nombre de usuario puede tener como máximo %d caracteres."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "La contraseña debe tener al menos %d caracteres."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "La contraseña puede tener como máximo %d caracteres."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Las contraseñas no coinciden."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "elige tu servidor"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Puerto:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Servidor:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Conectando…"
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Cursor propio"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Escriba la dirección y el puerto de un servidor."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Esperando al servidor"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Activar joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Activar joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Volumen efectos"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Volumen musica"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "sin texto"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Imposible comprar."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Imposible comprar."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "mostrar nombre"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "asi es como queda el color"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "colores"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "tipo: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "estatica"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "pulso"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "arcoiris"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "espectro"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "retraso: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "rojo: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "verde: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "azul: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Aplicar"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Reiniciar ventanas"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Presione el botón para comenzar la calibración"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Calibrar"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Activar joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Detener"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Gire el stick"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Teclado"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Asignar"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Asignar"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Predeterminado"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "conflictos entre teclas detectados"
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Resaltar"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "mostrar nombre"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Activar joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Resaltar"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "admitir /bloquear intercambios"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Imposible comprar."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Imposible comprar."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Activar joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "como particula"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relacion"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutral"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Amigo"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "desestimado"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ingnorado"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "permitir comercio"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "permitir susurros"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "poner susurros en pestañas"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "mostrar nombre"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Jugadores"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "cuando ignorando"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "mostrar nombre"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "mostrar nombre"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "objetivo jugador"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Efectos de Partículas"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Ayuda"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Modificar"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "para que el cambio tenga efecto reinicia el programa"
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "muy pequeño"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "pequeño"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "mediano"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "grande"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "sin texto"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Texto"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "burbujas sin nombres"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "burbujas con nombres"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "desactivado"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "bajo"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "alto"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "Medio"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Pantalla completa"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relacion"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Cursor propio"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "nombres visibles"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "efectos de particulas"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "mostrar aviso de recogida"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "en chat"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "como particula"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Activar joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Fondo"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Límite de FPS:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "Límite de FPS:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Vídeo"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "texto sobreoido"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Transparencia menus"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Efectos ambientales"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "detalle particulas"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "tamaño de letra"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "No"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "el modo y la restauracion del modo anterior fallaron"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "el modo y la restauracion del modo anterior fallaron"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Cambiar a pantalla completa"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Se necesita reiniciar para aplicar los cambios."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Cambiar a OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Se necesita reiniciar para aplicar los cambios hechos a OpenGL."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "se cambio la resolucion de pantalla"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "efectos de particulas cambiados"
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "los cambios tienen efecto en cuanto cambies de mapa"
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Añadir"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Solicitud de intercambio"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s desea realizar un intercambio con usted, acepta?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Habilidades"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Arriba"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "puntos de habilidad: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "puntos de habilidad: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Habilidades"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Nivel: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Nivel: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Clan"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Guild créada."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Crear clan"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "¿Está seguro que desea salir?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Grupo"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Invita a un jugador a entrar en tu grupo"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Invita a un jugador a entrar en tu grupo"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "¿Está seguro que desea salir?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Crear clan"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Crear Personaje"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Invitar a jugador"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "grande"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Invitacion acceptada de %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Rechazada la invitacion de %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Invitacion acceptada de %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Rechazada la invitacion de %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Eror al crear la guild."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Clan"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "elige tu servidor"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Has recibido una invitation para un grupo, pero uno existe ya."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s te invita a unirte al grupo %s."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Aceptar invitaciones a grupos"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Has recibido una invitation para un grupo, pero uno existe ya."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s te invita a unirte a su grupo."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s te invita a unirte al grupo %s."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s te invita a unirte a su grupo."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s te invita a unirte al grupo %s."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Aceptar invitaciones a grupos"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Grupo"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "elige tu servidor"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Nivel: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Dinero: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "PV:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "EXP:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "PM:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "trabajo : %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "trabajo:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Estadisticas del personaje OK"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Nivel: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "puntos de habilidad: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "mover a la izquierda"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "permitir comercio"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "mover a la izquierda"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "General"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magia:"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magia:"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Comando: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magia:"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Comando: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "objetivo jugador"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "nivel maximo"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "mostrar nombre"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Proponer"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "confirmado ... esperando"
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "aceptar trato"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "aceptado esperando..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "intercambiar: tu"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Comercio"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "tu recibes %s"
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Tu das:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Modificar"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"no se pudo añadir objeto: No puedes sobreponer un tipo de objeto en la "
+"ventana"
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "No tienes suficiente dinero."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nombre: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Actualizando ..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Conectando…"
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Jugar"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 el proceso de actualizacion esta incompleto"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 se recomienda que"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 lo intentes de nuevo mas tarde"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Terminado"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Ser"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Amigo"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "desestimado"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ingnorado"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "Nombres de los MJs"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Nombres de otros jugadores"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Nombre propio"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Nombres de los MJs"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "PNJs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monstruos"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monstruo golpea a jugador"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Grupo"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Clan"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Efectos de Partículas"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Aviso de recogida"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Aviso de Exp"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Jugador golpea al monstruo"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Monstruo golpea a jugador"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Nombres de otros jugadores"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Golpe Critico"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Jugador golpea al monstruo"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Jugador golpea al monstruo"
+
+#: src/gui/userpalette.cpp:137
+#, fuzzy
+msgid "Local Player Miss"
+msgstr "guardar lista de jugdores"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Fallos"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Resaltar pestaña"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Resaltar"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Resaltar pestaña"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monstruo golpea a jugador"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > muestra los usuarios activos en este canal"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > elegir el tema deste canal"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > abandonar el canal"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > convertir a un usuario en operador de canal"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > expulsar usuario del canal"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "orden: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "muestra los usuarios en este canal"
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Command: /topic <mensaje>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "hace que el tema sea <mensaje>"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "orden: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "te saca del canal actual"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "si eres la ultima persona de un canal sera eliminado"
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "orden: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "hace a <apodo> operador de canal"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"los operadores de canal pueden expulsar a otros usuarios y/o convertirlos en "
+"op. de canal"
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "orden:/kick <apodo>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "esta orden expulsa a <apodo> del canal"
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "necesitas a un usuario para op"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "hace falta un usuario para echarle"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Anuncio Global"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Anuncio global de %s"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s susurra: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Cierra la pestaña de susurros"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Comando: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "cierra la pestaña actual"
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Comando: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+"Este comando muestra el número de jugadores que actualmente están conectados."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Este comando graba el registro del chat en el archivo <nombre de archivo>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "ventana del chat"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "emoticono"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Estado"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Atajos"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "seleccionar OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Modificar"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "elige tu servidor"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "mover arriba"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "mover abajo"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "mover a la izquierda"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "mover a la derecha"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "objetivo y ataque"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "mover a la izquierda"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "emoticono"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "dejar de atacar"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "objetivo cercano"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "objetivo PNJ"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "objetivo jugador"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "recoger"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "ocultar ventanas"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "sentarse"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "foto de pantalla"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "admitir /bloquear intercambios"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Cambiar dirección de correo electrónico"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "atajo al objeto %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "atajo al objeto %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "ventana de ayuda"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "ventana de estado"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "ventana del inventorio"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Ventana de equipamiento"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "ventana de habilidades"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "ventana del minimapa"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "ventana del chat"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "ventana de atajos a objetos"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "ventana de configuracion"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "ventana de depuracion"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "ventana de habilidades"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "ventana de atajos a emoticones"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "ventana de estado"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "ventana de configuracion"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "ocultar ventanas"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "ventana de estado"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Comando: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "ventana del chat"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "chat anterior"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "chat siguiente"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "atajo a emoticon %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "cambiar chat"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "chat arriba"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "chat abajo"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "chat anterior"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "chat siguiente"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "chat anterior"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "chat siguiente"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "seleccionar OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "ignorar entrada 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "ignorar entrada 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "mover abajo"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "mover a la izquierda"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "mover a la derecha"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Cambiar personaje"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Servidor"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "objetivo y ataque"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Cambiar Contraseña"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Cambiar dirección de correo electrónico"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "admitir /bloquear intercambios"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "resuelvelo , o el juego puede comportarse de manera extraña"
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Imposible tomar objeto."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Ha recogido un(a) %s [@@%d|%s@@]."
+msgstr[1] "Ha recogido un(a) %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "tu recibes %s"
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opciones:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : archivo de configuracion a usar"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : archivo de configuracion a usar"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : muestra la version"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : muestra esta ayuda"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : archivo de configuracion a usar"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : conectarse con este nombre se usuario"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : entrar con esta contraseña"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : conectarse con este personaje"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : nombre o IP del servidor de conexion"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Puerto del Servidor de conexion"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Usar este servidor de actualizaciones"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : elige un servidor y personaje por defecto"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : saltarse bajar las actualizaciones"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Directorio para cargar archivos del juego"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Directorio a usar como directorio raiz"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Directorio a usar como directorio raiz"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : des habilitar OpenGl para esta sesion"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Fuerza"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "fuerza %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "agilidad2"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "agilidad %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Destreza"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Destreza %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "vitalidad"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "vitalidad %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "inteligencia"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "inteligencia %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Fuerza de voluntad:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Fuerza de voluntad: %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Estás muerto."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "Sentimos informarte de que tu personaje ha muerto en batalla."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Te quedaste sin vida."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Las manos heladas de la muerte se llevaron tu alma."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "¡Fin del juego!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"No, niños. Tu personaje no murió realmente. Él... eeh... se marchó a un "
+"lugar mejor."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Falló tu plan de romper el arma de tus enemigos golpeándola con tu garganta."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Creo que esto no funcionó muy bien."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "¿Quieres que tus posesiones sean identificadas?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Lamentablemente, ningún rastro tuyo fue encontrado nunca."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Aniquilado."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Parce que te volaron la cabeza."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+"Ya la has cagado otra vez, pon en tierra ese cuerpo por ahi en los tuneles y "
+"cogete otro."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Pulsa OK para volver a la vida"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Has muerto"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Ya estas conectado"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "El nombre de usuario ya existe"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Estadisticas del personaje OK"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Estadisticas del personaje OK"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Error desconocido."
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "informacion"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "personaje borrado"
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Seleccione cantidad de objetos para comerciar."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Error desconocido."
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "No hay servidores de juego disponibles."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Tema: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Jugador golpea al monstruo"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Comando: /join <canal>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Se te pide reunirte en el channel %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s se ha unido al grupo."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Comando desconocido."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Guild créada."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Eror al crear la guild."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Invitacion enviada."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "El miembro ha sido promovido con exito."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Fallo al promover el miembro."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Ficha de magia erronea"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Ya estas conectado"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Cuenta expirada."
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "La nueva contraseña es incorrecta"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "La contraseña antigua es incorrecta"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Cuenta no conectada. Conectate primero"
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "La nueva dirección de E-mail es incorrecta"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "La antigua dirección de E-mail es incorrecta"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "La nueva dirección de E-mail ya existe"
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "La version de tu cliente es demasiado antigua"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Nombre de usuario o contraseña incorrectos"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Cuenta expirada."
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Nombre de usuario, contraseña o dirección de email incorrectos"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "El nombre de usuario ya existe"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "La dirección de email ya existe"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Unido al grupo."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s se ha unido al grupo."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s rechazó tu invitación."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Se aceptan peticiones de intercambio."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Se ignoran peticiones de intercambio."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s desea realizar un intercambio con usted, acepta?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Intercambiar con %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Comercio cancelado."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Comercio completado."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "no se le pudo expulsar"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "se le expulso"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Nada para vender."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Gracias por comprar."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Imposible comprar."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Gravias por vender."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Impossibile vender."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "no se pude usar esta ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Error desconocido."
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "no se pudo crear personaje. probablemente el nombre este cogido"
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Personaje suprimido."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "no se pudo borrar personaje"
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Fuerza:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agilidad:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitalidad:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Inteligencia:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Destreza:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "suerte:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "El mensaje privado no se pudo enviar, la persona no esta conectada."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "El mensaje privado no se pudo enviar, la persona lo ha ignorado."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Jugador"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Jugador"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "no se soportan canales!!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Nombre:"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Solicitud de intercambio"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "fuerza %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "agilidad %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "vitalidad %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "inteligencia %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Destreza %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "suerte %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "autenticacion fallida"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "no hay servidores disponibles"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "alguien mas esta tratando de usar esta cuenta"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "esta cuenta ya esta conectada"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "se detecto hack de velocidad"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "conexion duplicada"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "error de conexion desconocido"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "fuiste desconectado del servidor!!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Suerte"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "defensa"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "ataque magico"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "defensa magica"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% AcPunteria"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% agilidad"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Golpe Critico"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Ataque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Ataque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monstruo golpea a jugador"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Mostrar la ayuda"
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Invitar a un jugador a tu grupo"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > abandonar tu grupo"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > expulsar a alguien de tu grupo"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Command: /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Este comando invita a <apodo> a un grupo contigo"
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Command: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Este comando hace que el jugador deje el grupo."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Eror al crear la guild."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Respuesta a invitacion desconocida para %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Clan"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Clan"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Nivel: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "nivel maximo"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Clan"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Guild créada."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Guild créada."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s es ahora miembro de tu grupo."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Respuesta a invitacion desconocida para %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Acaba de dejar al grupo."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s ha dejado el grupo."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s es ahora miembro de tu grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Invitar a un jugador a tu grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > abandonar tu grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > expulsar a alguien de tu grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > mostrar/cambiar opciones de compartir objetos del grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > mostrar/cambiar opciones para compartir experiencia en el grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Este comando hace que el jugador deje el grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Command: /item <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "cambia el compartir objetos dentro de un grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<policy> puede ser \"1\", \"yes\", \"true\" para compartir, o \"0\", \"no"
+"\", \"false\" para no compartir"
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Comando: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+"Este mando permite enseñar la politica de intercambio de objetos en el grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Comando: /exp <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "esta orden cambia si el grupo comparte o no la experiencia"
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<policy> puede ser \"1\", \"yes\", \"true\" para activar el intercambio de "
+"experiencia o \"0\", \"no\", \"false\" para desactivarla."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Comando: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr "Esta orden muestra si el grupo deja compartir experiencia."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Se permite compartir objetos"
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "No se permite compartir objetos"
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Imposible compartir ítem."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Se permite compartir objetos"
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Compartir experiencia activado."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Compartir experiencia desactivado."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Imposible compartir experiencia."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Compartir experiencia activado."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "No se pudo utilzar el objeto."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "no se pudo equipar"
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "La cuenta no se encontro. Por favor conectese de nuevo."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "La nueva contraseña es demasiada corta"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "ID sin registrar."
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Contraseña incorrecta."
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Cuenta expirada."
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Rechazado por el servidor."
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Has sido bloqueado permanentemente del juego. Por favor, contacta al Equipo "
+"GM."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Usted ha estado prohibido temporalmente el acceso al juego hasta %s.\n"
+"Por favor pongase en contacto con el equipo de GM a traves del forum.."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Este nombre de usuario ya está tomado."
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Impossibile vender."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "conectando al servidor de mapas...."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "No se ha podido crear el grupo."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "El grupo se creo con éxito."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s ya forma parte del grupo."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s rechazó tu invitación."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s es ahora miembro de tu grupo."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Respuesta a invitacion desconocida para %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Acaba de dejar al grupo."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s ha dejado el grupo."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Un miembro desconocido intentó decir: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s no es de su grupo !"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Inserta una moneda para continuar."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "No estás muerto aún. Sólo estás descansando."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Tú ya no existes más."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Has dejado de existir."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Has expirado e ido a encontrarte con tu creador."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Eres un tieso."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Sin vida, descanza en paz."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "Si estuvieras con mas animo, no estarias comiendo las raices."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Tus procesos metabólicos ya son historia."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Estas al borde de la ramita."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Has tocado el fondo."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+"Has terminado de barajar tu vida, has corrido debajo de la cortina y te has "
+"unido al sangriento coro invisible."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Eres un ex-jugador."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Estas ganando puntos para acabar en los fiordos."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Mensaje"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "Estás cargando más de la mitad de tu peso. No puedes recuperar salud."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr "Estás cargando más de la mitad de tu peso. No puedes recuperar salud."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Has cogido "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "tu recibes %s"
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Equipar primero las flechas."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Ha fallado el comercio"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Emoticon fallido!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Sentarse fallido!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Creación de conversación fallida!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "No pusidiste unirte al grupo!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "No puedes gritar!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "No has alcazado un nivel suficientemente alto!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Puntos de vidas insuficientes!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "insuficiente SP!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "No tienes ningun memo!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "No puedes hacer eso!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Parece que necesitas más dinero... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "No puedes usar esa habilidad con ese tipo de arma!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Necesitas otra gema roja!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Necesitas otra gema azul!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Estas cargando demasiado para hacer esto!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "¿eh? que es eso?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Teletransporte fallido..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "No pudiste robar nada..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "El veneno no tuvo efecto..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+"No se puede comerciar. La persona con quién se desea comerciar se encuentra "
+"demasiado lejos."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Intercambio imposible. El personaje no existe."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Intercambio anulado por razones desconocidas."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Intercambio: Usted y %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Intercambio con %s anulado."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Orden de cancelar intercambio descontrolado."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "No se pudo añadir el objeto. Tu compañero lleva demasiado peso encima."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "No se pudo añadir el objeto. Tu compañero no tiene espacio."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "No se pudo añadir el objeto, razon desconocida"
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|ignorar al maximo %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Ataque %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Defensa %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Objeto desconocido"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "Sin nombre"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "detalle particulas"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Efectos ambientales"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "atajo a emoticon %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Jugador golpea al monstruo"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Tema: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Nombre: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "Minimapa"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Empieza a registrar el chat en un archivo externo"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Comando: /record <nombre de archivo>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Este comando graba el registro del chat en el archivo <nombre de archivo>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Comando: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Este comando termina la sesion de grabación."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Asistencia grabada en el registro"
+
+#~ msgid "Finishing recording."
+#~ msgstr "se termino de grabar"
+
+#~ msgid "Not currently recording."
+#~ msgstr "no se esta grabando"
+
+#~ msgid "Already recording."
+#~ msgstr "ya esta grabando!!"
+
+#~ msgid "Starting to record..."
+#~ msgstr "empezando a grabar..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "no se pudo empezar a grabar"
+
+#~ msgid "Recording..."
+#~ msgstr "grabando..."
+
+#~ msgid "Stop recording"
+#~ msgstr "parar de grabar"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "encontrar ruta del raton"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "PV:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "PM:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "EXP:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Dinero: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "trabajo:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Nivel: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "El grupo se creo con éxito."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "El mensaje privado no se pudo enviar, la persona lo ha ignorado."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : archivo de configuracion a usar"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : archivo de configuracion a usar"
+
+#~ msgid "Sound"
+#~ msgstr "Sonido"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "acceso denegado"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "fallo desconocido al seleccionar personaje"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Por el momento no está soportado invitar de esta forma."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s te invita a unirte a su grupo."
+
+#~ msgid "Willpower:"
+#~ msgstr "Fuerza de voluntad:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "El servidor esta lleno"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Intercambiar con %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Susurro"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|ser amigo de %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "desestimado"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|ignorar al maximo %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Invita a %s a unirse a tu clan@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Invita a %sa unirse a tu grupoy@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "no se le pudo expulsar"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Hablar a %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|expulsar monstruor@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "recoger"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "no se pude enviar un chat vacio!!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "no se pudo desequipar"
+
+#~ msgid "Text Shadow"
+#~ msgstr "Sombra del texto"
+
+#~ msgid "Text Outline"
+#~ msgstr "Borde del texto"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "etiquetas de la barra de progreso"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Objeto demasiado caro"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Objeto equipado"
+
+#~ msgid "GM"
+#~ msgstr "MJ"
+
+#~ msgid "Player"
+#~ msgstr "Jugador"
+
+#~ msgid "Whisper"
+#~ msgstr "Susurro"
+
+#~ msgid "Is"
+#~ msgstr "Es"
+
+#~ msgid "Server"
+#~ msgstr "Servidor"
+
+#~ msgid "Logger"
+#~ msgstr "Registro"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Objeto desconocido"
+
+#~ msgid "Generics"
+#~ msgstr "Genericos"
+
+#~ msgid "Hats"
+#~ msgstr "Sombreros"
+
+#~ msgid "Usables"
+#~ msgstr "Consumibles"
+
+#~ msgid "Shirts"
+#~ msgstr "Faldas"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Armas de una mano"
+
+#~ msgid "Pants"
+#~ msgstr "Pantalones"
+
+#~ msgid "Shoes"
+#~ msgstr "Zapatos"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Armas de una mano"
+
+#~ msgid "Shields"
+#~ msgstr "Escudos"
+
+#~ msgid "Rings"
+#~ msgstr "Anillos"
+
+#~ msgid "Necklaces"
+#~ msgstr "Collares"
+
+#~ msgid "Arms"
+#~ msgstr "Brazos"
+
+#~ msgid "Ammo"
+#~ msgstr "Munición"
+
+#~ msgid "HP Bar"
+#~ msgstr "Barra de salud"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "Barra de salud a 3 cuartos"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "Barra de salud a la mitad"
+
+#~ msgid "no"
+#~ msgstr "no"
+
+#~ msgid "Buddy"
+#~ msgstr "Amigo"
+
+#~ msgid "Buddy List"
+#~ msgstr "Lista de amigos"
+
+#~ msgid "Description: %s"
+#~ msgstr "Descripción: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Efecto: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Anterior"
+
+#~ msgid "New"
+#~ msgstr "Nuevo"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Nivel de trabajo: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Presente: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Dejar el clan"
+
+#~ msgid "Ok"
+#~ msgstr "Aceptar"
+
+#~ msgid "Recent:"
+#~ msgstr "Reciente:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Usar hechizo de prueba 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Usar hechizo de prueba 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Usar hechizo de prueba 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Armas de segunda mano"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@usar|quitarselo@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Equipar@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Tirar@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Dividir@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|almacenar@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Seleccionar servidor"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "no se pudo cambiar a: "
+
+#~ msgid "windowed"
+#~ msgstr "en ventana"
+
+#~ msgid "fullscreen"
+#~ msgstr "pantalla completa"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "habilidad mis"
+
+#~ msgid "Weapons"
+#~ msgstr "armas"
+
+#~ msgid "Crafts"
+#~ msgstr "artesania"
+
+#~ msgid "Stats"
+#~ msgstr "Estadísticas"
+
+#~ msgid "Total"
+#~ msgstr "Total"
+
+#~ msgid "Cost"
+#~ msgstr "Coste"
+
+#~ msgid "Attack:"
+#~ msgstr "Ataque:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% reflejos"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "puntos de estatus que te quedan: %d"
+
+#~ msgid "curl error "
+#~ msgstr "error: "
+
+#~ msgid " host: "
+#~ msgstr " anfitrion "
+
+#~ msgid "Buddys"
+#~ msgstr "amigos"
+
+#~ msgid "Party Window"
+#~ msgstr "ventana de grupo"
+
+#~ msgid "Unarmed"
+#~ msgstr "desarmado"
+
+#~ msgid "Knife"
+#~ msgstr "cuchillo"
+
+#~ msgid "Sword"
+#~ msgstr "espada"
+
+#~ msgid "Staff"
+#~ msgstr "arma de staff"
+
+#~ msgid "Whip"
+#~ msgstr "latigo"
+
+#~ msgid "Bow"
+#~ msgstr "arco"
+
+#~ msgid "Shooting"
+#~ msgstr "disparando"
+
+#~ msgid "Mace"
+#~ msgstr "maza"
+
+#~ msgid "Axe"
+#~ msgstr "hacha"
+
+#~ msgid "Craft"
+#~ msgstr "artesanal"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "habilidad desconocida"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " no se puede crear , pero no existe , saliendo..."
+
+#~ msgid "Couldn't set "
+#~ msgstr "no se pudo configurar: "
+
+#~ msgid " video mode: "
+#~ msgstr " modo de video "
+
+#~ msgid "mana"
+#~ msgstr "TMW"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "conectando al servidor de personajes..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "conectando al servidor de cuentas de usuario..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "new > lo mismo que create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Comando: /new <nombre del grupo>"
+
+#~ msgid "a"
+#~ msgstr "un(a)"
+
+#~ msgid "Unnamed"
+#~ msgstr "Sin nombre"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Recoger %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Ratio de scroll"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Velocidad de scroll"
+
+#~ msgid "Unable to load selection.png"
+#~ msgstr "no se pudo cargar selection.png"
+
+#~ msgid "Slots: "
+#~ msgstr "ranuras: "
+
+#~ msgid "skills.xml"
+#~ msgstr "skills.xml"
+
+#~ msgid " cancelled"
+#~ msgstr " cancelado"
+
+#~ msgid "monsters.xml"
+#~ msgstr "monsters.xml"
+
+#~ msgid "items.xml"
+#~ msgstr "items.xml"
+
+#~ msgid "The Mana World %s"
+#~ msgstr "The Mana World %s"
diff --git a/po/et.po b/po/et.po
new file mode 100644
index 000000000..977b23756
--- /dev/null
+++ b/po/et.po
@@ -0,0 +1,3568 @@
+# Estonian translation for mana
+# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2010-01-26 08:47+0000\n"
+"Last-Translator: Kerdo <Unknown>\n"
+"Language-Team: Estonian <et@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Viga"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+msgid "Password Change"
+msgstr ""
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr ""
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr ""
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr ""
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:134
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:123
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "Mees"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "Naine"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+msgid "Change Email"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Kustuta"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "Sulge"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "Vestlus"
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Jah"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Ei"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "Nimi: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "Raha: %s"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "Abi"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "Sulge"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Järgmine"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Järgmine"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Ei"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:416
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+msgid "Create Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "Raha: %s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Raha: %d"
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+msgid "Level"
+msgstr ""
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nimi: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Game"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Kustuta"
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+msgid "Unknown error."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, c-format
+msgid "Unknown error (%d)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+msgid "Unknown channel event."
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Previous"
+#~ msgstr "Eelmine"
+
+#~ msgid "New"
+#~ msgstr "Uus"
diff --git a/po/fa.po b/po/fa.po
new file mode 100644
index 000000000..c85fa4853
--- /dev/null
+++ b/po/fa.po
@@ -0,0 +1,3591 @@
+# Persian translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-07-24 18:21+0000\n"
+"Last-Translator: kasra5004 <kasra5004@yahoo.com>\n"
+"Language-Team: Persian <fa@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "در حال اتصال..."
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "خطا"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "گذرواژه:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "ثبت نام نشده"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "چنین دستور وجود ندارد"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "رهنما"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "صفحه ی راهنما را نشان می دهد"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "نام نقشه ی حاضر را نشان می دهد"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "تعداد افراد آنلاین را نشان می دهد"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "با این فرمان می توانید به سایرین چیزی در مورد خودتان بگویید"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "صفحه را پاک می کند"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "می توانید با این فرمان پیغام خصوصی بفرستید"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+"با این دستور می توانید یک شاخه برای پیغام های خصوصی کاربری دیگر ، درست کنید"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "تمامی کانال های عمومی را نشان می دهد"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "با این دستور می توانید به یک کانال بپیوندید یا یکی درست کنید"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "می توانید با این دستور کاربری دیگر را به گروه خود دعوت کنید"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "می توانید با این دستور کاربری دیگر را به گروه خود دعوت کنید"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "می توانید به وسیله ی آن از چت خود، یک کپی خروجی بگیرید"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "اعلام سراسری( تنها مسئولان بازی می توانند از آن استفاده کنند.)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "برای اطلاعات بیشتر ، <دستور مورد نظر> help/ را تایپ کنید"
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "کلی"
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "خطای شبکه"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "خروج"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "حداکثر"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "انصراف"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "نام شما حداقل باید 4 کاراکتر داشته باشد"
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "نام شما حداقل باید 4 کاراکتر داشته باشد"
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "تغییر گذرواژه"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "گذرواژه:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "نام شما حداقل باید 4 کاراکتر داشته باشد"
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "نام شما حداقل باید 4 کاراکتر داشته باشد"
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "نام"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "رنگ مو"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "مدل مو"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "بساز"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "مرد"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "زن"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "نام شما حداقل باید 4 کاراکتر داشته باشد"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "تایید می کنم که خواهان حذف این شخصیت هستم"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "آیا اطمینان دارید که خواهان حذف این شخصیت هستید؟"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "ثبت نام نشده"
+
+#: src/gui/charselectdialog.cpp:150
+msgid "Change Email"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "حذف"
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "چت"
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "بلی"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, c-format
+msgid "Map: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "تجهیزات"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "تایید"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "بعدی"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "بعدی"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "در حال اتصال..."
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+msgid "None"
+msgstr ""
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:416
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "آیا مطمئن هستید که می‌خواهید خارج شوید؟"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "می توانید با این دستور کاربری دیگر را به گروه خود دعوت کنید"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "می توانید با این دستور کاربری دیگر را به گروه خود دعوت کنید"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "آیا مطمئن هستید که می‌خواهید خارج شوید؟"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "بساز"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+msgid "Level"
+msgstr ""
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "در حال اتصال..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "صفحه ی راهنما را نشان می دهد"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "نام"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "حذف"
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "می توانید با این دستور کاربری دیگر را به گروه خود دعوت کنید"
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "چنین دستور وجود ندارد"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "ثبت نام نشده"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "تغییر گذرواژه"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "چنین دستور وجود ندارد"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "چنین دستور وجود ندارد"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "no"
+#~ msgstr "خير"
+
+#~ msgid "Buddy"
+#~ msgstr "دوست"
+
+#~ msgid "Buddy List"
+#~ msgstr "فهرست دوستان"
+
+#~ msgid "Previous"
+#~ msgstr "قبلی"
+
+#~ msgid "New"
+#~ msgstr "جدید"
diff --git a/po/fi.po b/po/fi.po
new file mode 100644
index 000000000..faab4cb38
--- /dev/null
+++ b/po/fi.po
@@ -0,0 +1,3763 @@
+# Finnish translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-07-25 15:42+0000\n"
+"Last-Translator: gemis <vienamo@mbnet.fi>\n"
+"Language-Team: Finnish <fi@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "Asetukset"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Yhdistetään kartta palvelimelle"
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "Kirjaudu sisään"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Valitse hahmo"
+
+#: src/client.cpp:768
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Yhdistetään kartta palvelimelle"
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Virhe"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Salasana:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "Muuta"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Poista palvelimelta"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Tuntematon komento."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "--Apua--"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/help > Näyttää tämän apu tekstin"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > Näytä kartan nimi"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > Näytä paikalla olevien pelaajien määrä"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > Kerro jotain itsestäsi"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > Tyhjennä ikkuna"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Lähetä yksityis viesti käyttäjälle"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Tekee välilehden toisen käyttäjän yksityisviestejä varten."
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > Näytä kaikki julkiset kanavat"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/join > Liity tai luo kanava"
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/record > Aloita keskustelun nauhoitus ulkoiseen tiedostoon"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "Tämä komento näyttää listan kaikista komennoista."
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Tämä komento näyttää paikalla olevien pelaajien määrän."
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Jos kanavaa <cannel> ei ole, se luodaan."
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "Tämä komento näyttää listan kaikista kanavista"
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "Tämä komento lähettää tekstin <message> käyttäjälle <nick>."
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Tällä komennolla poistut kanvalta."
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr "Tämä komento aloittaa keskustelun nauhoituksen tiedostoon <filename>."
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "Tämä komento näyttää nykyisen kartan nimen"
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "Tämä komento näyttää paikalla olevien pelaajien määrän."
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "Kirjoita /help jotta näkisit listan komennoista."
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "Yleiset"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Ruutukaappaus tallennettu ~/"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "Ruutukaappauksen tallentaminen epäonnistui!"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Yhteys palvelimeen katkesi, ohjelma sulkeutuu nyt"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "Verkkovirhe"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "Hyväksy kauppa pyyntö"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Karttaa ei voi ladata"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "Ongelma ladatessa %s"
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "Osta"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Sulje"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "Max"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "Kauppa"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Myy"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "Peru"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Vaihda sähköpostiosoite"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Tili: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Kirjoita uusi sähköposti osoite toisen kerran:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Käyttäjänimen tulee olla vähintään %d merkkiä pitkä"
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Käyttäjänimen tulee olla alle %d merkkiä pitkä."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "Vaihda salasana"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Salasana:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Kirjoita uusi salasana toisen kerran:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Salasanan tulee olla vähintään %d merkkiä pitkä"
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Salasanan tulee olla alle %d merkkiä pitkä."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Luo hahmo"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "Nimi:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Hiusten väri:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Hiustyyli:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "Luo"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "Miespuolinen"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "Naispuolinen"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Jaa %d pistettä"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Nimessäsi täytyy olla ainakin 4 merkkiä."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Hahmon pistejako OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "%d pistettä liikaa"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "Vahvista hahmon poistopyyntö"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Oletko varma, että haluat poistaa tämän hahmon?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "Tilin ja hahmojen hallinta"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Poista palvelimelta"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Vaihda sähköpostiosoite"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Poista"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "Sulje"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "Keskustelu"
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Kyllä"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Ei"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "Nimi: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Hiukkas tehosteet"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "Hiukkas tehosteet"
+
+#: src/gui/debugwindow.cpp:121
+#, fuzzy, c-format
+msgid "Ambient FX: %s"
+msgstr "Taustaäänet"
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Varusteet"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "Poista varuste käytöstä"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "Apua"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "Sulje"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "Varusteluettelo"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "Ota käyttöön"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Käytä"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "Pudota"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "Jaa"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "Paino:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "Pudota"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "Ok"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "Kaikki"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "Anna vaihdettavien tavaroiden määrä."
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "Anna pudotettavien tavaroiden määrä."
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "Anna eri pinoon jaettavien tavaroiden määrä."
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Paino: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "Kirjaudu sisään"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "Muista käyttäjätunnus"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Rekisteröidy"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Palvelin:"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "Kartta"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "Odotetaan palvelinta"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Seuraava"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr "Lähetä"
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "Epäpelattava hahmo"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "Nollaa"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Seuraava"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "Lähetä"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "Poista varuste käytöstä"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "Teksti"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "Tekstin varjo"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "Tausta"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr "Korostus"
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "Esine on liian kallis"
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "Pelaaja"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "Palvelin:"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr "Hyperlinkki"
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "Muiden pelaajien nimet"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr "Oma nimi"
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "T"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "NPCt"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "Hirviöt"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr "Tuntematon esine tyyppi"
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "Hatut"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "Paidat"
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "Housut"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "Kengät"
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "Kilvet"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "Sormukset"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "Kaulanauhat"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "Panokset"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "@@trade|Tee kauppaa %s kanssa@@"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "Hyökkäys %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "ohitettu"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, fuzzy, c-format
+msgid "Invite %s to join your guild"
+msgstr "@@party|Kutsu %s mukaan ryhmääsi@@"
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "@@party|Kutsu %s mukaan ryhmääsi@@"
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "Hirviöt"
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr "Talleta"
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "Vaihda palvelinta"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "Vaihda hahmoa"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "Vahvista:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "Sähköpostiosoite:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Käyttäjänimen tulee olla vähintään %d merkkiä pitkä"
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Käyttäjänimen tulee olla alle %d merkkiä pitkä."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Salasanan tulee olla vähintään %d merkkiä pitkä"
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Salasanan tulee olla alle %d merkkiä pitkä."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Salasanat eivät täsmää."
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Valitse palvelin"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Palvelin:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Portti:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Palvelin:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "Yhdistetään..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Tyylitelty hiiren osoitin"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "Kirjoita kenttiin sekä palvelimen osoite että portti"
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Odotetaan palvelinta"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "Ääni"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "Ääni"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Äänitehosteiden voimakkuus"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Musiikin voimakkuus"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "Ei tekstiä"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "Värit"
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "Sateenkaari"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Hyväksy"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "Palauta ikkunoiden oletusasetukset"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "Paina tätä nappia aloittaaksesi peliohjaimen kalibroinnin"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "Kalibroi"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Peliohjaintuki päälle"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Peliohjain"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "Lopeta"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "Käytä ohjain ääriasennoissaan pyörittämällä"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Näppäimistö"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "Oletus"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "Nimi"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr "Relaatio"
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "Neutraali"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "Ystävä"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "ohitettu"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "Salli kaupakäynti"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "Näytä nimi"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "Pelaajat"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr "Pikkuruinen"
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "Pieni"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "Suuri"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "Ei tekstiä"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "pois päältä"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "matala"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "korkea"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "Kokoruututila"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "Tyylitelty hiiren osoitin"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr "Näytä nimet"
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr "Hiukkas tehosteet"
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "Näytä nimi"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Piirtonopeusrajoitin (kuvaa / sekunti)"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "Kuva"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "Näytä nimi"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "Käyttöliittymän läpinäkyvyys"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr "Taustaäänet"
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "Hiukkas tehosteet"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "Kirjasimen koko"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Ei"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Kokoruututilaan siirtyminen"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "Ohjelma pitää käynnistää uudelleen, jotta muutokset astuvat voimaan."
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Vaihdetaan OpenGL -toimintatilaan"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "OpenGL -asetusten muutokset vaativat ohjelman uudelleenkäynnistyksen"
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Näytön resoluutio vaihdettu"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Hiukkas tehoste asetukset vaihdettu."
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Taidot"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "Ylös"
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Taidot"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Taso: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Taso: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Haluatko varmasti lopettaa?"
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Haluatko varmasti lopettaa?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Luo hahmo"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "Kutsu käyttäjä"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "Suuri"
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "T"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Valitse palvelin"
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Valitse palvelin"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Taso: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Rahatilanne: %d"
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Hahmon pistejako OK"
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Taso: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr "Varasto"
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "Ehdota vaihtokauppaa"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr "Varmistettu. Odotetaan..."
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr "Hyväksy kauppa"
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr "Hyväksytty. Odotetaan..."
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "Lisää"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Annat:"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "Annat:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "Muuta"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "Sinulla ei ole tarpeeksi rahaa."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nimi: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "Päivitetään..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "Yhdistetään..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr "##1 Päivitys prosessi keskeytyi"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr "##1 On vahvasti suositeltavaa että"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 yrität myöhemmin uudelleen"
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "Valmis"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Aseta kanavan aihe"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Poistu kanavalta"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Tee käyttäjästä operaattori"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Poista käyttäjä kanavalta"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Tämä komento näyttää käyttäjät kanavalla."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Tällä komennolla poistut kanvalta."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Jos olet viimeinen henkilö kanavalla niin se katoaa."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Tämä komento tekee <nick> operaattorin."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Kanavan operaattori voi poistaa käyttäjiä kanavalta ja jakaa operaattorin "
+"oikeuksia."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "Globaali ilmoitus:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Tämä komento näyttää paikalla olevien pelaajien määrän."
+
+#: src/gui/widgets/whispertab.cpp:94
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "Tämä komento aloittaa keskustelun nauhoituksen tiedostoon <filename>."
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "Hahmon tiedot"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "Pikavalinnat"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "Valitse palvelin"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "Muuta"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "Valitse palvelin"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr "Ylöspäin"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr "Alaspäin"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr "Vasemmalle"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr "Oikealle"
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "Hirviöt"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr "Piilota ikkunat"
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr "Istu"
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "Kuvankaappaus"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr "Inventaario Ikkuna"
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr "Varuste ikkuna"
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr "Asetus ikkuna"
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+#, fuzzy
+msgid "Social Window"
+msgstr "Piilota ikkunat"
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Varuste ikkuna"
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr "Edellinen keskustelu välilehti"
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr "Seuraava keskustelu välilehti"
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr "Asetukset:"
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "/help > Näyttää tämän apu tekstin"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr "Ei mitään myytävää"
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+#, fuzzy
+msgid "Access denied."
+msgstr "Pääsy evätty"
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+#, fuzzy
+msgid "Unknown failure to select character."
+msgstr "Hahmon poisto epäonnistui"
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Hahmon luonti epäonnistui. Todennäköisesti hahmon nimi on jo käytössä."
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr "Hahmo poistettu"
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr "Hahmon poisto epäonnistui"
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "Voima:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "Ketteryys:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "Elinvoima:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "Älykkyys:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "Näppäryys:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "Pelaaja"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr "Kanavia ei tueta!"
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "Nimi"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Tunnistus epäonnistui"
+
+#: src/net/ea/generalhandler.cpp:133
+#, fuzzy
+msgid "No servers available."
+msgstr "Palvelimia ei saatavilla"
+
+#: src/net/ea/generalhandler.cpp:137
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Joku muu yrittää käyttää tätä tunnusta"
+
+#: src/net/ea/generalhandler.cpp:140
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Tällä tunnuksella on jo kirjauduttu"
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Tuntematon yhteys ongelma"
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Puolustus %+d"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "Hyökkäys %+d"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "Puolustus %+d"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Tarkkuus:"
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Poista käyttäjä kanavalta"
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Tämä komento tekee <nick> operaattorin."
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Tämä komento lähettää tekstin <message> käyttäjälle <nick>."
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr "Esineen käyttö epä-onnistui"
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr "Tunnusta ei löytynyt. Yritä uudelleen."
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Vanha salsana on väärin."
+
+#: src/net/ea/loginhandler.cpp:85
+#, fuzzy
+msgid "New password too short."
+msgstr "Uusi salasana on liian lyhyt."
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Tuntematon virhe"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Poista palvelimelta"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "Väärä salasana"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Sinun pääsysi peliin on väliaikaisesti estetty %s asti\n"
+"Ota yhteyttä GM tiimiin foorumeilla."
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Sinun pääsysi peliin on väliaikaisesti estetty %s asti\n"
+"Ota yhteyttä GM tiimiin foorumeilla."
+
+#: src/net/ea/loginhandler.cpp:172
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Käyttäjänimi on jo käytössä"
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Yhdistetään kartta palvelimelle"
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr "Sinä olet kuollut."
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr "Et ole enää elossa."
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr "Peli Loppu!"
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr "Syötä kolikko jatkaaksesi."
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Ei, lapset. Teidän hahmonne ei oikeasti kuollut. Se... öhm... meni parempaan "
+"paikkaan."
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Suunnitelmasi rikkoa vastustajiesi aseet iskemällä ne omaan kurkkuusi "
+"epäonnistui."
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr "Sinä et ole kuollut vielä. olet vain lepäämässä."
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr "Sinä et ole enään."
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr "Viesti"
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "Painat yli puolet painostasi. Et voi saavuttaa terveyttä enää."
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr "Kauppa epäonnistui!"
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr "Istuminen epäonnistui!"
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr "Et voi tehdä sitä juuri nyt!"
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr "Näyttää siltä että tarvitset lisää rahaa."
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Et voi käyttää tätä taitoa tuollaisen aseen kanssa."
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr "Tarvitset toisen punaisen helmen."
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr "Tarvitset toisen sinisen helmen."
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr "Myrkyllä ei ollut vaikutusta..."
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s haluaa käydäkauppaa kanssasi, hyväksytkö pyynnön?"
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Kaupankäynti ei ole mahdollista. kauppa kumppani on liian kaukana."
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Kaupankäynti ei ole mahdollista. Hahmoa ei ole."
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Kauppa keskeytyi tuntemattomasta syystä."
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "Annat:"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Hahmo poistettu"
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Hahmon pistejako OK"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Hahmon pistejako OK"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+#, fuzzy
+msgid "Player deleted."
+msgstr "Hahmo poistettu"
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Anna vaihdettavien tavaroiden määrä."
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Tuntematon virhe"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "Tahdonvoima:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Tuntematon komento."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "Tahdonvoima:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+#, fuzzy
+msgid "Already logged in."
+msgstr "Tällä tunnuksella on jo kirjauduttu"
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Vanha salsana on väärin."
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Kirjoita uusi sähköposti osoite toisen kerran:"
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Vanha salsana on väärin."
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Väärä salasana"
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+#, fuzzy
+msgid "Username already exists."
+msgstr "Käyttäjänimi on jo käytössä"
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "Valmis"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "Hyökkäys %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "Puolustus %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "Iskupisteet %+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "Taikapisteet %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "no"
+#~ msgstr "ei"
+
+#~ msgid "Buddy"
+#~ msgstr "Kaveri"
+
+#~ msgid "Buddy List"
+#~ msgstr "Kaverilista"
+
+#~ msgid "Description: %s"
+#~ msgstr "Kuvaus: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Vaikutus: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Edellinen"
+
+#~ msgid "New"
+#~ msgstr "Uusi"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Magic"
+#~ msgstr "Taika"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@attack|Hyökkää %s kimppuun@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@cancel|Peruuta@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Ota varuste käyttöön@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@use|Käytä@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Pudota maahan@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Pinon jako@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Kauppa@@"
+
+#~ msgid "windowed"
+#~ msgstr "ikkunoitu"
+
+#~ msgid "fullscreen"
+#~ msgstr "Kokoruututila"
+
+#~ msgid "Weapons"
+#~ msgstr "Aseet"
+
+#~ msgid "Cost"
+#~ msgstr "Hinta"
+
+#~ msgid "Guilds"
+#~ msgstr "Kiltatoiminta"
+
+#~ msgid "Knife"
+#~ msgstr "Puukko"
+
+#~ msgid "Sword"
+#~ msgstr "Miekka"
+
+#~ msgid "Whip"
+#~ msgstr "Ruoska"
+
+#~ msgid "Bow"
+#~ msgstr "Jousi"
+
+#~ msgid "Shooting"
+#~ msgstr "Ammunta"
+
+#~ msgid "Axe"
+#~ msgstr "Kirves"
+
+#~ msgid "Couldn't set "
+#~ msgstr "Ei voitu asettaa "
+
+#~ msgid " video mode: "
+#~ msgstr " video tila: "
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Yhdistetään hahmo palvelimelle"
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Yhdistetään tunnus palvelimelle"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Kameran perässälaahaus"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Kameran perässälaahauksen tiukkuus"
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 000000000..e67bf1537
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,5816 @@
+# French translation of The Mana World.
+# Copyright (C) 2007 The Mana World Development Team
+# This file is distributed under the same license as the The Mana World package.
+# Guillaume Melquiond <guillaume.melquiond@gmail.com>, 2007.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: The Mana World 0.1.0\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-01-27 21:27+0000\n"
+"Last-Translator: JVC <Unknown>\n"
+"Language-Team: French\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Configuration"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Connexion au serveur de cartes..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Connexion"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Sélectionner votre personnnage"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Connexion au serveur de cartes..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Serveur"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Erreur"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Mot de passe :"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Changer"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "La promotion de ce membre a réussie."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Se désinscrire"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Hôte de mise à jour incorrect : "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Impossible de créer le dossier de mise à jour !"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Commande inconnue."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Aide --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Montre l'aide"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Affiche le nom de la carte"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Affiche le nombre d'utilisateurs en ligne"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Dire quelque chose à votre propos"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Vide cette fenêtre"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Envoie un message privé à un utilisateur"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alias de msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Alias de msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+"/query > Crée un nouvel onglet pour vos messages privés avec un autre "
+"utilisateur"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Alias de query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Ferme l'onglet de conversation privée"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Négliger%s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Affiche une liste de tous les salons publics"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Rejoindre ou créer un salon."
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Créer un nouveau groupe"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Créer un nouveau groupe"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Invite un utilisateur dans un groupe"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+"/toggle > Détermine si la touche <entrée> bascule l'historique du tchat"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Obtiens la liste des joueurs présents (envoyée dans l'historique "
+"du tchat s'il a été activé)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Annonce globale (MJ uniquement)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Ferme l'onglet de conversation privée"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Envoie un message privé à un utilisateur"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Pour plus d'informations, taper /help <command>"
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Commande : /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Cette commande affiche une liste de toutes les commandes disponibles."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Commande : /help <commande>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Cette commande affiche une aide sur la commande <command>."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Commande : /announce <msg>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** uniquement disponible pour les MJ ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Cette commande envoie le message <msg> à tous les joueurs en ligne."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Commande : /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+"Cette commande vide l'historique de conversation de la conversation "
+"précédente."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Commande : /item <policy>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Cette commande affiche le nombre de joueurs actuellement connectés."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Commande : /join <channel>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Cette commande vous fait rentrer dans le salon <channel>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Si <channel> n'existe pas, il sera créé."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Commande : /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Cette commande affiche une liste de tous les salons publics."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Commande : /me <message>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Cette commande informe les autres joueurs que vous faites <msg>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Commande : /msg <nick> <message>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Commande : /whisper <nick> <message>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Commande : /w <nick> <message>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Cette commande envoie le texte <message> au joueur <nick>"
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Si le <nick> contient des espaces, entourez le de guillemets (exemple : \"ni "
+"ck\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Commande : /query <nick>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Commande : /q <nick>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Cette commande essaye de créer une fenêtre de dialogue entre vous et <nick>"
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Commande : /w <nick> <message>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Commande : /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Cette commande change le sujet du salon en <message>"
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Commande : /create <party-name>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Cette commande crée un nouveau groupe appelé <party-name>"
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Commande : /create <party-name>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Cette commande crée un nouveau groupe appelé <party-name>"
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Commande : /party <nick>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Cette commande invite <nick> à rejoindre votre groupe."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Commande : /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Cette commande récupère une liste de tous les joueurs présents et l'envoie "
+"dans le fichier d'enregistrement s'il est activé, ou dans l'enregistrement "
+"de la conversation."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Command: /toggle <state>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Cette commande définie si la touche entrée doit fermer le fichier "
+"d'enregistrement de la conversation ou si celui-ci se fermera "
+"automatiquement."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<state> peut être en position \"1\", \"yes\", \"true\" pour activer le "
+"bouton sur marche, ou \"0\", \"no\", \"false\" pour désactiver le bouton."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Commande : /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Cette commande vous affiche le status du toggle courant."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Commande : /item <policy>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Commande : /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Cette commande affiche le nom de la carte où vous vous trouvez."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Commande : /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Cette commande affiche le nombre de joueurs actuellement connectés."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Entrer /help pour obtenir une liste des commandes disponibles."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Vous ne pouvez pas envoyer des messages privés vides !"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Il ne peut être créer une fenêtre de conversation avec nick \"%s\" ! Elle "
+"existe déjà ou il s'agit de vous même."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Il vous est demandé de rejoindre le chan %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Indiquez un nom de groupe."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Indiquez un nom de groupe."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "La touche enter ferme maintenant la ligne d'entrée du chat."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Ce message ferme la conversation."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "La touche enter ferme la ligne d'entrée de la conversation."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Ce message ferme maintenant la conversation."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Ami"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Négligé"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutre"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Le message privé n'a pu être envoyé, le destinataire l'a ignoré."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Création du groupe réussie."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Le message privé n'a pu être envoyé, le destinataire l'a ignoré."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Le message privé n'a pu être envoyé, le destinataire l'a ignoré."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Le message privé n'a pu être envoyé, le destinataire l'a ignoré."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Création du groupe réussie."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Le message privé n'a pu être envoyé, le destinataire l'a ignoré."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Les options qui peuvent être transmises à /%s sont \"yes\", \"no\", \"true"
+"\", \"false\", \"1\", \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Général"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Capture d'écran sauvegardée dans ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Impossible de sauvegarder la capture d'écran !"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr ""
+"La connexion au serveur a été coupée, le programme va maintenant se fermer."
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Erreur Réseau"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignorer les requêtes d'échanges entrantes"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Accepter les requêtes d'échanges entrantes"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "La localisation géographique n'a pu être chargé"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Erreur durant le chargement %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Groupe (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Guildes"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Fenêtre d'emote"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Nom"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Attaquer"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Parler"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Monter"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Réinitialiser"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Acheter"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Prix : %s / Total : %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr "+"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr "-"
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Quitter"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Max."
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Magasin"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Vendre"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Annuler"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Modifier l'adresse mail"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Compte : %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Entrer de nouveau la nouvelle adresse mail :"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Le nom d'utilisateur doit faire au moins %d caractères."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Le nom d'utilisateur doit faire moins de %d caractères."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Cette nouvelle adresse email existe déjà."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Changer le mot de passe"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Mot de passe :"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Entrer une nouvelle fois le nouveau mot de passe :"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Le mot de passe doit faire au moins %d caractères."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Le mot de passe doit faire moins de %d caractères."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Création du personnage"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Nom :"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Couleur des cheveux :"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Coupe :"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Créer"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Masculin"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Féminin"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Veuillez distribuer %d points"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Votre nom doit comporter un minimum de 4 caractères."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Caractéristiques du personnage Ok"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Veuillez retirer %d points"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Confirmer la suppression du personnage"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Êtes-vous certain de vouloir supprimer ce personnage ?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Gestion du compte et du personnage"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Se désinscrire"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Modifier l'adresse mail"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Supprimer"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Fermer"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Par défaut"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Ami"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Vert : "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Bleu : "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "léger"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Lien"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Lancé"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Arc-en-ciel"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Arc-en-ciel"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Arc-en-ciel"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Conversation"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d joueurs sont présents."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Message privé envoyé à %s : %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Oui"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Non"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignoré"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Sujet : %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Nom : %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Plan"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Effets de particules"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Caractéristiques du personnage Ok"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Le joueur touche le monstre"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Aller à gauche"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Cibler le Joueur"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Cibler le Joueur"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Cibler le Joueur"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Cibler le Joueur"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Curseur personnalisé"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "Ok"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Équipement"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Retirer"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Aide"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Fermer"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventaire"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Stockage"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Cases :"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Équiper"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Utiliser"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Jeter"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Partager"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Poids :"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Entreposer"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Récupérer"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Jeter"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Tout"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Choisissez le nombre d'objets à troquer."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Choisissez le nombre d'objets à jeter."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Sélectionnez le nombre d'objets à stocker."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Sélectionnez le nombre d'objet à reprendre"
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Choisissez le nombre d'objets à déplacer."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Erreur inconnue"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Poids : "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Fenêtre d'état"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Réinitialiser"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Réinitialiser"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Niveau : %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp :"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Aller à gauche"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Fermer"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Connexion"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Serveur :"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Se souvenir du nom d'utilisateur"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "S'inscrire"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Serveur"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Plan"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Attente du serveur"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Suivant"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Soumettre"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "PNJ"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Pique"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Suivant"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "A :"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Envoyer"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Echec de l'envoi comme émetteur ou caractère invalide."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Argent : %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Retirer"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Troquer avec %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Attaquer %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Utiliser@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Annuler@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Retirer@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Négliger%s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignorer %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Utiliser@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Ne plus ignorer %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Complètement ignorer %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Invite un utilisateur dans un groupe"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Invite un utilisateur dans un groupe"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Ne plus ignorer %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Utiliser@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Attaquer %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Kick player@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Ajouter le nom dans la conversation@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Annuler@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Ramasser %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Ajouter à la conversation@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Utiliser@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Onglet mis en surbrillance"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Onglet mis en surbrillance"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Changer"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Entreposer"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Entreposer"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Entreposer"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Récupérer"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Récupérer"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Récupérer"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Ajouter à la conversation@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Changer de serveur"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Changer de personnage"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Vérification :"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email :"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Le nom d'utilisateur doit faire au moins %d caractères."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Le nom d'utilisateur doit faire moins de %d caractères."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Le mot de passe doit faire au moins %d caractères."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Le mot de passe doit faire moins de %d caractères."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Les deux mots de passe sont différents"
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Choisissez le serveur"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port :"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Serveur :"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Connexion..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Curseur personnalisé"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Veuillez entrer l'adresse et le port du serveur."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Attente du serveur"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Activer le joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Activer le joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Volume des effets sonores"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Volume de la musique"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Pas de texte"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Impossible d'acheter."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Impossible d'acheter."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Afficher le nom"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Voilà à quoi ressemble cette couleur"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Couleurs"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Type : "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statique"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Impulsion"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Arc-en-ciel"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Spectre"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Retardé : "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Rouge : "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Vert : "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Bleu : "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Appliquer"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Rétablir les fenêtres"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Presser le bouton pour démarrer la calibration"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Calibrer"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Activer le joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Stop"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Tourner le joystick"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Clavier"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Assigner"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Assigner"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Par défaut"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Conflit(s) de touche détecté"
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Surbrillance"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Afficher le nom"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Activer le joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Surbrillance"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Activer / Désactiver les échanges"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Impossible d'acheter."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Impossible d'acheter."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Activer le joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "avec des particules"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relation"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutre"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Ami"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Négligé"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignoré"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Autoriser les échanges"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Autoriser les messages privés"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Placer tous les messages privés dans des onglets"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Afficher le nom"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Joueurs"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Quand ignoré :"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Afficher le nom"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Afficher le nom"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Cibler le Joueur"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Effets de particules"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Aide"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Changer"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Redémarrez le jeu pour que les changements soient appliqués."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "fin"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Petit"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Medium"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Grand"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "Ouvrir GL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "Ouvrir GL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Pas de texte"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Texte"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Bulles, sans noms"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Bulles avec noms"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "aucun"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "léger"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "élevé"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "moyen"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Plein écran"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relation"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Curseur personnalisé"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Afficher les noms"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Effets de particules"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Afficher les messages de ramassage"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "dans la conversation"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "avec des particules"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Activer le joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Arrière-plan"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Limite FPS :"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "Limite FPS :"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Vidéo"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Texte aérien"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Opacité de l'interface"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Effets ambiants"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Détail des particules"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Taille de police"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Non"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "le mode et la restauration du vieux mode ont également échoué !"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "le mode et la restauration du vieux mode ont également échoué !"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Passage en plein écran"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr ""
+"Les changements ne seront pris en compte qu'au prochain démarrage du jeu."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Changement OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+"Le changement OpenGL ne sera pris en compte qu'au prochain démarrage du jeu."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Résolution de l'écran changée"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Paramètres d'effet de particules changés."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Les changements seront appliqués au changement de carte."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Ajouter"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Demande d'échange"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s souhaite réaliser un échange avec vous. Acceptez-vous ?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Compétences"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Augmenter"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Points de compétences : %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Points de compétences : %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Compétences"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Niveau : %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Niveau : %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Guilde"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Guilde créée."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Créer une Guilde"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Êtes-vous sûr de vouloir sortir ?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Groupe"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Invite un utilisateur dans un groupe"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Invite un utilisateur dans un groupe"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Êtes-vous sûr de vouloir sortir ?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Créer une Guilde"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Création du personnage"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Inviter un utilisateur"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Grand"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Invitation acceptée de la part de %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Invitation refusée de la part de %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Invitation acceptée de la part de %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Invitation refusée de la part de %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Erreur lors de la création de la guilde."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Guilde"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Choisissez le serveur"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr ""
+"Vous avez reçu une demande de rejoindre un groupe, mais il en existe déjà un."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s vous a invité à rejoindre le groupe %s."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Accepter l'invitation pour ce groupe"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr ""
+"Vous avez reçu une demande de rejoindre un groupe, mais il en existe déjà un."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s vous a invité à rejoindre son groupe."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s vous a invité à rejoindre le groupe %s."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s vous a invité à rejoindre son groupe."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s vous a invité à rejoindre le groupe %s."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Accepter l'invitation pour ce groupe"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Groupe"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Choisissez le serveur"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Niveau : %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Argent : %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "Vie :"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp :"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "PM :"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Metier : %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Habilité :"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Caractéristiques du personnage Ok"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Niveau : %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Points de compétences : %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Aller à gauche"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Autoriser les échanges"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Aller à gauche"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Général"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magie"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magie"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Commande : /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magie"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Commande : /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Cibler le Joueur"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Niveau max."
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Afficher le nom"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Proposer un troc"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Confirmé. En attente..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Accepter l'échange"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Accepté. En attente..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Échange : Vous"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Échange"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Vous recevez %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Vous donnez :"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Changer"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"L'objet ne peux être ajouté. Vous ne pouvez ajouter deux fois le même objet "
+"dans cette fenêtre."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Vous n'avez pas assez d'argent."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nom : %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Mise à jour en cours..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Connexion..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Jouer"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Le processus de mise à jour n'est pas achevé"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Il est fortement recommandé que"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 vous réessayez plus tard"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Terminé"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Forme de vie"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Ami"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Négligé"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignoré"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "Nom des MJ"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Nom des autres joueurs"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Mon nom"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Nom des MJ"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "PNJs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monstres"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Le monstre touche le joueur"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Groupe"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Guilde"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Effets de particules"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Information de récupération"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Information d'expérience"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Le joueur touche le monstre"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Le monstre touche le joueur"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Nom des autres joueurs"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Coup critique"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Le joueur touche le monstre"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Le joueur touche le monstre"
+
+#: src/gui/userpalette.cpp:137
+#, fuzzy
+msgid "Local Player Miss"
+msgstr "Sauvegarder la liste de joueurs"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Coups manqués"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Onglet mis en surbrillance"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Surbrillance"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Onglet mis en surbrillance"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Le monstre touche le joueur"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Affiche la liste des utilisateurs de ce salon"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Change le sujet du salon"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Quitter un salon"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Faire de l'utilisateur un opérateur du salon"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Sortir un utilisateur du salon"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Commande : /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Cette commande affiche la liste d'utilisateurs présents dans ce salon."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Commande: /topic <message>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Cette commande change le sujet du salon en <message>"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Commande : /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Cette commande quitte le salon."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+"Si vous étiez la dernière personne présente dans ce salon, il sera supprimé."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Commande : /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Cette commande donne les droit d'opérateur du salon à <nick>"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Seul les opérateurs du salon peuvent sortir des utilisateurs et donner les "
+"droit d'opérateur aux autres utilisateurs du salon."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Commande : /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Cette commande sort <nick> du salon."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Indiquez à quel utilisateur donner les droit d'opérateur !"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Indiquez quel utilisateur sortir !"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Annonce globale :"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Annonce globale de %s :"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "Message privé de %s : "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Ferme l'onglet de conversation privée"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Commande : /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Cette commande ferme l'onglet courant de conversation privée."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Commande : /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Cette commande affiche le nombre de joueurs actuellement connectés."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Cette commande active l'enregistrement de la conversation dans le fichier "
+"<filename>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Fenêtre d'emote"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Smilie"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Statut"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Raccourcis"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Sélectionner OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Changer"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Choisissez le serveur"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Monter"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Descendre"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Aller à gauche"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Aller à droite"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Cibler et Attaquer"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Aller à gauche"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Smilie"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Arrêter d'attaquer"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Cible la plus proche"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Cibler le PNJ"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Cibler le Joueur"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Ramasser"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Cacher les fenêtres"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "S'assoir"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Capture d'écran"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Activer / Désactiver les échanges"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Modifier l'adresse mail"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Raccourci Objet %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Raccourci Objet %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Fenêtre d'Aide"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Fenêtre d'état"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Fenêtre de l'inventaire"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Fenêtre d'équipements."
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Fenêtre de compétences"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Fenêtre du plan"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Fenêtre de conversation"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Fenêtre de raccourci objet"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Fenêtre de configuration"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Fenêtre de debug"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Fenêtre de compétences"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Fenêtre de raccourcis d'emote"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Fenêtre d'état"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Fenêtre de configuration"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Cacher les fenêtres"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Fenêtre d'état"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Commande : /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Fenêtre d'emote"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Onglet de la conversation précédente"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Onglet de la conversation suivante"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Raccourci d'emote %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Activer / Désactiver la conversation"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Défiler la conversation (haut)"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Défiler la conversation (bas)"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Onglet de la conversation précédente"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Onglet de la conversation suivante"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Onglet de la conversation précédente"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Onglet de la conversation suivante"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Sélectionner OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignorer l'entrée 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignorer l'entrée 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Descendre"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Aller à gauche"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Aller à droite"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Changer de personnage"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Serveur"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Cibler et Attaquer"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Changer le mot de passe"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Modifier l'adresse mail"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Activer / Désactiver les échanges"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+"Trouver une solution ou des choses étranges se produiront pendant la partie."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Impossible de ramasser l'objet."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "vous avez ramassé un(e) %s [@@%d|%s@@]."
+msgstr[1] "vous avez ramassé un(e) %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Vous recevez %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Options :"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Fichier de configuration à utiliser"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Fichier de configuration à utiliser"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Affiche la version"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Montre cette aide"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Fichier de configuration à utiliser"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Se connecter avec ce nom d'utilisateur"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Se connecter avec ce mot de passe"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Se connecter avec ce personnage"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Nom du serveur pour la connexion ou IP"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Port de connexion au serveur"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Utilise cette mise à jour d'Hôte"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+" -D --default : Choisir le serveur de personnages et le personnage par "
+"défaut"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Passer les téléchargements de mise à jour"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+" -d --data : Répertoire dans lequel les données du jeu se trouvent et "
+"seront chargées"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Répertoire à utiliser comme répertoire principal"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Répertoire à utiliser comme répertoire principal"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Désactive OpenGL pour cette session"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Force"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Force %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Agilité"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Agilité %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Dextérité"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Dextérité %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Vitalité"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Vitalité %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligence"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligence %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Volonté :"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Volonté %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Vous êtes mort."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+"Nous avons le regret de vous informer que votre personnage est mort sur le "
+"champ de bataille."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Vous n'êtes plus vraiment en vie."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Les mains gelées de la faucheuse viennent réclamer votre âme."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Fin de la partie !"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Non, les enfants. Ton personnage n'est pas vraiment mort... Il... enfin,.. "
+"il... est parti dans un monde meilleur."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Votre tentative de casser l'arme de votre ennemi en la frappant avec votre "
+"gorge a échoué."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "J'ai la sensation que cela ne s'est pas aussi bien passé que prévu."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Voulez-vous que vos biens soient identifiés ?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Tristement, aucune trace de vous ne fut jamais retrouvée..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Vaporisé."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Il semble que l'on vous ait rendu votre tête."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+"Vous avez encore échoué, jetez votre corps aux oubliettes et prenez en un "
+"autre."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Cliquer sur OK pour ressuciter"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Vous êtes mort"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Déjà connecté"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Ce nom d'utilisateur existe déjà"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Caractéristiques du personnage Ok"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Caractéristiques du personnage Ok"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Erreur inconnue"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Informations"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Personnage supprimé"
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Choisissez le nombre d'objets à troquer."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Erreur inconnue"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Pas de serveur de jeu disponible."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Sujet : %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Le joueur touche le monstre"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Commande : /join <channel>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Il vous est demandé de rejoindre le chan %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s a rejoind le groupe."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Commande inconnue."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Guilde créée."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Erreur lors de la création de la guilde."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Invitation envoyée."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "La promotion de ce membre a réussie."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Echec lors de la promotion du membre"
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Mauvaise empreinte magique"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Déjà connecté"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Compte expiré"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Nouveau mot de passe incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Ancien mot de passe incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Compte non connecté. Identifiez-vous tout d'abord."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Nouvelle adresse email incorrecte"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Ancienne adresse email incorrecte"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Cette nouvelle adresse email existe déjà."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "La version de votre client est trop ancienne."
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Mauvais nom d'utilisateur ou mot de passe."
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Compte expiré"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Mauvais nom d'utilisateur, mot de passe ou adrese email."
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Ce nom d'utilisateur existe déjà"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Cette adresse email existe déjà"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Groupe rejoind."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s a rejoind le groupe."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s a refusé votre invitation."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Accepter les demandes d'échanges."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignorer les demandes d'échanges."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s souhaite réaliser un échange avec vous. Acceptez-vous ?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Echange avec %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Echange annulé."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Echange finalisé."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Impossible de sortir la personne !"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Sortie de la personne effectuée avec succès !"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Rien à vendre."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Merci pour votre achat."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Impossible d'acheter."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Merci pour votre vente."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Impossible de vendre."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Impossible d'utiliser cet ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Erreur inconnue"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+"Impossible de créer ce personnage. Il est probable que ce nom soit déjà "
+"utilisé."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Personnage supprimé."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "La suppresion du personnage n'a pu s\"effectuer."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Force :"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agilité :"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitalité :"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligence :"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Dextérité :"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Chance :"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr ""
+"Le message privé n'a pu être envoyé, le destinataire n'est pas connecté."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Le message privé n'a pu être envoyé, le destinataire l'a ignoré."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Joueur"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Joueur"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Les salons ne sont pas gérés !"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Nom"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Demande d'échange"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Force %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Agilité %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Vitalité %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligence %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Dextérité %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Chance %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Échec de l'indentification"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Aucun serveur n'est disponible"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Quelqu'un d'autre essaye d'utiliser ce compte"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Ce compte est déjà connecté"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Speed hack detecté"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Identification dupliquée"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Erreur de connexion inconnue"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Vous avez été déconnecté du serveur !"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Chance"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Défense :"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "Attaque M. :"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "Défense M. :"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Précision :"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Esquive :"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Coup critique"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Attaque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Attaque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Le monstre touche le joueur"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Affiche cette aide."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Invite un joueur à rejoindre votre groupe"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Quitte le groupe dans lequel vous vous trouvez"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Sortir quelqu'un du groupe dont vous faites partie"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Commande : /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Cette commande invite <nick> à rejoindre votre groupe."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Commande : /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Cette commande vous fait quitter votre groupe actuel."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Erreur lors de la création de la guilde."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Réponse d'invitation de %s inconnue."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Guilde"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Guilde"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Niveau : %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Niveau max."
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Guilde"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Guilde créée."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Guilde créée."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s est maintenant membre de votre groupe."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Réponse d'invitation de %s inconnue."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "vous avez quitté le groupe."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s a quitté le groupe."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s est maintenant membre de votre groupe."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Invite un joueur à rejoindre votre groupe"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Quitte le groupe dans lequel vous vous trouvez"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Sortir quelqu'un du groupe dont vous faites partie"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Affiche / Modifie les préférences d'échange d'objet du groupe"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Affiche / Modifie les préférences d'expérience du groupe"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Cette commande vous fait quitter votre groupe actuel."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Commande : /item <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Cette commande change les préférences d'échange d'objet du groupe."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<préférences> peut être \"1\", \"yes\", \"true\" pour activer l'échange "
+"d'objet, ou \"0\", \"no\", \"false\" pour le désactiver."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Commande : /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+"Cette commande affiche les préférences actuelles du groupe sur le partage "
+"d'objet."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Commande : /exp <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+"Cette commande change les préférences du groupe sur le partage d'expérience."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<préférences> peut être \"1\", \"yes\", \"true\" pour activer le partage "
+"d'expérience, ou \"0\", \"no\", \"false\" pour le désactiver."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Commande : /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+"Cette commande affiche les préférences actuelles du groupe sur le partage "
+"d'expérience."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Partage d'objet activé."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Partage d'objet desactivé."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Partage d'objet impossible."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Partage d'objet activé."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Partage d'expérience authorisé."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Partage d'expérience non authorisé."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Partage d'expérience impossible."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Partage d'expérience authorisé."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Impossible d'utiliser l'objet."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Impossible d'équiper cet objet."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Le compte n'a pas été trouvé. Reconnectez vous svp."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Nouveau mot de passe trop court"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "ID non enregistrée"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Mauvais mot de passe"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Compte expiré"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Rejeté par le server"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Vous avez été banni de façon permanente du jeu. Merci de vous mettre en "
+"contact avec l'équipe des MJ."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Vous avez été banni temporairement du jeu depuis %s.\n"
+"Merci de contacter un MJ par le forum."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Ce nom d'utilisateur est déjà utilisé"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Impossible de vendre."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Connexion au serveur de cartes..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Le groupe n'a pu être créé."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Création du groupe réussie."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s est déjà membre du groupe."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s a refusé votre invitation."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s est maintenant membre de votre groupe."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Réponse d'invitation de %s inconnue."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "vous avez quitté le groupe."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s a quitté le groupe."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Un membre inconnu a essayé de dire : %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s n'est pas membre de votre groupe !"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "veuillez insérer une pièce pour continuer."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Vous n'êtes pas encore mort. Vous vous reposez seulement."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Vous n'existez plus."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Vous avez cessez d'exister."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Tu es fini. Tu es parti retrouver ton créateur."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Tu es un dur."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Privé de toute essence de vie, vous reposez en paix."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+"Si tu n'étais pas autant en forme, tu serais en train de manger les "
+"pissenlits par la racine."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Vos processus métaboliques appartiennent au passé maintenant."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Tu es en dehors des clous"
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Tu viens de toucher le fond."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+"Vous êtes sorti de votre enveloppe charnelle et mortelle. Vous avez rejoint "
+"l'armée de l'ombre."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Tu n'es plus qu'un ancien joueur sans intérêt."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Tu reposes au fond de l'eau."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Message"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Vous portez plus de la moitié du poids de votre inventaire. Vous n'êtes plus "
+"en mesure de regagner vos points de vie."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Vous portez plus de la moitié du poids de votre inventaire. Vous n'êtes plus "
+"en mesure de regagner vos points de vie."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Vous avez ramassé "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Vous recevez %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Equiper en premier les flèches"
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Echange non réalisé !"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Emote non realisé !"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Vous n'avez pas pu vous assoir !"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Vous n'avez pas pu créer la conversation !"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Vous n'avez pas pu rejoindre le groupe !"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Vous ne pouvez pas crier !"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Vous n'avez pas encore atteind le niveau requis !"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Pas assez de vie !"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "PV insuffisant !"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Vous n'avez pas de messages !"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Vous ne pouvez faire cela maintenant !"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Il semblerait que vous ayez besoin de plus d'argent... ;)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Vous ne pouvez utiliser ce pouvoir avec ce type d'arme !"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Vous avez besoin d'une autre pierre précieuse rouge !"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Vous avez besoin d'une autre pierre précieuse bleue !"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Vous portez trop de choses pour pouvoir faire cela !"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Hé ? Qu'est-ce donc que cela ?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Enchainement échoué..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Vous n'avez rien pu voler..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Le poison fut sans effet..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "L'échange est impossible. Votre partenaire est trop éloigné."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Echange impossible. Ce personnage n'existe pas."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Echange annulé pour une raison inconnue."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Echange : Vous et %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Echange avec %s annulé."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Echange non pris en compte."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+"Impossible de rajouter un objet. Votre partenaire pour cet échange est "
+"surchargé."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+"Impossible de rajouter un objet. Votre partenaire pour cet échange n'a plus "
+"de place libre."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Impossible de rajouter un objet pour une raison inconnue."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Complètement ignorer %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Attaque %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Défense %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "PV %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "PM %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Objet inconnu"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "anonyme"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Détail des particules"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Effets ambiants"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Raccourci d'emote %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Le joueur touche le monstre"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Sujet : %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Nom : %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "Plan"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr ""
+#~ "/record > Commence à enregistrer la conversation dans un fichier externe"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Commande : /record <filename>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Cette commande active l'enregistrement de la conversation dans le fichier "
+#~ "<filename>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Commande : /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Cette commande termine une session d'enregistrement."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Présence inscrite dans le fichier d'enregistrement."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Fin de l'engistrement."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Pas d'enregistrement en cours."
+
+#~ msgid "Already recording."
+#~ msgstr "Enregistrement en cours."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Début de l'enregistrement..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Impossible de démarrer l'enregistrement."
+
+#~ msgid "Recording..."
+#~ msgstr "En cours d'enregistrement..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Arrêter l'enregistrement"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Trouver le chemin vers la souris"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "Vie :"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "PM :"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp :"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Argent : %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Habilité :"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Niveau : %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Création du groupe réussie."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Le message privé n'a pu être envoyé, le destinataire l'a ignoré."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Fichier de configuration à utiliser"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Fichier de configuration à utiliser"
+
+#~ msgid "Sound"
+#~ msgstr "Son"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Accès refusé"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Problème inconnu lors de la séléction du personnage"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Cette manière d'inviter n'est pas en place actuellement."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s vous a invité à rejoindre son groupe."
+
+#~ msgid "Willpower:"
+#~ msgstr "Volonté :"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Le serveur est plein"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Echange avec %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Message privé"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Être ami avec %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Négligé"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Complètement ignorer %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Inviter %s à rejoindre votre guilde@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Invitation de %s à joindre votre groupe@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Impossible de sortir la personne !"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Parler à %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Kick monster@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Ramasser"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Impossible d'envoyer une conversation vide !"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Impossible de deséquiper cet objet."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Ombre du texte"
+
+#~ msgid "Text Outline"
+#~ msgstr "Bordure du texte"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Texte des barres de progression"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Objet trop cher"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "L'objet est équipé"
+
+#~ msgid "GM"
+#~ msgstr "MJ"
+
+#~ msgid "Player"
+#~ msgstr "Joueur"
+
+#~ msgid "Whisper"
+#~ msgstr "Message privé"
+
+#~ msgid "Is"
+#~ msgstr "Est"
+
+#~ msgid "Server"
+#~ msgstr "Serveur"
+
+#~ msgid "Logger"
+#~ msgstr "Historique"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Type inconnu d'objet"
+
+#~ msgid "Generics"
+#~ msgstr "Génériques"
+
+#~ msgid "Hats"
+#~ msgstr "Chapeaux"
+
+#~ msgid "Usables"
+#~ msgstr "Utilisables"
+
+#~ msgid "Shirts"
+#~ msgstr "Chemises"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Armes à une main"
+
+#~ msgid "Pants"
+#~ msgstr "Pantalon"
+
+#~ msgid "Shoes"
+#~ msgstr "Chaussures"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Armes à une main"
+
+#~ msgid "Shields"
+#~ msgstr "Boucliers"
+
+#~ msgid "Rings"
+#~ msgstr "Anneaux"
+
+#~ msgid "Necklaces"
+#~ msgstr "Colliers"
+
+#~ msgid "Arms"
+#~ msgstr "Bras"
+
+#~ msgid "Ammo"
+#~ msgstr "Munitions"
+
+#~ msgid "HP Bar"
+#~ msgstr "Barre de vie (niveau maximum)"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 Barre de vie"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 Barre de vie"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 Barre de vie"
+
+#~ msgid "no"
+#~ msgstr "non"
+
+#~ msgid "Buddy"
+#~ msgstr "Contact"
+
+#~ msgid "Buddy List"
+#~ msgstr "Liste de contacts"
+
+#~ msgid "Description: %s"
+#~ msgstr "Description : %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effet : %s"
+
+#~ msgid "Previous"
+#~ msgstr "Précédent"
+
+#~ msgid "New"
+#~ msgstr "Nouveau"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Niveau de Compétences : %d"
+
+#~ msgid "Present: "
+#~ msgstr "Présent : "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Quitter la guilde"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Recent:"
+#~ msgstr "Récent :"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Jeter le sort d'essai 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Jeter le sort d'essai 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Jeter le sort d'essai 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Armes à deux mains"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Déséquiper@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Équiper@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Jeter@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Partager@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Magasin@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Sélectionner un serveur"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Impossible de passer à "
+
+#~ msgid "windowed"
+#~ msgstr "fenetré"
+
+#~ msgid "fullscreen"
+#~ msgstr "plein écran"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Aptitude mystérieuse"
+
+#~ msgid "Weapons"
+#~ msgstr "Armes"
+
+#~ msgid "Crafts"
+#~ msgstr "Metiers"
+
+#~ msgid "Stats"
+#~ msgstr "Statut"
+
+#~ msgid "Total"
+#~ msgstr "Total"
+
+#~ msgid "Cost"
+#~ msgstr "Coût"
+
+#~ msgid "Attack:"
+#~ msgstr "Attaque :"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Réflexe :"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Point(s) de statut restant(s) : %d"
+
+#~ msgid "curl error "
+#~ msgstr "Courbe d'erreur "
+
+#~ msgid " host: "
+#~ msgstr " hôte : "
+
+#~ msgid "Buddys"
+#~ msgstr "Contacts"
+
+#~ msgid "Party Window"
+#~ msgstr "Fenêtre de groupe"
+
+#~ msgid "Unarmed"
+#~ msgstr "Désarmé"
+
+#~ msgid "Knife"
+#~ msgstr "Couteau"
+
+#~ msgid "Sword"
+#~ msgstr "Épée"
+
+#~ msgid "Staff"
+#~ msgstr "Bâton"
+
+#~ msgid "Whip"
+#~ msgstr "Fouet"
+
+#~ msgid "Bow"
+#~ msgstr "Arc"
+
+#~ msgid "Shooting"
+#~ msgstr "Tirer"
+
+#~ msgid "Mace"
+#~ msgstr "Masse"
+
+#~ msgid "Axe"
+#~ msgstr "Hache"
+
+#~ msgid "Craft"
+#~ msgstr "Compétences"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Compétence inconnue"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr ""
+#~ " ne peut pas être créé, mais il n'existe pourtant pas ! Fermeture du "
+#~ "programme."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Impossibler d'assigner "
+
+#~ msgid " video mode: "
+#~ msgstr " mode d'affichage "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Connexion au serveur de personnages..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Connexion au serveur de comptes..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Alias de création"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Commande : /new <party-name>"
+
+#~ msgid "a"
+#~ msgstr "un(e)"
+
+#~ msgid "Unnamed"
+#~ msgstr "Aonyme"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Ramasser %s@@"
+
+#~ msgid "Unable to load selection.png"
+#~ msgstr "Impossible de charger le fichier selection.png"
+
+#~ msgid "Emote"
+#~ msgstr "Emote"
+
+#~ msgid "NPC Text Request"
+#~ msgstr "Requête de texte PNJ"
+
+#~ msgid "NPC Number Request"
+#~ msgstr "Requête de nombre PNJ"
+
+#~ msgid ""
+#~ "\n"
+#~ "> Cancel\n"
+#~ msgstr ""
+#~ "\n"
+#~ "> Annuler\n"
+
+#~ msgid "skills.xml"
+#~ msgstr "skills.xml"
+
+#~ msgid "use"
+#~ msgstr "Utiliser"
+
+#~ msgid "%s: %s"
+#~ msgstr "%s : %s"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Rayon du défilement"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Lenteur du défilement"
+
+#~ msgid "Slots: "
+#~ msgstr "Cases : "
+
+#~ msgid " -D --default : Bypass the login process with default settings"
+#~ msgstr ""
+#~ " -D --default : Bypasser le processus de connexion par la configuration "
+#~ "par défaut"
+
+#~ msgid " cancelled"
+#~ msgstr " annulé"
+
+#~ msgid "monsters.xml"
+#~ msgstr "monsters.xml"
+
+#~ msgid "items.xml"
+#~ msgstr "items.xml"
+
+#~ msgid "inc"
+#~ msgstr "inc"
+
+#~ msgid "; "
+#~ msgstr "; "
+
+#~ msgid "The Mana World %s"
+#~ msgstr "The Mana World %s"
diff --git a/po/he.po b/po/he.po
new file mode 100644
index 000000000..9d671e827
--- /dev/null
+++ b/po/he.po
@@ -0,0 +1,3973 @@
+# Hebrew translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2010-01-09 11:27+0000\n"
+"Last-Translator: hewhohasalongname <Unknown>\n"
+"Language-Team: Hebrew <he@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "הגדרות"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "מתחבר לשרת המפה..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "התחברות"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "בחר שחקן"
+
+#: src/client.cpp:768
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "מתחבר לשרת המפה..."
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "שגיאה"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "סיסמה:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "שנה"
+
+#: src/client.cpp:863
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "החבר קודם בהצלחה."
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "בטל רישום"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "שרת עדכון פגום: "
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr "שגיאה ביצירת ספריית העדכונים!"
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "פקודה לא מוכרת."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- עזרה --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "הצג תפריט עזרה זה <help/"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "הצג את שם המפה <where/"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "הצג את כמות המשתמשים המחוברים <who/"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "ספר על עצמך <me/"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "נקה את החלון <clear/"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "שלח הודעה פרטית למשתמש < msg/"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "נמען ההודעה < whisper/"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "נמען ההודעה <w/"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > יוצר לשונית עבור הודעות פרטיות עם משתמש אחר"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q > שם נוסף ל-query"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > הצג את כל החדרים הציבוריים"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/join > צור או הצטרף לחדר"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > צור חבורה חדשה"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "/party > הזמן משתמש לחבורה"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/record > התחל להקליט את השיחה לקובץ חיצוני"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > קובע אם <אנטר> סוגר את תיבת הטקסט של הצ'אט"
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr "/present > קבל את רשימת הנמצאים (ישלח לרישום, אם פעיל)"
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > הודעה גלובאלית (GM בלבד)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "למידע נוסף, הקלד /help <command>."
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "פקודה: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "פקודה זו מציגה רשימה של כל הפקודות האפשריות."
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "פקודה: /help <command>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "פקודה זו מציגה עזרה על <command>."
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "פקודה: /announce <msg>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** זמין ל-GM בלבד ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"This command sends the message <msg> to all players currently online.\r\n"
+"פקודה זו שולחת את ההודעה <msg> לכל השחקנים המחוברים."
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "פקודה: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "פקודה זו מנקה את רישום השיחה הקודמת."
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "פקודה: /item <policy>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "פקודה זו מציגה את מספר השחקנים המחוברים כרגע."
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "פקודה: /join <channel>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "פקודה זו מכניסה אותך אל <channel>."
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "אם <channel> אינו קיים, הוא נוצר."
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "פקודה: /list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "פקודה זו מציגה את רשימת כל החדרים."
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "פקודה: /me <message>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr "פקודה זו תאמר לאחרים שאתה (עושה) <msg>."
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "פקודה: /msg <nick> <message>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "פקודה: /whisper <nick> <message>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "פקודה: /w <nick> <message>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "פקודה זו שולחת את הטקסט <message> אל <nick>."
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "אם <nick> מכיל רווחים בתוכו, תחום אותו במרכאות כפולות (\")."
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "פקודה: /query <nick>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "פקודה: /q <nick>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr "הפקודה מנסה ליצור לשונית עבור מסרים בינך לבין <nick>."
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "פקודה: /create <party-name>"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "פקודות אלה יוצרות חבורה בשם <party-name>."
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "פקודה: /party <nick>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr "פקודה זו מזמינה את <nick> להיות בחבורתך."
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "פקודה: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+"פקודה זו מקבלת את רשימת המשתמשים המופיעים על המסך, ושולח אותה לרישום, אם "
+"הינך מקליט רישום, או אל השיחה."
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "פקודה: /record <filename>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr "פקודה זו מתחילה להקליט רישום שיחה לקובץ <filename>."
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "פקודה: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr "פקודה זו מסיימת תהליך הקלטה."
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr "פקודה: /toggle <state>"
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"הפקודה קובעת אם מקש האנטר יסגור את תיבת הטקסט של הצ'אט או שהוא ייסגר באופן "
+"אוטומטי."
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<state> יכול להיות אחד משני משני מצבים. \"1\", \"yes\", \"ture\" כדי לשנות "
+"למצב פעיל, או \"0\", no\", falst\" כדי לשנות למצב כבוי."
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr "פקודה: /toggle"
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr "הפקודה מציגה את מצב סגירת הטקסט האוטומטית."
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "פקודה: /item <policy>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "פקודה: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "פקודה זו מציגה את שם המפה הנוכחית."
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "פקודה: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "פקודה זו מציגה את מספר השחקנים המחוברים כרגע."
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "הקלד /help לרשימת הפקודות."
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr "לא ניתן לשלוח לחישות ריקות!"
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"לא ניתן ליצור לשונית לחישות עבור הכינוי \"%s\"! הלשונית כבר קיימת או שמדובר "
+"בך."
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "מבקש להצטרף לחדר %s."
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr "שם חבורה חסר."
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr "סגירת תיבת הטקסט האוטומטית."
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr "ההודעה סוגרת את תיבת הטקסט."
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr "מקש האנטר כעת סוגר את תיבת הטקסט."
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr "ההודעה כעת סוגרת את תיבת הטקסט."
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+#, fuzzy
+msgid "Player successfully ignored!"
+msgstr "חבורה נוצרה בהצלחה."
+
+#: src/commandhandler.cpp:486
+#, fuzzy
+msgid "Player could not be ignored!"
+msgstr "הלחישה לא יכלה להשלח, מהמשתמש מתעלם."
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "הלחישה לא יכלה להשלח, מהמשתמש מתעלם."
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"האפשרויות עבור /%s הינם \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "כללי"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "תמונת־מסך נשמרה במיקום ~/"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "שמירת תמונת־מסך נכשלה"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "החיבור לשרת נכשל, התוכנה תסגר כעת"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "שגיאת רשת"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr "מתעלם מהצעות סחר נכנסות"
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "מאשר הצעות סחר נכנסות"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "לא ניתן לטעון את המפה"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "שגיאה בעת טעינת %s"
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "חבורה (%s)"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "קנה"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "מחיר: %s / סה\"כ: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "יציאה"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "מקסימום"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "חנות"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "מכר"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "בטל"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "שנה כתובת דואר אלקטרוני"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "משתמש: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "הקלד כתובת דוא\"ל חדשה פעמיים:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "שם המשתמש חייב להכיל לפחות %d תוים."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "שם המשתמש חייב להכיל פחות מ-%d תוים."
+
+#: src/gui/changeemaildialog.cpp:141
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "כתובת הדוא\"ל החדשה כבר בשימוש."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "שנה סיסמה"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "סיסמה:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "הקלד סיסמה חדשה פעמיים:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "הסיסמה חייבת להכיל לפחות %d תוים."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "הסיסמה חייבת להכיל פחות מ-%d תוים."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "צור שחקן"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "שם:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "צבע שיער:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "תיספורת:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "צור"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "זכר"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "נקבה"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "אנא חלק %d נקודות"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "יש להכניס לפחות 4 תוים בשם."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "נתוני שחקן - אישור"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "אנא הסר %d נקודות"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "אשר מחיקת שחקן"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "האם אתה בטוח כי ברצונך למחוק את השחקן?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "ניהול משתמש ושחקן"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "בטל רישום"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "שנה כתובת דואר אלקטרוני"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "מחק"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "סגור"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "שיחה"
+
+#: src/gui/chat.cpp:287
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d משתמשים נוכחים."
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr "מקליט שמות נוכחים לרישום."
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "לוחש אל %s: %s"
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "כן"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "לא"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, fuzzy, c-format
+msgid "Music: %s"
+msgstr "כותרת: %s"
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "שם: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "חלון מיני מפה"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "אפקטים חלקיים"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "מידע חלקי"
+
+#: src/gui/debugwindow.cpp:121
+#, fuzzy, c-format
+msgid "Ambient FX: %s"
+msgstr "אופף FX"
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "לבוש"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "הורד"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "עזרה"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "סגור"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "ציוד"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "השתמש"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "השתמש"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "השלך"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "פצל"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr "בשימוש:"
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "משקל:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "השלך"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "אישור"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "הכל"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "בחר כמות חפצים לסחור."
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "בחר כמות חפצים להשליך."
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr "בחר כמות חפצים לאחסן."
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr "בחר כמות חפצים להחזיר."
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "בחר כמות חפצים לפצל."
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "משקל: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "התחברות"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "זכור שם משתמש"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "הרשם"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "שרת"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "מפה"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "ממתין לשרת"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "הבא"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr "שלח"
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "אפס"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "הבא"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr "אל:"
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "שלח"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "נכשלה השליחה מכיוון והשולח או המכתב בעלי שגיאה."
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "הורד"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "טקסט"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "הצללת טקסט"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr "מתאר הטקסט"
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr "תוויות סרגל התקדמות"
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "רקע"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr "הדגשה"
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr "לשונית הדגשה"
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "החפץ יקר מדי"
+
+#: src/gui/palette.cpp:94
+#, fuzzy
+msgid "Item Is Equipped"
+msgstr "החפץ בשימוש"
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr "GM"
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "שחקן"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr "לחישה"
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr "הינו"
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "חבורה"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr "גילדה"
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "שרת"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr "רישום"
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr "קישור"
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr "נהיה"
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "שמות המשתמשים האחרים"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr "השם שלך"
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "שמות המנהלים"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "דמויות"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "מפלצות"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr "סוג חפץ לא ידוע"
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr "כלליים"
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "כובעים"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr "שימושיים"
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "חולצות"
+
+#: src/gui/palette.cpp:119
+#, fuzzy
+msgid "One Handed Weapons"
+msgstr "נשקים ליד אחת"
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "מכנסיים"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "נעליים"
+
+#: src/gui/palette.cpp:122
+#, fuzzy
+msgid "Two Handed Weapons"
+msgstr "נשקים ליד אחת"
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "מגנים"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "טבעות"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "שרשראות"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr "ידיים"
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "תחמושת"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr "אפקטים חלקיים"
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr "הודעה על לקיחה"
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr "הודעה על נק' נסיון"
+
+#: src/gui/palette.cpp:133
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "משתמש מכה מפלצת"
+
+#: src/gui/palette.cpp:135
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "משתמש מכה משתמש"
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr "מכה קריטית"
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr "פספוס"
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr "סרגל חיים"
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr "3/4 סרגל חיים"
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr "1/2 סרגל חיים"
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr "1/4 סרגל חיים"
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "סוחר עם%s"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "התקפה %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "לחישה"
+
+#: src/gui/popupmenu.cpp:101
+#, fuzzy, c-format
+msgid "Befriend %s"
+msgstr "@@friend|הצע חברות %s@@"
+
+#: src/gui/popupmenu.cpp:106
+#, fuzzy, c-format
+msgid "Disregard %s"
+msgstr "מזלזל"
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "מתעלם"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, fuzzy, c-format
+msgid "Completely ignore %s"
+msgstr "@@ignore|התעלם לחלוטין %s@@"
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, fuzzy, c-format
+msgid "Invite %s to join your guild"
+msgstr "@@guild|הזמן את %s להצטרף לגילדה@@"
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "@@party|הזמן את %s להצטרף לחבורה@@"
+
+#: src/gui/popupmenu.cpp:144
+#, fuzzy
+msgid "Kick player"
+msgstr "העפה נכשלה!"
+
+#: src/gui/popupmenu.cpp:153
+#, fuzzy, c-format
+msgid "Talk to %s"
+msgstr "@@talk|דבר אל %s@@"
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "@@admin-kick|העף מפלצת@@"
+
+#: src/gui/popupmenu.cpp:174
+#, fuzzy
+msgid "Add name to chat"
+msgstr "@@name|הוסף שם לשיחה@@"
+
+#: src/gui/popupmenu.cpp:191
+#, fuzzy, c-format
+msgid "Pick up %s"
+msgstr "הרם"
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|הוסף לשיחה@@"
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr "אחסן"
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr "החזר"
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "החלף שרת"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "החלף שחקן"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr "מסיים להקליט."
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr "אינו מקליט כרגע."
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr "כבר מקליט."
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr "מתחיל להקליט..."
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr "שגיאה בהתחלת ההקלטה."
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr "מקליט..."
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr "מפסיק להקליט"
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "אשר:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "דוא\"ל:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "שם המשתמש חייב להכיל לפחות %d תוים."
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "שם המשתמש חייב להכיל פחות מ-%d תוים."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "הסיסמה חייבת להכיל לפחות %d תוים."
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "הסיסמה חייבת להכיל פחות מ-%d תוים."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "הסיסמאות אינן תואמות."
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "בחר את השרת שלך"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "שרת:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "פורט:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "שרת:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "מתחבר..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "סמן-עכבר מותאם"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "אנא הכנס גם את כתובת וגם את פורט השרת."
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "ממתין לשרת"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "צליל"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "שמע"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "עוצמת SFX"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "עוצמת מוזיקה"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "ללא טקסט"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr "כך הצבע נראה"
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "צבעים"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "סוג: "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr "סטטי"
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "פעימה"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "קשת בענן"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "מינסרה"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "עיכוב: "
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "אדום: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "ירוק: "
+
+#: src/gui/setup_colors.cpp:137
+#, fuzzy
+msgid "Blue:"
+msgstr "כחול: "
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "אשר"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "אתחל חלונות"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "לחץ על הכפתור בכדי להתחיל בכיול"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "כייל"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "אפשר ג'ויסטיק"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "ג'ויסטיק"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "עצור"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "סובב את המקל"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "מקלדת"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "שנה"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "ברירת מחדל"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr "נמצאו קונפליקטי מקשים."
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "שם"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr "התנהגות"
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "ניטרלי"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "חבר"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr "מזלזל"
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "מתעלם"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "אפשר מסחר"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr "אפשר לחישות"
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr "הכנס את כל הלחישות ללשוניות"
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "הצג שם"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "שחקנים"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr "כאשר מתעלם:"
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr "מזערי"
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "קטן"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "בינוני"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "גדול"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "ללא טקסט"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr "בועות, ללא שמות"
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr "בועות עם שמות"
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "כבוי"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "נמוך"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "גבוה"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "בינוני"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "מקסימלי"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "מסך מלא"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "‏OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "סמן-עכבר מותאם"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr "שמות גלויים"
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr "אפקטים חלקיים"
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "הצג שם"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr "הצג התרעת לקיחה"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr "בשיחה"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr "באופן חלקי"
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "הגבלת FPS:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "וידאו"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "הצג שם"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr "טקסט מעל הראש"
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "אטימות Gui"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr "אופף FX"
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "מידע חלקי"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "גודל הגופן"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "לא"
+
+#: src/gui/setup_video.cpp:381
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "מצב ושיחזור מצב ישן נכשלו!"
+
+#: src/gui/setup_video.cpp:387
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "מצב ושיחזור מצב ישן נכשלו!"
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "מחליף למסך מלא"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "נדרש איתחול כדי שהשינויים יהיו ברי-תוקף."
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "משנה OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "אישור שינויים עבור OpenGL דורש איתחול."
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "רזולוצית המסך השתנתה"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr "טען מחדש כדי שהשינוי יחול."
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "הגדרות השינוי החלקי השתנו."
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr "השינויים יחולו על שינוי המפה."
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "כישורים"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "למעלה"
+
+#: src/gui/skilldialog.cpp:262
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "נקודות כישורים: %d"
+
+#: src/gui/skilldialog.cpp:314
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "נקודות כישורים: %d"
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "כישורים"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "רמה: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "רמה: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "גילדה נוצרה."
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "צור גילדה"
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "האם אתה בטוח שברצונך לצאת?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > הזמן משתמש לחבורה"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > הזמן משתמש לחבורה"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "האם אתה בטוח שברצונך לצאת?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr "צור גילדה"
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "צור שחקן"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "הזמן משתמש"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "גדול"
+
+#: src/gui/socialwindow.cpp:394
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "אשר את ההזמנה של %s."
+
+#: src/gui/socialwindow.cpp:400
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "דחה את ההזמנה של %s."
+
+#: src/gui/socialwindow.cpp:413
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "אשר את ההזמנה של %s."
+
+#: src/gui/socialwindow.cpp:419
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "דחה את ההזמנה של %s."
+
+#: src/gui/socialwindow.cpp:463
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "שגיאה ביצירת גילדה."
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "גילדה"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "בחר את השרת שלך"
+
+#: src/gui/socialwindow.cpp:497
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "התקבלה הזמנה לחבורה, אך הזמנה זהה כבר קיימת."
+
+#: src/gui/socialwindow.cpp:502
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s הזמין אותך להצטרף לחבורת %s."
+
+#: src/gui/socialwindow.cpp:507
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "אשר את הזמנת חבורה"
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr "התקבלה הזמנה לחבורה, אך הזמנה זהה כבר קיימת."
+
+#: src/gui/socialwindow.cpp:529
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s הזמין אותך לחבורה שלהם."
+
+#: src/gui/socialwindow.cpp:533
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s הזמין אותך להצטרף לחבורת %s."
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s הזמין אותך לחבורה שלהם."
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s הזמין אותך להצטרף לחבורת %s."
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr "אשר את הזמנת חבורה"
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "חבורה"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "בחר את השרת שלך"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "רמה: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "כסף: %s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr "חיים:"
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr "נסיון:"
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr "קסם:"
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr "עבודה: %d"
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr "עבודה:"
+
+#: src/gui/statuswindow.cpp:194
+#, fuzzy
+msgid "HP"
+msgstr "חיים:"
+
+#: src/gui/statuswindow.cpp:200
+#, fuzzy
+msgid "MP"
+msgstr "קסם:"
+
+#: src/gui/statuswindow.cpp:206
+#, fuzzy
+msgid "Exp"
+msgstr "נסיון:"
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "זהב: %d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "עבודה:"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "נתוני שחקן - אישור"
+
+#: src/gui/statuswindow.cpp:235
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "נקודות כישורים: %d"
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "רמה: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr "איחסון"
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "מציע לחור"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr "אושר. ממתין..."
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr "הסכם למסחר"
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr "מוסכם. ממתין..."
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr "סחור: אתה"
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "סחרר"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "הוסף"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "אתה מקבל %s."
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "אתה נותן:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "שנה"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr "הוספת הפריט נכשלה. לא ניתן להכניס מעל חפץ אחד לחלון."
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "אין לך מספיק כסף."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "שם: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "מעדכן..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "מתחבר..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr "שחק"
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr "##1 תהליך העדכון לא תם."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr "##1 מומלץ ביותר שתנסה שוב מאוחר יותר"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "-"
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "הסתיים"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > רשימת המשתמשים בחדר הנוכחי"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > קבע את כותרת נושא החדר"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit >עזוב את החדר"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > הפוך משתמש למנהל החדר"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > העף משתמש מהחדר"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "פקודה: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "פקודה זו מציגה את המשתמשים בחדר."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "פקודה: /topic <message>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "פקודה זו מציבה את <message> ככותרת נושא החדר."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "פקודה: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "הפקודה מוציאה אותך מהחדר הנוכחי."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "אם הינך האדם האחרון בחדר, הוא יימחק."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "פקודה: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "פקודה זו הופכת את <nick> למנהל החדר."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr "מנהלי חדר יכולים להעיף משתמשים ולהפוך משתמשים אחרים בחדר למנהלים."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "פקודה: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "פקודה זו גורמת ל-<nick> לעזוב את החדר."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "צריך משתמש שינהל!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "צריך משתמש שיעיף!"
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "הודעה גלובאלית:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "הודעה גלובאלית מאת %s:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s: לוחש: "
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr "לא ניתן לשלוח הודעה ריקה!"
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr "/close > סוגר את לשונית הלחישות"
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr "פקודה: /close"
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr "הפקודה סוגרת את לשונית הלחישות הנוכחית."
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "פקודה: /item"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "פקודה זו מציגה את מספר השחקנים המחוברים כרגע."
+
+#: src/gui/widgets/whispertab.cpp:94
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "פקודה זו מתחילה להקליט רישום שיחה לקובץ <filename>."
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "מצב"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "קיצור־דרך"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "בחר אישור"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "שנה"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "בחר את השרת שלך"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr "הזז למעלה"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr "הזז למטה"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr "הזז שמאלה"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr "הזז ימינה"
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr "תקוף"
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr "כוון ותקוף"
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr "חייך"
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr "דבר"
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr "הפסק לתקוף"
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "כוון לקרוב ביותר"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr "כוון לדמות"
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr "כוון לשחקן"
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr "הרם"
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr "הסתר חלונות"
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr "שב"
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "תמונת־מסך"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr "אפשר/בטל מסחר"
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr "מצא נתיב לעכבר"
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "קיצור־דרך לחפץ %d"
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr "חלון עזרה"
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr "חלון מצב"
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr "חלון ציוד"
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr "חלון לבוש"
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr "חלון כישורים"
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr "חלון מיני מפה"
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr "חלון שיחה"
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr "חלון קיצור־דרך לחפץ"
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr "חלון הגדרות"
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr "חלון ניפוי"
+
+#: src/keyboardconfig.cpp:80
+#, fuzzy
+msgid "Social Window"
+msgstr "חלון כישורים"
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr "חלון קיצור־דרך לרגישון"
+
+#: src/keyboardconfig.cpp:82
+#, fuzzy
+msgid "Outfits Window"
+msgstr "חלון מצב"
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "קיצור־דרך לריגשון %d"
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr "סגירת הצ'אט"
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr "גלול שיחה למעלה"
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr "גלול שיחה למטה"
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr "לשונית השיחה הקודמת"
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr "לשונית השיחה הבאה"
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr "בחר אישור"
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr "קלט התעלמות 1"
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr "קלט התעלמות 2"
+
+#: src/keyboardconfig.cpp:178
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "פתור אותם, אחרת המשחק עלול להתנהג באופן מוזר."
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr "לא ניתן להרים את החפץ."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "הרמת %s [@@%d|%s@@]."
+msgstr[1] "הרמת %s [@@%d|%s@@]."
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr "אפשרויות:"
+
+#: src/main.cpp:45
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Display the version"
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Display this help"
+
+#: src/main.cpp:47
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Configuration file to use"
+
+#: src/main.cpp:48
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Login with this username"
+
+#: src/main.cpp:49
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Login with this password"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Login with this character"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Login server name or IP"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Login server port"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Use this update host"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Choose default character server and character"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Skip the update downloads"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Directory to load game data from"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Directory to use as home directory"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Directory to use as home directory"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Disable OpenGL for this session"
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr "העפה נכשלה!"
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr "העפה הצליחה!"
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr "אין מה למכור."
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr "תודה על הקנייה."
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr "לא ניתן לקנות."
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr "תודה על המכירה."
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr "לא ניתן למכור."
+
+#: src/net/ea/charserverhandler.cpp:103
+#, fuzzy
+msgid "Access denied."
+msgstr "הגישה נדחתה"
+
+#: src/net/ea/charserverhandler.cpp:106
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "לא ניתן להשתמש ב-ID זה."
+
+#: src/net/ea/charserverhandler.cpp:109
+#, fuzzy
+msgid "Unknown failure to select character."
+msgstr "שגיאה לא ידועה בבחירת השחקן"
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "נכשל ביצירת השחקן. ייתכן כי שם זה כבר תפוס."
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr "מידע"
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr "השחקן נמחק."
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr "נכשל במחיקת השחקן."
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "עוצמה:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "זריזות:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "חיוניות:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "תבונה:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "מיומנות:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr "מזל:"
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr "הלחישה לא יכלה להשלח, המשתמש אינו מחובר."
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr "הלחישה לא יכלה להשלח, מהמשתמש מתעלם."
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "שחקן"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr "חדרים אינם נתמכים!"
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "שם"
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "בקשה למסחר"
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr "עוצמה %+d"
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr "זריזות %+d"
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr "חיוניות %+d"
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr "תבונה %+d"
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr "מיומנות %+d"
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr "מזל %+d"
+
+#: src/net/ea/generalhandler.cpp:130
+#, fuzzy
+msgid "Authentication failed."
+msgstr "האימות נכשל"
+
+#: src/net/ea/generalhandler.cpp:133
+#, fuzzy
+msgid "No servers available."
+msgstr "אין שרתים זמינים"
+
+#: src/net/ea/generalhandler.cpp:137
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "אדם אחר מנסה להשתמש בחשבון זה"
+
+#: src/net/ea/generalhandler.cpp:140
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "חשבון זה כבר מחובר"
+
+#: src/net/ea/generalhandler.cpp:143
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "פריצת מהירות זוהתה"
+
+#: src/net/ea/generalhandler.cpp:146
+#, fuzzy
+msgid "Duplicated login."
+msgstr "התחברות כפולה"
+
+#: src/net/ea/generalhandler.cpp:149
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "שגיאת חיבור לא ידועה"
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr "נותקת מהשרת!"
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "עוצמה"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "זריזות"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "חיוניות"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "תבונה"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "מיומנות"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "מזל"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "הגנה:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "התקפת קסם:"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "הגנת קסם:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% דיוק:"
+
+#: src/net/ea/generalhandler.cpp:228
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% התחמקות:"
+
+#: src/net/ea/generalhandler.cpp:229
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "מכה קריטית"
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr "/help > מציג עזרה זו."
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > הזמן שחקן לחבורה שלך"
+
+#: src/net/ea/gui/guildtab.cpp:63
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > עזוב את החבורה בה אתה נמצא"
+
+#: src/net/ea/gui/guildtab.cpp:64
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > העף מישהו מהחבורה בה אתה נמצא"
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr "פקודה: /invite <nick>"
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "פקודה זו מזמינה את <nick> להיות בחבורתך."
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr "פקודה: /leave"
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "פקודה זו גורמת לשחקן לעזוב את החבורה."
+
+#: src/net/ea/gui/guildtab.cpp:89
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "שם חבורה חסר."
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s הצטרף לחבורה."
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "תגובה לא ידועה להזמנה עבור %s."
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > הזמן שחקן לחבורה שלך"
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > עזוב את החבורה בה אתה נמצא"
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > העף מישהו מהחבורה בה אתה נמצא"
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > הצג/שנה את אפשרויות השיתוף של חפץ בחבורה"
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > הצג/שנה את אפשרויות שיתוף הנסיון בחבורה"
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr "פקודה זו גורמת לשחקן לעזוב את החבורה."
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr "פקודה: /item <policy>"
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr "הפקודה משנה את מדיניות השיתוף של חפצים בחבורה."
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<policy> יכול להיות אחד מ- \"1\", \"yes\", \"true\" כדי לאפשר שיתוף חפץ, או "
+"\"0\", \"no\", \"false\" כדי לבטל שיתוף חפץ."
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr "פקודה: /item"
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr "הפקודה מציגה את מדיניות השיתוף של חפצים בחבורה."
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr "פקודה: /exp <policy>"
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr "פקודה זו משנה את מדיניות שיתוף הנסיון בחבורה."
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<policy> יכול להיות \"1\", \"yes\", \"true\" כדי לאפשר שיתוף נסיון, או \"0"
+"\", \"no\", \"false\" כדי לבטל שיתוף נסיון."
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr "פקודה: /exp"
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr "פקודה זו מציגה את מדיניות שיתוף הנסיון הנוכחית בחבורה."
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr "שיתוף חפצים מאופשר."
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr "שיתוף חפצים מבוטל."
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr "שיתוף חפצים לא אפשרי."
+
+#: src/net/ea/gui/partytab.cpp:141
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "שיתוף חפצים מאופשר."
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr "שיתוף נסיון מאופשר."
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr "שיתוף נסיון מבוטל."
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr "שיתוף נסיון לא אפשרי."
+
+#: src/net/ea/gui/partytab.cpp:176
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "שיתוף נסיון מאופשר."
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr "נכשל בשימוש בחפץ."
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr "לא ניתן ללבוש."
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr "לא ניתן להסיר."
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr "החשבון לא נמצא. אנא נסה להתחבר שנית."
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "הסיסמה הישנה שגויה"
+
+#: src/net/ea/loginhandler.cpp:85
+#, fuzzy
+msgid "New password too short."
+msgstr "הסיסמה החדשה קצרה מדי"
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "שגיאה לא ידועה"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "ID לא רשום"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "סיסמה שגויה"
+
+#: src/net/ea/loginhandler.cpp:155
+#, fuzzy
+msgid "Account expired."
+msgstr "המשתמש מושהה"
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "הועפת מהשרת"
+
+#: src/net/ea/loginhandler.cpp:161
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "הורחקת לצמיתות מן המשחק. אנא צור קשר עם צוות המנהלים."
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"הורחקת זמנית מן המשחק עד %s.\n"
+"אנא צור קשר עם צוות המנהלים באמצעות מערכת הפורומים."
+
+#: src/net/ea/loginhandler.cpp:172
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "שם המשתמש כבר נלקח"
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "לא ניתן למכור."
+
+#: src/net/ea/network.cpp:414
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "מתחבר לשרת המפה..."
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr "לא היה ניתן ליצור חבורה."
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr "חבורה נוצרה בהצלחה."
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s כבר חבר בחבורה."
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s דחה את הזמנתך."
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s הצטרף לחבורה."
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr "תגובה לא ידועה להזמנה עבור %s."
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr "עזבת את החבורה."
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr "%s עזב את החבורה שלך."
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "משתמש לא ידוע ניסה לומר: %s"
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr "הזמנה בדרך זו אינה נתמכת כרגע."
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s אינו נמצא בחבורתך!"
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr "אתה מת."
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "צר לנו לבשר לכם כי שחקנכם נהרג בקרב."
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr "אינך חי כל־כך כרגע."
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "קור ידיו של המוות הקודר אוחזים בנשמתך."
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr "המשחק נגמר!"
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr "הכנס מטבע כדי להמשיך."
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr "לא, ילדים. השחקן שלכם לא באמת מת. הוא... אה... הלך למקום טוב יותר."
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr "תוכניתך לשבור את נשק האויב באמצות צווארך נכשלה."
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr "אני מניח שלא הלך לך כל־כך טוב."
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr "האם ברצונך שיאתרו את חלקי גופתך?"
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr "באופן מצער, מעולם לא נמצא זכר ממך..."
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr "הושמדתך."
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr "נראה כאילו ראשך נמסר אליך."
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "פישלת שוב, גופתך תיזרק לצינוק ותקבל אחת חדשה."
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr "אינך מת עדיין. אתה רק נח."
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr "אינך יותר."
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr "חדלת מלהתקיים."
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr "התפוגגת ועברת לפגוש את הבורא."
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr "אינך מת עדיין. אתה רק נח."
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr "נטול חיים, את נח על משכבך."
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "אתה לא מת עדיין! אה.. טוב, עכשיו כן."
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr "חילוף החומרים שלך הפך להיסטוריה."
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr "אתה מכה כמו גופה."
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr "חדלת מלהתקיים."
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr "התפוגגת ועברת לפגוש את הבורא."
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr "הינך שחקן לשעבר."
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr "אתה מת. טוב שיש חברת ביטוח..."
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr "הודעה"
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "אתה סוחב יותר מחצי ממשקלך. אינך יכול לאחות את החיים."
+
+#: src/net/ea/playerhandler.cpp:333
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "הרמת "
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr "הצטייד בחצים תחילה."
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr "המסחר נכשל!"
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr "הבעה נכשלה!"
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr "הישיבה נכשלה!"
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr "יצירת שיחה נכשלה!"
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr "לא היה ניתן להצטרף לחגיגה!"
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr "לא ניתן לצעוק!"
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr "לא הגעת לרמה גבוהה מספיק!"
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr "לא נותרו נק' חיים!"
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr "לא נותרו נק' קסם!"
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr "אין תזכירים!"
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr "אינך יכול לעשות זאת כרגע!"
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr "נראה שאתה צריך עוד כסף... ;-)"
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "אינך יכול להשתמש בכישור עם נשק זה!"
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr "אתה צריך עוד אבן אדומה!"
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr "אתה צריך עוד אבן כחולה!"
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr "אתה סוחב יותר מדי בכדי לעשות זאת!"
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr "הא? מה זה?"
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr "הפיתול נכשל...."
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr "לא היה ניתן לגנוב דבר..."
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr "לרעל לא הייתה כל השפעה..."
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr "בקשה למסחר"
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s מעוניין לסחור עימך, האם אתה מסכים?"
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "מסחר אינו אפשרי. השותף למסחר רחוק מדי."
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "מסחר אינו אפשרי. השחקן אינו קיים."
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr "המסחר בוטל מסיבה לא ידועה."
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr "מסחר: אתה ו-%s"
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "המסחר עם %s בוטל."
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr "המסחר נכשל"
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "נכשל בהוספת חפץ. השותף למסחר שוקל יותר מדי."
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "נכשל בהוספת חפץ. לשותף למסחר אין מקומות פנויים."
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr "נכשל בהוספת חפץ מסיבה לא ידועה."
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr "המסחר בוטל."
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr "המסחר הושלם."
+
+#: src/net/manaserv/beinghandler.cpp:324
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " לחץ אישור כדי להשיב"
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "נהרגת"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+#, fuzzy
+msgid "Not logged in."
+msgstr "כבר מחובר"
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "שם המשתמש כבר בשימוש"
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "נתוני שחקן - אישור"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "נתוני שחקן - אישור"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+#, fuzzy
+msgid "Player deleted."
+msgstr "השחקן נמחק."
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "בחר כמות חפצים לסחור."
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "שגיאה לא ידועה"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr "אין שרתי משחק זמינים."
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "כח רצון:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr "כותרת: %s"
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "משתמש מכה מפלצת"
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "פקודה: /join <channel>"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Listing channels."
+msgstr "מבקש להצטרף לחדר %s."
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s הצטרף לחבורה."
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "פקודה לא מוכרת."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr "כח רצון %+d"
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "כח רצון:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr "גילדה נוצרה."
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr "שגיאה ביצירת גילדה."
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr "הזמנה נשלחה."
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr "החבר קודם בהצלחה."
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr "נכשל בקידום החבר."
+
+#: src/net/manaserv/loginhandler.cpp:87
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "magic_token שגוי"
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+#, fuzzy
+msgid "Already logged in."
+msgstr "כבר מחובר"
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+#, fuzzy
+msgid "Server is full."
+msgstr "השרת מלא"
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "הסיסמה החדשה שגויה"
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr "החשבון אינו מחובר. אנא קודם־כל התחבר."
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "כתובת דוא\"ל חדשה שגויה"
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "כתובת דוא\"ל ישנה שגויה"
+
+#: src/net/manaserv/loginhandler.cpp:158
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "כתובת הדוא\"ל החדשה כבר בשימוש."
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+#, fuzzy
+msgid "Client version is too old."
+msgstr "גרסת הקליינט ישנה מדי"
+
+#: src/net/manaserv/loginhandler.cpp:266
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "שם משתמש או סיסמה שגויים"
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "שם משתמש, סיסמה או דוא\"ל שגויים"
+
+#: src/net/manaserv/loginhandler.cpp:306
+#, fuzzy
+msgid "Username already exists."
+msgstr "שם המשתמש כבר בשימוש"
+
+#: src/net/manaserv/loginhandler.cpp:309
+#, fuzzy
+msgid "Email address already exists."
+msgstr "כתובת הדוא\"ל כבר בשימוש"
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr "הצטרפת לחבורה."
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr "%s הצטרף לחבורה."
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s דחה את הזמנתך."
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr "מקבל בקשות מסחר נכנסות."
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr "מתעלם מבקשות סחר נכנסות."
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr "סוחר עם%s"
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|התעלם לחלוטין %s@@"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "התקפה %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "הגנה %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "חיים %+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr "חפץ לא ידוע"
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr "ללא שם"
+
+#~ msgid "no"
+#~ msgstr "לא"
+
+#~ msgid "Buddy"
+#~ msgstr "חבר"
+
+#~ msgid "Buddy List"
+#~ msgstr "רשימת חברים"
+
+#~ msgid "Description: %s"
+#~ msgstr "תיאור: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "השפעה: %s"
+
+#~ msgid "Previous"
+#~ msgstr "הקודם"
+
+#~ msgid "New"
+#~ msgstr "חדש"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "רמת עבודה: %d"
+
+#~ msgid "Present: "
+#~ msgstr "נוכחים: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "עזוב גילדה"
+
+#~ msgid "Ok"
+#~ msgstr "אישור"
+
+#~ msgid "Recent:"
+#~ msgstr "לאחרונה:"
+
+#~ msgid "Magic"
+#~ msgstr "קסם"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "הטל קסם נסיון 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "הטל קסם נסיון 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "הטל קסם נסיון 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "נשקים לשתי ידיים"
+
+#~ msgid "@@trade|Trade With %s@@"
+#~ msgstr "@@trade|סחור עם %s@@"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@attack|תקוף את %s@@"
+
+#~ msgid "@@disregard|Disregard %s@@"
+#~ msgstr "@@disregard|זלזל %s@@"
+
+#~ msgid "@@ignore|Ignore %s@@"
+#~ msgstr "@@ignore|התעלם %s@@"
+
+#~ msgid "@@unignore|Un-Ignore %s@@"
+#~ msgstr "@@unignore|אל-התעלם %s@@"
+
+#~ msgid "@@admin-kick|Kick player@@"
+#~ msgstr "@@admin-kick|העף שחקן@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@cancel|ביטול@@"
+
+#~ msgid "@@pickup|Pick up %s@@"
+#~ msgstr "@@pickup|הרם %s@@"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|הפשט@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|השתמש@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@use|Use@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|השלך@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|פצל@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|אחסן@@"
+
+#~ msgid "@@retrieve|Retrieve@@"
+#~ msgstr "@@retrieve|החזר@@"
+
+#~ msgid "Select Server"
+#~ msgstr "בחר שרת"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "נכשל במעבר אל "
+
+#~ msgid "windowed"
+#~ msgstr "חלון"
+
+#~ msgid "fullscreen"
+#~ msgstr "מסך מלא"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "כישור מיסתורי"
+
+#~ msgid "Weapons"
+#~ msgstr "נשקים"
+
+#~ msgid "Crafts"
+#~ msgstr "מלאכה"
+
+#~ msgid "Stats"
+#~ msgstr "רמות"
+
+#~ msgid "Total"
+#~ msgstr "סה\"כ"
+
+#~ msgid "Cost"
+#~ msgstr "עלות"
+
+#~ msgid "Attack:"
+#~ msgstr "התקפה:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% ריפלקס:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "נקודות מצב נותרות: %d"
+
+#~ msgid "Max level"
+#~ msgstr "רמה מקסימלית"
+
+#~ msgid "curl error "
+#~ msgstr "שגיאת קיפולים: "
+
+#~ msgid " host: "
+#~ msgstr " שרת מארח: "
+
+#~ msgid "Guilds"
+#~ msgstr "גילדות"
+
+#~ msgid "Buddys"
+#~ msgstr "חברים"
+
+#~ msgid "Party Window"
+#~ msgstr "חלון חבורה"
+
+#~ msgid "Unarmed"
+#~ msgstr "ללא תחמושת"
+
+#~ msgid "Knife"
+#~ msgstr "סכין"
+
+#~ msgid "Sword"
+#~ msgstr "חרב"
+
+#~ msgid "Polearm"
+#~ msgstr "נשק מוט"
+
+#~ msgid "Staff"
+#~ msgstr "מקל"
+
+#~ msgid "Whip"
+#~ msgstr "שוט"
+
+#~ msgid "Bow"
+#~ msgstr "קשת"
+
+#~ msgid "Shooting"
+#~ msgstr "ירייה"
+
+#~ msgid "Mace"
+#~ msgstr "שרביט"
+
+#~ msgid "Axe"
+#~ msgstr "גרזן"
+
+#~ msgid "Thrown"
+#~ msgstr "זריקה"
+
+#~ msgid "Craft"
+#~ msgstr "מלאכה"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "כישור לא ידוע"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " can't be created, but it doesn't exist! Exiting."
+
+#~ msgid "Couldn't set "
+#~ msgstr "לא ניתן להגדיר "
+
+#~ msgid " video mode: "
+#~ msgstr " מצב וידאו: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "מתחבר לשרת השחקן..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "מתחבר לשרת החשבון..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > שם נוסף ל-create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "פקודה: /new <party-name>"
+
+#~ msgid "a"
+#~ msgstr "‎"
+
+#~ msgid "Unnamed"
+#~ msgstr "ללא שם"
+
+#~ msgid "Scroll radius"
+#~ msgstr "תווך גלילה"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "עצלנות גלילה"
diff --git a/po/hr.po b/po/hr.po
new file mode 100644
index 000000000..9186f832d
--- /dev/null
+++ b/po/hr.po
@@ -0,0 +1,5665 @@
+# Croatian translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2009-12-13 09:30+0000\n"
+"Last-Translator: nafterburner <nafterburner@gmail.com>\n"
+"Language-Team: Croatian <hr@li.org>\n"
+"Language: hr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Podešavanje"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Spajanje na poslužitelja karti..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Korisničko ime"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Odaberi lika"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Spajanje na poslužitelja karti..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Server"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Greška"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Lozinka"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Izmijeni"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Član je uspješno unaprijeđen."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Odjavi"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Nepoznata naredba."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Pomoć --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Prikaži ovu pomoć"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Prikaži ime karte"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Prikaži broj trenutno prijavljenih korisnika"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Recite nešto o sebi"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Očisti ovaj prozor"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Pošaljite privatnu poruku korisniku"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alias za msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Alias za msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Čini karticu za privatne poruke s drugim korisnikom"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Alias od query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Zatvara karticu za šaptaje"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Zanemari %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Prikaži sve javne kanale"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Pridruži se ili napravi kanal"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Napravi novu partiju"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Napravi novu partiju"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Pozovite korisnike na partiju"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Globalna obavijest (samo GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Zatvara karticu za šaptaje"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Pošaljite privatnu poruku korisniku"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Za više informacija, utipkajte /pomoć <naredba>."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Naredba: /pomoć"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Ova naredba prikazuje listu svih raspoloživih naredbi."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Naredba: /pomoć <naredba>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Ova naredba prikazuje pomoć pri <naredba>."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Command: /announce <msg>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** dostupno samo za GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Ova naredba šalje poruku <msg> svim igračima trenutno online."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Naredba: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Ova naredba briše chat log prethodnog chata."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Naredba: /item <policy>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Ova naredba prikazuje broj igrača trenutno online."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Naredba: /join <channel>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Ova naredba vas unaša u <channel>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Ako <channel> ne postoji, onda je napravljen."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Naredba: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Ova naredba prikazuje listu svih kanala."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Naredba: /me <message>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Ova naredba govori drugima da vi (radite) <msg>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Naredba: /msg <nick> <message>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Naredba: /whisper <nick> <message>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Naredba: /w <nick> <message>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Ova naredba šalje tekst <message> za <nick>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Ako <nick> ima razmake u sebi, zatvoriti ga u dvostrukim navodnicima (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Naredba: /query <nick>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Naredba: /q <nick>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Ova naredba pokušava napraviti karticu za šaptanje između vas i <nick>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Naredba: /w <nick> <message>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Naredba: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Ova naredba postavlja temu za <message>."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Naredba: /create <ime-partije>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Ove naredbe kreira novu partiju zvanu <party-name>."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Naredba: /create <ime-partije>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Ove naredbe kreira novu partiju zvanu <party-name>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Naredba: /party <nick>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Ova naredba poziva <nick> na partiju sa vama."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Naredba: /present"
+
+#: src/commandhandler.cpp:443
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Naredba: /toggle <state>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Naredba: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Naredba: /item <policy>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Naredba: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Ova naredba prikazuje naziv trenutne karte."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Naredba: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Ova naredba prikazuje broj igrača trenutno online."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Upišite /help za listu svih naredbi."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Ne mogu poslati prazan šapate!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Ne mogu stvoriti šapat karticu za nadimak \"%s\"! To već postoji ili ste to "
+"vi."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Zahtjev za pridruživanje kanalu %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Ime partije nedostaje."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Ime partije nedostaje."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Poruka zatvara chat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Poruka sada zatvara chat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Prijatelj"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Zanemareno"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutralno"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Šapat nije mogao biti poslan, ignorirani ste od strane korisnika."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Partija je uspješno kreirana."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Šapat nije mogao biti poslan, ignorirani ste od strane korisnika."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Šapat nije mogao biti poslan, ignorirani ste od strane korisnika."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Šapat nije mogao biti poslan, ignorirani ste od strane korisnika."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Partija je uspješno kreirana."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Šapat nije mogao biti poslan, ignorirani ste od strane korisnika."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr "Opcije za /%s su \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Općenito"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Screenshot spremljen u ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Spremanje screenshot-a nije uspjelo!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Veza s poslužiteljem je bila izgubljena, program će se sada zatvoriti"
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Mreža Greška"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignoriranje dolaznih zahtjeva za trgovanje"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Prihvaćanje dolaznih zahtjeva za trgovanje"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Ne mogu učitati karte"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Greška prilikom učitavanja %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Partija (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Cehovi"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Chat Prozor"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Ime"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Napad"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Govori"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Pomakni Gore"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Poništi"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Kupi"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Cijena: %s / Ukupno: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Izlaz"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Max"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Trgovina"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Prodaj"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Poništi"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Promijeni Email Adresu"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Korisnički račun: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Utipkajte Novu Email Adresu dvaput:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Korisničko ime mora biti dugo najmanje %d znakova."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Korisničko ime mora biti kraće od %d znakova."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Nova E-mail Adresa već postoji."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Promijeni Lozinku"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Lozinka"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Utipkajte Novu Lozinku dvaput:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Lozinka mora biti duga najmanje %d znakova."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Lozinka mora biti kraća od %d znakova."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Stvori Lika"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Ime:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Boja kose:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Frizura:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Stvori"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Muško"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Žensko"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Molimo, rasporedi %d bodova"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Ime mora imati barem 4 znaka."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Podaci lika su u redu"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Molimo, oduzmi %d bodova"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Potvrdi Brisanje Lika"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Da li ste sigurni da želite obrisati ovog lika?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Upravljanje Računom i Likovima"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Odjavi"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Promijeni Email Adresu"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Obriši"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Zatvori"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Zadano"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Prijatelj"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Zelena: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Plava: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "nisko"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Hiperveza"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+msgid "brown"
+msgstr ""
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Duga"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Duga"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Duga"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d igrača je prisutno."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Šaptaj prema %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Da"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Ne"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignorirano"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Tema: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Ime: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Prozor Minikarte"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Efekti Čestica"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Podaci lika su u redu"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Igrač pogađa Čudovište"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Pomakni Ulijevo"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Ciljaj Igrača"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Ciljaj Igrača"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Ciljaj Igrača"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Ciljaj Igrača"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Vlastiti kursor"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "U redu"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Oprema"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Skini opremu"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Pomoć"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Zatvori"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Zalihe"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Pohrana"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Mjesta:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Opremi"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Upotrijebi"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Ispusti"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Razdvoji"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Težina:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Pohrani"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Preuzmi"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Ispusti"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Sve"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Odaberi količinu predmeta za razmjenu."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Odaberi količinu predmeta za ispuštanje."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Odaberite količinu predmeta za spremanje."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Odaberite iznos predmeta za preuzimanje."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Odaberi količinu predmeta za razdvajanje."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Nepoznata greška"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Težina: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Prozor Statusa"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Poništi"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Poništi"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Nivo: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Pomakni Ulijevo"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Zatvori"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Korisničko ime"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Poslužitelj:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Zapamti korisničko ime"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registriraj se"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Karta"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Čekanje servera"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Slijedeći"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Dostavi"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Zatvori"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Slijedeći"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Za:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Pošalji"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Neuspjelo slanje kao pošiljatelj ili nevažeće pismo."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Novac: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Skini opremu"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Razmijeni se s %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Napadni %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Upotrijebi@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Otkaži@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Preuzmi@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Zanemari %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignoriraj %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Upotrijebi@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Prestani Ignorirati %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Potpuno ignoriraj %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Pozovite korisnike na partiju"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Šutni igrača@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Šutni igrača@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Pozovite korisnike na partiju"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Šutni igrača@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Prestani Ignorirati %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Upotrijebi@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Napadni %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Šutni igrača@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Dodaj ime u chat@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Otkaži@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Pokupi %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Dudaj u chat@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Upotrijebi@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Istakni Karticu"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Istakni Karticu"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Izmijeni"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Pohrani"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Pohrani"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Pohrani"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Preuzmi"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Preuzmi"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Preuzmi"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Dudaj u chat@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Promijeni poslužitelj"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Promijeni lika"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Potvrdi:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "E-pošta:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Korisničko ime mora biti dugo najmanje %d znakova."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Korisničko ime mora biti kraće od %d znakova."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Lozinka mora biti duga najmanje %d znakova."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Lozinka mora biti kraća od %d znakova."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Lozinke se ne podudaraju."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Izaberite vaš server"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Poslužitelj:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Spajanje..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Vlastiti kursor"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Molimo upišite adresu poslužitelja i port poslužitelja."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Čekanje servera"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Omogući igraću palicu"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Omogući igraću palicu"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Zvuk"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Glasnoća zvučnih efekata"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Glasnoća glazbe"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Nema teksta"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Ne može se kupiti"
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Ne može se kupiti"
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Prikaži ime"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Ovako izgleda boja"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Boje"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Tip: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statično"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulsiranje"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Duga"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Spektar"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Odgoda: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Crvena: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Zelena: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Plava: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Primjeni"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Ponovno pokreni prozore"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Pritisnite tipku za početak kalibracije"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Kalibriraj"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Omogući igraću palicu"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Igraća palica"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Zaustavi"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Kružite palicom"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Tipkovnica"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Dodijeli"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Dodijeli"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Zadano"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Otkriven je Konflikt(i) Tipki."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Istakni"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Prikaži ime"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Omogući igraću palicu"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Istakni"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Omogući/Onemogući Trgovanje"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Ne može se kupiti"
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Ne može se kupiti"
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Omogući igraću palicu"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "kao čestica"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Odnos"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutralno"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Prijatelj"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Zanemareno"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignorirano"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Dozvoli trgovanje"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Dozvoli šapate"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Stavi sve šapate u kartice"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Prikaži ime"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Igrači"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Kad ignorira:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Prikaži ime"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Prikaži ime"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Ciljaj Igrača"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Efekti Čestica"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Pomoć"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Izmijeni"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Ponovo pokrenite klijent da bi promjene bile efektne."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Sićušno"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Maleno"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Srednje"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Veliko"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Nema teksta"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Tekst"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Mjehurići, bez imena"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Mjehurići s imenima"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "isključeno"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "nisko"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "visoko"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "srednje"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Pregled na čitavom ekranu"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Odnos"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Vlastiti kursor"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Vidljiva imena"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Efekt čestica"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Prikaži obavijesti o prikupljanju."
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "u chat-u"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "kao čestica"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Omogući igraću palicu"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Pozadina"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Ograničenje sličica u sekundi"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "Ograničenje sličica u sekundi"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Slika"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Tekst iznad glave"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Prozirnost sučelja"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Efekti okruženja"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Detalji Čestica"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Veličina fonta"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Ne"
+
+#: src/gui/setup_video.cpp:528
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:534
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Prebacivanje u pregled na čitavom ekranu"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Potrebno je ponovno pokrenuti klijent za izvršavanje promjena."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Promjena OpenGL-a"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Izmjene OpenGL-a zahtjevaju ponovno pokretanje klijenta."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Rezolucija Ekrana promijenjena"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Postavke efekta čestica su promijenjene."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Promjene će stupiti na snagu na promjeni karte."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Dodaj"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Zahtjev za Trgovanje"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s želi trgovati s vama, prihvaćate li?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Vještine"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Gore"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Bodovi vještine: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Bodovi vještine: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Vještine"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Nivo: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Nivo: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Ceh"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Ceh, ustanovljen."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Formiraj Ceh"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Jeste li sigurni da želite odustati?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Partija"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Pozovite korisnike na partiju"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Pozovite korisnike na partiju"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Jeste li sigurni da želite odustati?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Formiraj Ceh"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Stvori Lika"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Pozovi Korisnika"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Veliko"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Prihvaćen poziv od %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Odbijen poziv od %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Prihvaćen poziv od %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Odbijen poziv od %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Pogreška pri ustanovljavanju ceha."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Ceh"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Izaberite vaš server"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Primljen zahtjev za partiju, ali ona već postoji."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s vas je pozvao/la da se pridružite %s partiji."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Prihvati Pozivnicu za Partiju"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Primljen zahtjev za partiju, ali ona već postoji."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s vas je pozvao/la da se pridružite njihovoj partiji."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s vas je pozvao/la da se pridružite %s partiji."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s vas je pozvao/la da se pridružite njihovoj partiji."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s vas je pozvao/la da se pridružite %s partiji."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Prihvati Pozivnicu za Partiju"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Partija"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Izaberite vaš server"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Nivo: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Novac: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Zadatak: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Zadatak:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Podaci lika su u redu"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Nivo: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Bodovi vještine: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Pomakni Ulijevo"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Dozvoli trgovanje"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Pomakni Ulijevo"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Općenito"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magija"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magija"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Naredba: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magija"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Naredba: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Ciljaj Igrača"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Najviša razina"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Prikaži ime"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Predloži razmjenu"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Potvrđeno. Čekanje..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Složi se za trgovanje"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Dogovoreno. Čekanje..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Trgovanje: Vi"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Trgovanje"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Vi dobijete %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Daješ:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Izmijeni"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Nemate dovoljno novca."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Ime: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Ažuriranje"
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Spajanje..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Igraj"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Proces ažuriranja je nepotpun."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Vrlo je preporučljivo da"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 pokušate ponovno kasnije"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Dovršeno"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Biće"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Prijatelj"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Zanemareno"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignorirano"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "GM Imena"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Imena Drugih Igrača"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Vlastito Ime"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "GM Imena"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Čudovišta"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Čudovište pogađa Igrača"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Partija"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Ceh"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Efekti Čestica"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Obavijest Sakupljanja"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Exp Obavijest"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Igrač pogađa Čudovište"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Čudovište pogađa Igrača"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Imena Drugih Igrača"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Kritični Udarac"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Igrač pogađa Čudovište"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Igrač pogađa Čudovište"
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr ""
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Promašaji"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Istakni Karticu"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Istakni"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Istakni Karticu"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Čudovište pogađa Igrača"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Lista korisnika u trenutnom kanalu"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Postavi temu trenutnog kanala"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Napusti kanal"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Napravite korisnika operatorom kanala"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Šutni korisnika iz kanala"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Naredba: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Ova naredba prikazuje korisnike u ovom kanalu."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Naredba: /topic <poruka>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Ova naredba postavlja temu za <message>."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Naredba: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Ova naredba napušta trenutni kanal."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Ako ste zadnja osoba u kanalu, kanal će biti izbrisan."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Naredba: /op <nadimak>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Ova naredba čini <nadimak> operatorom kanala."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr "Kanal operatori mogu kick i op ostale korisnike iz kanala."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Naredba: /kick <nadimak>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Ova naredba napravi da <nick> napusti kanal."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Trebate korisnika za op!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Trebate korisnika za kick!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Javna obavijest:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Javna obavijest od %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s šaptanje: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Zatvara karticu za šaptaje"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Naredba: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Ova naredba zatvara trenutnu karticu za šaptaje."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Naredba: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Ova naredba prikazuje broj igrača trenutno online."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "Ova naredba započinje snimanje chat log-a u datoteku <filename>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Chat Prozor"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Smajlić"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Stanje"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Kratica"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Odaberite OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Izmijeni"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Izaberite vaš server"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Pomakni Gore"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Pomakni Dolje"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Pomakni Ulijevo"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Pomakni Udesno"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Meta i Napad"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Pomakni Ulijevo"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Smajlić"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Prekini Napad"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Ciljaj Najbližeg"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Ciljaj NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Ciljaj Igrača"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Pokupi"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Skrij Prozore"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Sjedni"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Snimak zaslona"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Omogući/Onemogući Trgovanje"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Promijeni Email Adresu"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Prečac do Predmeta %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Prečac do Predmeta %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Prozor za Pomoć"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Prozor Statusa"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Prozor Inventara"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Prozor Opreme"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Prozor Vještine"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Prozor Minikarte"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Chat Prozor"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Prozor za Prečice do Predmeta"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Prozor za Postavke"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Debug Prozor"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Prozor Vještine"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Prozor Prečica za Ispoljavanje emocija"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Prozor Statusa"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Prozor za Postavke"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Skrij Prozore"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Prozor Statusa"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Naredba: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Chat Prozor"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Prethodna Chat Kartica"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Sljedeća Chat Kartica"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Prečica za Ispoljavanje emocija %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Pomakni Chat Gore"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Pomakni Chat Dolje"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Prethodna Chat Kartica"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Sljedeća Chat Kartica"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Prethodna Chat Kartica"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Sljedeća Chat Kartica"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Odaberite OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Pomakni Dolje"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Pomakni Ulijevo"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Pomakni Udesno"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Promijeni lika"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Server"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Meta i Napad"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Promijeni Lozinku"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Promijeni Email Adresu"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Omogući/Onemogući Trgovanje"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Pokupili ste %s [@@%d|%s@@]."
+msgstr[1] "Pokupili ste %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Vi dobijete %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opcije:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Konfiguracijska datoteka za korištenje"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Konfiguracijska datoteka za korištenje"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Prikaži verziju"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Prikaži ovu pomoć"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Konfiguracijska datoteka za korištenje"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Prijava s ovim korisničkim imenom"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Prijava s ovom lozinkom"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Ulaz s tim likom"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -U --username : Prijava s ovim korisničkim imenom"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -P --password : Prijava s ovom lozinkom"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -u --skip-update : Preskoči preuzimanje ažuriranja"
+
+#: src/main.cpp:61
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Preskoči preuzimanje ažuriranja"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Direktorij iz kojeg se učitavaju podaci igre"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Direktorij koristiti kao home direktorij"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Direktorij koristiti kao home direktorij"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Onemogući OpenGL za ovu sesiju"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Snaga"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Snaga %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Okretnost"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Okretnost %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Spretnost"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Spretnost %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Vitalnost"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Vitalnost %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Inteligencija"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Inteligencija %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Snaga volje:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Snaga Volje %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Vi ste mrtvi."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "Žao nam je obavijestiti vas da je vaš lik je bio ubijen u borbi."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Niste više tako živi."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Kraj Igre!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Ne, djeco. Vaš lik zapravo nije umro. On... err... je otišao na bolje mjesto."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Predpostavljam da ovo nije išlo previše dobro."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Želite li svoju imovinu identificirati?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Nažalost, ni traga od vas nije nikada pronađeno ..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Uništen."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Izgleda da su vam predali vašu glavu."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+"Uprskali ste opet, odbacite svoje tijelo u kanalizaciju i nabavite novo."
+
+#: src/net/manaserv/beinghandler.cpp:336
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Umrli ste"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Već prijavljeni"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Korisničko ime već postoji"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Podaci lika su u redu"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Podaci lika su u redu"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Nepoznata greška"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Info"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Lik izbrisan."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Odaberi količinu predmeta za razmjenu."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Nepoznata greška"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Nijedan od servera igre nije dostupan."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Tema: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Igrač pogađa Čudovište"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Naredba: /join <channel>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Zahtjev za pridruživanje kanalu %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s se pridružio partiji."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Nepoznata naredba."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Ceh, ustanovljen."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Pogreška pri ustanovljavanju ceha."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Pozivnica je poslana."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Član je uspješno unaprijeđen."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Neuspješno promicanje člana."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Pogrešan magični_simbol"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Već prijavljeni"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Račun je istekao"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Nova lozinka je netočna"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Stara lozinka je netočna"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Račun nije priključen. Molimo prvo se prijavite."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Nova e-mail adresa netočna"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Stara e-mail adresa netočna"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Nova E-mail Adresa već postoji."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Verzija klijenta je prestara"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Pogrešno korisničko ime ili lozinka"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Račun je istekao"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Pogrešno korisničko ime, lozinka ili email adresa"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Korisničko ime već postoji"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Email adresa već postoji"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Pridružen pertiji."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s se pridružio partiji."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s je odbio vašu pozivnicu."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Prihvaćanje dolaznih zahtjeva za trgovanje."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignoriranje nadolazećih zahtjeva za trgovanje."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s želi trgovati s vama, prihvaćate li?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Trgovanje s %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Otkazano trgovanje."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Trgovanje je završeno."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Šut nije uspio!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Šut uspio!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Ništa za prodati."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Hvala za kupnju."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Ne može se kupiti"
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Hvala za prodaju."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Nije moguće prodati."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Ne mogu koristiti ovaj ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Nepoznata greška"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Ne mogu stvoriti lik. Najvjerojatnije je ime već zauzeto."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Lik izbrisan."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Neuspješno brisanje znaka."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Snaga:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Okretnost:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitalnost:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Inteligencija:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Spretnost:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Sreća:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Šapat nije mogao biti poslan, korisnik je offline."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Šapat nije mogao biti poslan, ignorirani ste od strane korisnika."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Igrač"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Igrač"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Kanali nisu podržani!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Ime"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Zahtjev za Trgovanje"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Snaga %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Okretnost %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Vitalnost %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Inteligencija %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Spretnost %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Sreća %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Autentikacija nije uspjela"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Nema dostupnih poslužitelji"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Netko drugi pokušava korištiti ovaj račun"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Ovaj korisnički račun je već prijavljen"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Otkrit brzi hack"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Dvostruka prijava"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Nepoznata pogreška veze"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Sreća"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Obrana:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "M.Napad:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "M.Obrana:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Preciznost:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Izbjegavanje:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Kritični Udarac"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Napad %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Napad %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Čudovište pogađa Igrača"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Prikaži ovu pomoć."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Pozovite igrače na vašu partiju"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Napustite partiju u kojoj ste"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Šutnite nekog iz partije u kojoj ste"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Naredba: /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Ova naredba poziva <nick> na partiju sa vama."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Naredba: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Ova naredba postavlja temu za <message>."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Pogreška pri ustanovljavanju ceha."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Nepoznata greška"
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Ceh"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Ceh"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Nivo: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Najviša razina"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Ceh"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Ceh, ustanovljen."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Ceh, ustanovljen."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s je sada član vaše partije."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Napustili ste partiju."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s je napustio/la vašu partiju."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s je sada član vaše partije."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Pozovite igrače na vašu partiju"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Napustite partiju u kojoj ste"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Šutnite nekog iz partije u kojoj ste"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Naredba: /item <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+"Ova naredba mijenja politiku korištenja zajedničkih predmete u partiji."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Naredba: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Naredba: /exp <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Naredba: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Dijeljenje predmeta je omogućeno.moguće."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Dijeljenje predmeta je onemogućeno."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Dijeljenje predmeta nije moguće."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Dijeljenje predmeta je omogućeno.moguće."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:193
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Neuspješno korištenje predmeta."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Nije moguće opremiti."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Račun nije pronađen. Molimo, ponovno se prijavite."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Nova lozinka je prekratka"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Neregistriran ID"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Pogrešna lozinka"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Račun je istekao"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Odbijeno od poslužitelja"
+
+#: src/net/tmwa/loginhandler.cpp:173
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Ovo korisničko ime je već zauzeto"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Nije moguće prodati."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Spajanje na poslužitelja karti..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Nije se mogla napraviti partija."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Partija je uspješno kreirana."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s je već član partije."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s je odbio vašu pozivnicu."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s je sada član vaše partije."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Napustili ste partiju."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s je napustio/la vašu partiju."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Nepoznati član pokušava reći: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s nije u vašoj partiji!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Ubacite žeton za nastavak."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Niste još mrtvi. Samo se odmarate."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Nema vas više."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Prestali ste postojati."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Istekao vam je rok i otišli ste upoznati svog stvoritelja."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Ukočili ste se."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Lišeni života, počivate u miru."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "Da niste bili toliko animirani sad bi podizali tratinčice."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Vaši metabolički procesi su sad povijest."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Pali ste s grančice."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Vi ste šutirali sić."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Vi ste bivši igrač."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Poruka"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Nosite više od pola svoje težine. Niste u mogućnosti kako bi povratili "
+"zdravlje."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Nosite više od pola svoje težine. Niste u mogućnosti kako bi povratili "
+"zdravlje."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Pokupili ste "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Vi dobijete %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Prvo se opremite strijelama."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Neuspjela razmjena!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Neuspjelo korištenje emotea!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Neuspjelo sjedanje!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Neuspjelo stvaranje lika!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Neuspjelo priključivanje družini!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Neuspjelo vikanje!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Još nisi dosegao/la dovoljno visok nivo!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Nedovoljno zdravlja!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Nedovoljno SP-a!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Nemaš podsjetnika!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Ne možeš to učiniti sad!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Čini se da trebate više novca... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Ne možeš koristiti tu vještinu s tim oružjem!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Trebaš još jedan crveni dragulj!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Trebaš još jedan plavi dragulj!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Nosiš previše predmeta da bi učinio to!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Ha? Što je to?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Skok nije uspio..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Krađa nije uspjela..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Otrov nije uspio..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Trgovanje nije moguće. Trgovački partner je predaleko."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Trgovanje nije moguće. Lik ne postoji."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Trgovanje otkazano zbog nepoznatih razloga."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Trgujte: Vi i %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Trgovanje s %s otkazano."
+
+#: src/net/tmwa/tradehandler.cpp:184
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Neuspješno dodavanje predmeta. Trgovinski partner je preopterećen."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+"Neuspješno dodavanje predmeta. Trgovinski partner nema slobodnog prostora."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Neuspješno dodavanje predmeta, iz nepoznatog razloga."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Potpuno ignoriraj %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Napad %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Obrana %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "Zdravlje %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "Mana %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Nepoznati predmet"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "neimenovano"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Detalji Čestica"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Efekti okruženja"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Prečica za Ispoljavanje emocija %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Igrač pogađa Čudovište"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Tema: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Ime: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "Prozor Minikarte"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Započni snimanje chat-a u eksternoj datoteci"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Naredba: /record <filename>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr "Ova naredba započinje snimanje chat log-a u datoteku <filename>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Naredba: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Ova naredba završava sesiju snimanja."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Prisutnost zapisana u evidentni dnevnik."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Završavanje snimanja."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Trenutno ne snima."
+
+#~ msgid "Already recording."
+#~ msgstr "Već se snima."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Započinjanje snimanja..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Neuspjeli početak snimanja."
+
+#~ msgid "Recording..."
+#~ msgstr "Snimanje..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Prestanak snimanja"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Pronađi Put do Miša"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Novac: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Zadatak:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Nivo: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Partija je uspješno kreirana."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Šapat nije mogao biti poslan, ignorirani ste od strane korisnika."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Konfiguracijska datoteka za korištenje"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Konfiguracijska datoteka za korištenje"
+
+#~ msgid "Sound"
+#~ msgstr "Zvuk"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Pristup odbijen"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Nepoznata greška pri odabiru lika"
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s vas je pozvao/la da se pridružite njihovoj partiji."
+
+#~ msgid "Willpower:"
+#~ msgstr "Snaga volje:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Server je pun"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Trgovanje s %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Šapat"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Budi prijatelj %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Zanemareno"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Potpuno ignoriraj %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Pozovi %s da se pridrži tvom cehu@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Pozovi %s da se pridruži tvojoj skupini@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Šut nije uspio!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Govori S %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Šutni čudovište@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Pokupi"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Ne mogu poslati prazan chat!"
+
+#~ msgid "Text Shadow"
+#~ msgstr "Sjena Teksta"
+
+#~ msgid "Text Outline"
+#~ msgstr "Obris Teksta"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Progress Bar Oznake"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Preskup predmet"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Predmet je opremljen"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Igrač"
+
+#~ msgid "Whisper"
+#~ msgstr "Šapat"
+
+#~ msgid "Is"
+#~ msgstr "Je"
+
+#~ msgid "Server"
+#~ msgstr "Server"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Nepoznat Tip Predmeta"
+
+#~ msgid "Generics"
+#~ msgstr "Generički"
+
+#~ msgid "Hats"
+#~ msgstr "Šeširi"
+
+#~ msgid "Shirts"
+#~ msgstr "Košulje"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "1 Ručno Oružje"
+
+#~ msgid "Pants"
+#~ msgstr "Hlače"
+
+#~ msgid "Shoes"
+#~ msgstr "Cipele"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "1 Ručno Oružje"
+
+#~ msgid "Shields"
+#~ msgstr "Štitovi"
+
+#~ msgid "Rings"
+#~ msgstr "Prstenovi"
+
+#~ msgid "Necklaces"
+#~ msgstr "Ogrlice"
+
+#~ msgid "Arms"
+#~ msgstr "Naoružanje"
+
+#~ msgid "Ammo"
+#~ msgstr "Streljivo"
+
+#~ msgid "HP Bar"
+#~ msgstr "HP Bar"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 HP Bar"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 HP Bar"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 HP Bar"
+
+#~ msgid "no"
+#~ msgstr "ne"
+
+#~ msgid "Buddy"
+#~ msgstr "Prijatelj"
+
+#~ msgid "Buddy List"
+#~ msgstr "Lista Prijatelja"
+
+#~ msgid "Description: %s"
+#~ msgstr "Opis: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Učinak: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Prethodni"
+
+#~ msgid "New"
+#~ msgstr "Novi"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Nivo poslaČ %d"
+
+#~ msgid "Present: "
+#~ msgstr "Pokloniti: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Napusti Ceh"
+
+#~ msgid "Ok"
+#~ msgstr "U redu"
+
+#~ msgid "Recent:"
+#~ msgstr "Novije:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Baci Testnu Čaroliju 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Baci Testnu Čaroliju 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Baci Testnu Čaroliju 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "2 Ručno Oružje"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Skini opremu@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Opremi@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Ispusti@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Razdvoji@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Pohrani@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Odaberi poslužitelj"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Neuspješno prebacivanje na "
+
+#~ msgid "windowed"
+#~ msgstr "uokvireno"
+
+#~ msgid "fullscreen"
+#~ msgstr "cijeli ekran"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Vještina Misterije"
+
+#~ msgid "Weapons"
+#~ msgstr "Oružje"
+
+#~ msgid "Crafts"
+#~ msgstr "Obrti"
+
+#~ msgid "Stats"
+#~ msgstr "Statistika"
+
+#~ msgid "Total"
+#~ msgstr "Total"
+
+#~ msgid "Cost"
+#~ msgstr "Cijena"
+
+#~ msgid "Attack:"
+#~ msgstr "Napad:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Refleks:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Preostali Bodovi Statusa: %d"
+
+#~ msgid "curl error "
+#~ msgstr "curl greška "
+
+#~ msgid " host: "
+#~ msgstr " domaćin: "
+
+#~ msgid "Buddys"
+#~ msgstr "Prijatelji"
+
+#~ msgid "Party Window"
+#~ msgstr "Prozor za Partiju"
+
+#~ msgid "Unarmed"
+#~ msgstr "Razoružan"
+
+#~ msgid "Knife"
+#~ msgstr "Nož"
+
+#~ msgid "Sword"
+#~ msgstr "Mač"
+
+#~ msgid "Staff"
+#~ msgstr "Motka"
+
+#~ msgid "Whip"
+#~ msgstr "Bič"
+
+#~ msgid "Bow"
+#~ msgstr "Luk"
+
+#~ msgid "Shooting"
+#~ msgstr "Gađanje"
+
+#~ msgid "Mace"
+#~ msgstr "Buzdovan"
+
+#~ msgid "Axe"
+#~ msgstr "Sjekira"
+
+#~ msgid "Craft"
+#~ msgstr "Zanat"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Nepoznata Vještina"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " ne može biti stvoren, ali ne postoji! Izlaz."
+
+#~ msgid " video mode: "
+#~ msgstr " video način: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Spajanje na poslužitelja likova..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Spajanje na poslužitelja korisnika..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Alias od napravi"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Naredba: /new <ime-partije>"
+
+#~ msgid "a"
+#~ msgstr "jedan"
+
+#~ msgid "Unnamed"
+#~ msgstr "Neimenovano"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Polumjer klizanja"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Brzina klizanja"
diff --git a/po/hu.po b/po/hu.po
new file mode 100644
index 000000000..9b2f32728
--- /dev/null
+++ b/po/hu.po
@@ -0,0 +1,5708 @@
+# Hungarian translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2009-07-07 19:52+0000\n"
+"Last-Translator: Tatsukichi <artit91@gmail.com>\n"
+"Language-Team: Hungarian <hu@li.org>\n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Beállítások"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Csatlakozás a térkép szerverhez...."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Belépés"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Kapcsolódási kérelem a %s nevű csatornába."
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Csatlakozás a térkép szerverhez...."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Szerver"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Hiba"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Jelszó:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Változtatás"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "A tag előléptetése sikeres."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Regisztráció megszüntetése"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Helytelen frissítési kiszolgáló: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Hiba a frissítési könyvtár létrehozása közben!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Ismeretlen parancs."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Segítség --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Megmutatja ezt a segítséget"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Megmutatja a térkép nevét"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Megmutatja az online felhasználókat"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Mondasz valamit magadról"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Letörli ezt az ablakot"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Privát üzenetet küld egy felhasználónak"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > msg megfelelője"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > msg megfelelője"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Fület hoz létre privát beszélgetéshez"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > query megfelelője"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Bezárja a privát fület."
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Semmibe veszed %s-t@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Publikus csatornák listázása"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Csatornához kapcsolódás/csatornát létrehoz"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Új csapat létrehozása"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Új csapat létrehozása"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Felhasználó csapatba hívása"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+"/toggle > Választható, hogy üres <enter> kell e az input panel bezárásához"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr "/present > \"Hallható\" játékosok kilistázása"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Globális üzenet (csak GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Bezárja a privát fület."
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Privát üzenetet küld egy felhasználónak"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "További információhoz gépeld be a /help <parancsnév> parancsot."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Parancs: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Ez a parancs az elérhető parancsokat listázza."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Parancs: /help <parancsnév>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr ""
+"Ez a parancs segítséget nyújt a <parancsnév> alatt megadott parancshoz."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Parancs: /announce <üzenet>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** csak GM-nek elérhető ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"Ez a parancs az <üzenet>-en belül megadott szöveget elküldi az összes "
+"elérhető játékosnak."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Parancs: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Törli a beszélgetés panel tartalmát."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Parancs: /item <szabály>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Ez a parancs megmutatja az online játékosok számát."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Parancs: /join <csatorna>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Belépsz a <csatorna> helyen megadott beszélgetési csatornába."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Ha a <csatorna> helyen megadott csatorna nem létezik, létrehozod."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Parancs: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Kilistázza az összes csatornát."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Parancs: /me <üzenet>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Ezzel a paranccsal az állapotodat jelzed. Megjelenés: Név <üzenet>"
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Parancs: /msg <név> <üzenet>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Parancs: /whisper <név> <üzenet>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Parancs: /w <név> <üzenet>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+"Ez a parancs elküldi az <üzenet> szövegét a <név> alatt megadott nevű "
+"játékosnak."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Ha a <név> alatt megadott név szóközt tartalmaz idézőjelbe kell tenni. (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Parancs: /query <név>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Parancs: /q <név>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Ez a parancs egy új fület nyit beszélgetéseidhez a <név> alatt megadott nevű "
+"játékossal."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Parancs: /w <név> <üzenet>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Parancs: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Ez a parancs beállítja a témát a <téma> alatt megadott szövegre."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Parancs: /create <csapatnév>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr ""
+"Ezek a parancsok új csapatot hoznak létre a <csapatnév> alatt megadott néven."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Parancs: /create <csapatnév>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr ""
+"Ezek a parancsok új csapatot hoznak létre a <csapatnév> alatt megadott néven."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Parancs: /party <név>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Ez a parancs csapatba hívja a <név> alatt megadott nevű játékost."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Parancs: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Ez a parancs megmutatja a \"hallható\" játékosok nevét és fájlba is rögzíti, "
+"ha éppen rögzítjük a beszélgetést."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Parancs: /toggle <állás>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr "Ez a parancs beállítja az enter billentyű használatát a játékban."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<állás> lehet \"1\", \"yes\", \"true\" ha ki akarod kapcsolni a chat input "
+"automatikus eltűnését, \"0\", \"no\", \"false\" ha nem."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Parancs: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "A /toggle jelenlegi állását mutatja meg."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Parancs: /item <szabály>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Parancs: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Ez a parancs megmutatja az aktuális térkép nevét."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Parancs: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Ez a parancs megmutatja az online játékosok számát."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Parancsok listája: /help"
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Nem küldhetsz üres üzenetet!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Nem tudsz fület létrehozni \"%s\" számára! Létre van hozva, vagy te vagy az."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Kapcsolódási kérelem a %s nevű csatornába."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "A csapatnév hiányzik."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "A csapatnév hiányzik."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Az enter megnyitja a bevitelt."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Az üzenet bezárja a bevitelt."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Az enter mostantól megnyitja a bevitelt."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Az üzenet mostantól bezárja a bevitelt."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Barát"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Semmibevett"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Semleges"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "A privát üzenet nem lett elküldve, mert le lettél tiltva."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Csapat létrehozása sikeres."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "A privát üzenet nem lett elküldve, mert le lettél tiltva."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "A privát üzenet nem lett elküldve, mert le lettél tiltva."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "A privát üzenet nem lett elküldve, mert le lettél tiltva."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Csapat létrehozása sikeres."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "A privát üzenet nem lett elküldve, mert le lettél tiltva."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Lehetőségek a /%s parancshoz: \"yes\", \"no\", \"true\", \"false\", \"1\", "
+"\"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Általános"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Képernyőt mentettük a ~/ helyre"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Hiba a képernyő mentése során!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "A kapcsolat megszakadt a szerverrel, a program most kilép."
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Hálózati hiba"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Kereskedési kérelmek elutasítása"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Kereskedési kérelmek elfogadása"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Nem lehet betölteni a térképet"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Hiba %s betöltése közben"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Csapat (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Klánok"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Chat Ablak"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Név"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Támadás"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Csevegés"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Mozgás felfelé"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Alaphelyzet"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Vétel"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Ár: %s / Teljes: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Kilépés"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Max."
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Üzlet"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Eladás"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Mégse"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Email cím módosírása"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Fiók: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Írd be az új Email címet kétszer:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "A felhasználónévnek legalább %d karakternek kell lennie."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "A felhasználónévnek legfeljebb %d karakternek kell lennie."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Az új email cím már foglalt."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Jelszó módosítása"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Jelszó:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Írd be az új jelszót kétszer:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "A jelszónak legalább %d karakter hosszúnak kell lennie."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "A jelszónak legfeljebb %d karakter hosszúnak kell lennie."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Karakter létrehozása"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Név:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Haj szín:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Haj stílus:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Létrehozás"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Férfi"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Nő"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Kérlek oszd el a pontjaidat (%d van még)"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "A nevednek minimum 4 karakternek kell lennie."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Karakter statok rendben"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Kérlek távolíts el %d pontot"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Karakter törlésének megerősítése"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Biztos hogy ki akarod törölni ezt a karaktert?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Fiók és Karakter Menedzsment"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Regisztráció megszüntetése"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Email cím módosírása"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Törlés"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Bezár"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Alapértelmezett"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Barát"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Zöld: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Kék: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "alacsony"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Hiperlink"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Dobófegyver"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Szivárvány"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Szivárvány"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Szivárvány"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d játékos van a közeledben."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Üzenet %s számára: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Igen"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Nem"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Tiltott"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Téma: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Név: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Minitérkép Ablak"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Effektek"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Karakter statok rendben"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Sebzéskor"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Mozgás balra"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Játékost Kijelöl"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Játékost Kijelöl"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Játékost Kijelöl"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Játékost Kijelöl"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Egyéni kurzor"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "Ok"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Felszerelés"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Nem használ"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Súgó"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Bezár"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Táska"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Raktár"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Hely:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Használ"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Bevet"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Eldob"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Felosztás"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Súly:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Raktároz"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Magához vesz"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Eldob"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Mind"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Válaszd ki mennyi tárggyal akarsz üzletelni."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Válaszd ki mennyit akarsz eldobni."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Válaszd ki a raktározandó mennyiséget."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Válaszd ki mennyit veszel magadhoz."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Válaszd ki az elosztandó mennyiséget."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Ismeretlen hiba"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Súly: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Sztátusz Ablak"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Alaphelyzet"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Alaphelyzet"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Szint: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "TP:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Mozgás balra"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Bezár"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Belépés"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Szerver:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Felhasználónév megjegyzése"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Regisztráció"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Szerver"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Térkép"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Várakozás a szerverre"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Következő"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Küldés"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "Gépjátékos"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Szálfegyver"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Következő"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Cél:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Küldés"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "A levél elküldése sikertelen. A feladó, vagy a címzett nem található."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Pénz: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Nem használ"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Üzlet Te és %s között@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|%s megtámadása@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Bevet@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|mégse@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Visszavesz@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Semmibe veszed %s-t@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|%s tiltása@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Bevet@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|%s tiltásának feloldása@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Teljesen letiltod %s-t@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Felhasználó csapatba hívása"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Játékos kirúgása@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Játékos kirúgása@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Felhasználó csapatba hívása"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Játékos kirúgása@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|%s tiltásának feloldása@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Bevet@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|%s megtámadása@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Játékos kirúgása@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Neve hozzáadása a csevegéshez@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|mégse@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Vedd fel a(z) %s-t@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Hozzáadás a chat-hez@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Bevet@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Kijelölt fül"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Kijelölt fül"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Változtatás"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Raktároz"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Raktároz"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Raktároz"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Magához vesz"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Magához vesz"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Magához vesz"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Hozzáadás a chat-hez@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Szerver változtatása"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Karakter változtatása"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Megerősítés:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "A felhasználónévnek legalább %d karakternek kell lennie."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "A felhasználónévnek legfeljebb %d karakternek kell lennie."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "A jelszónak legalább %d karakter hosszúnak kell lennie."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "A jelszónak legfeljebb %d karakter hosszúnak kell lennie."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "A jelszavak nem egyeznek."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Válassz szervert"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Szerver:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Csatlakozás…"
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Egyéni kurzor"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Kérlek írd be a szerver címét és portját egyaránt."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Várakozás a szerverre"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Joystick engedélyezése"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Joystick engedélyezése"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Audió"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Effektek hangereje"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Zene hangereje"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Nincs szöveg"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Nem tudod megvenni."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Nem tudod megvenni."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "A név mutatása"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Így fog kinézni a felirat."
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Színek"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Típus: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statikus"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulzáló"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Szivárvány"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Színkép"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Várakozás "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Vörös: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Zöld: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Kék: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Alkalmaz"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Ablakok alaphelyzetbe"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Nyomd meg a gombot a kalibrálás megkezdéséhez"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Kalibrálás"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Joystick engedélyezése"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Leállít"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Mozgasd körbe"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Billentyűzet"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Hozzárendel"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Hozzárendel"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Alapértelmezett"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Billentyű ütközés van."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Kijelölt"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "A név mutatása"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Joystick engedélyezése"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Kijelölt"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Üzletelés Engedélyezése/Tiltása"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Nem tudod megvenni."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Nem tudod megvenni."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Joystick engedélyezése"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "Karakter felett"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Kapcsolat"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Semleges"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Barát"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Semmibevett"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Tiltott"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Üzletelés engedélyezése"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Privát engedélyezése"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Privátok fülekbe tétele"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "A név mutatása"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Játékosok"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Ha ignorolva van:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "A név mutatása"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "A név mutatása"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Játékost Kijelöl"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Effektek"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Súgó"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Változtatás"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "A változások érvénybe lépéséhez a program újraindítása szükséges."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Apró"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Kicsi"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Közepes"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Nagy"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Nincs szöveg"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Szöveg"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Buborékok, nincs név."
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Buborékok nevekkel"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "ki"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "alacsony"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "magas"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "közepes"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "max."
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Teljes képernyő"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Kapcsolat"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Egyéni kurzor"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Látható nevek"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Játékbéli effektek"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Értesítés tárgy felvételkor"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "Chat-en belül"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "Karakter felett"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Joystick engedélyezése"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Háttér"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS Limit:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "FPS Limit:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Videó"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Fej feletti szöveg"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Menük áttetszősége"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Környezeti effektek"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Effektek részletessége"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Betűméret"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Nem"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "Ez a mód és az előző mód visszaállítása sikertelen."
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "Ez a mód és az előző mód visszaállítása sikertelen."
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Átállás teljes képernyőre"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "A változások érvénybe lépéséhez a program újraindítása szükséges."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "OpenGL átállítása"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "A változások érvénybe lépéséhez a program újraindítása szükséges."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "A képernyő felbontása megváltozott"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Effektek beállítása megváltozott."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "A változások érvénybe lépéséhez töltsön be egy új térképet."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Hozzáad"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Üzleti ajánlat"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s üzletelni akar veled. Te akarsz vele?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Képességek"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Fejleszt"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Képesség pontok: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Képesség pontok: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Képességek"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Szint: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Szint: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Klán"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Klán létrehozva."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Klán létrehozása"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Biztos, hogy ki szeretne lépni?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Csapat"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Felhasználó csapatba hívása"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Felhasználó csapatba hívása"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Biztos, hogy ki szeretne lépni?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Klán létrehozása"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Karakter létrehozása"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Felhasználó meghívása"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Nagy"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Csapatba hívást elfogadta %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Csapatba hívást elutasította %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Csapatba hívást elfogadta %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Csapatba hívást elutasította %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Hiba a klán létrehozása közben."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Klán"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Válassz szervert"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Csapatba hívtak, de neked van csapatod."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s behívott %s csapatába."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Ajánlat elfogadása"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Csapatba hívtak, de neked van csapatod."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s a csapatába hívott."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s behívott %s csapatába."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s a csapatába hívott."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s behívott %s csapatába."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Ajánlat elfogadása"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Csapat"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Válassz szervert"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Szint: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Pénz: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "Élet:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "TP:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "Varázserő:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Munka: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Munka:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Karakter statok rendben"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Szint: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Képesség pontok: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Mozgás balra"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Üzletelés engedélyezése"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Mozgás balra"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Általános"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Mágia"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Mágia"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Parancs: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Mágia"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Parancs: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Játékost Kijelöl"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Max. szint"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "A név mutatása"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Üzletet javasol"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Megerősítve. Vár..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Üzlet elfogadása"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Elfogadva. Vár..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Üzlet: Te"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Üzlet"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Kapott tárgy: %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Adott tárgyak:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Változtatás"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Hiba a tárgy hozzáadásakor. Nem tudod rárakni az egyik tárgyat a másikra."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Nincs elég pénzed."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Név: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Frissítés…"
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Csatlakozás…"
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Játék"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 A frissítési folyamat befejezetlen"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Erősen ajánljuk, hogy"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 próbáld meg később"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Kész"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Nevek"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Barát"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Semmibevett"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Tiltott"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "GM név"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Ismeretlen játékos neve"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Saját név"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "GM név"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "Gépjátékos neve"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Szörny neve"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Sérüléskor"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Csapat"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Klán"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Effektek"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Tárgy felvételekor"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Tapasztalat szerzésekor"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Sebzéskor"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Sérüléskor"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Ismeretlen játékos neve"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Kritikális ütéskor"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Sebzéskor"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Sebzéskor"
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr ""
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Ha nincs találat."
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Kijelölt fül"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Kijelölt"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Kijelölt fül"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Sérüléskor"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Kilistázza az aktuális csatorna felhasználóit"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Beállítja egy csatorna témáját."
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Csatorna elhagyása"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Felhasználóból csatorna operátort képez."
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Felhasználó kirúgása a csatornából"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Parancs: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Ez a parancs megmutatja ennek a csatornának a felhasználóit."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Parancs: /topic <téma>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Ez a parancs beállítja a témát a <téma> alatt megadott szövegre."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Parancs: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Ez a parancs kilép az aktuális csatornából."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Ha te vagy az utolsó személy a csatornán, akkor kitörli."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Parancs: /op <név>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+"Ez a parancs a <név> alatt megadott személyt csatorna operátorrá teszi."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr "A csatorna operátor parancsai: /kick /op"
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Parancs: /kick <név>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Ez a parancs kirúgja a <név> alatt megadott személyt a csatornából."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Kell egy játékos az op parancshoz."
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Kell egy játékos a kick parancshoz."
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Globális bejelentés:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Globális bejelentés (%s) :"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s mondja: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Bezárja a privát fület."
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Parancs: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Ez a parancs bezárja az aktuális privát fület."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Parancs: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Ez a parancs megmutatja az online játékosok számát."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Ez a parancs elkezdi felvenni a beszélgetést a <fájlnév> alatt megadott "
+"fájlba."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Chat Ablak"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Hangulatjel"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Státusz"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Gyorsmenü"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Ok Kiválasztása"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Változtatás"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Válassz szervert"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Mozgás felfelé"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Mozgás lefelé"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Mozgás balra"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Mozgás jobbra"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Kijelöl és Támad"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Mozgás balra"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Hangulatjel"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Támadás Megszüntetése"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Legközelebbit Kijelöl"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Gépjátékost Kijelöl"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Játékost Kijelöl"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Felvesz"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Ablakok Elrejtése"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Ülés"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Képernyőkép"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Üzletelés Engedélyezése/Tiltása"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Email cím módosírása"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Gyorsmenü %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Gyorsmenü %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Súgó Ablak"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Sztátusz Ablak"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Táska Ablak"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Felszerelés Ablak"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Képességek Ablak"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Minitérkép Ablak"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Chat Ablak"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Gyorsmenü Ablak"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Beállítások Ablak"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Hibakereső Ablak"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Képességek Ablak"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Hangulatjel Gyorsmenü Ablak"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Sztátusz Ablak"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Beállítások Ablak"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Ablakok Elrejtése"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Sztátusz Ablak"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Parancs: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Chat Ablak"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Előző Chat Fül"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Következő Chat Fül"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Hangulatjel Gyorsmenü %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Chat Ki/Be Kapcsolása"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Csevej Felfele Görgetése"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Csevej Lefele Görgetése"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Előző Chat Fül"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Következő Chat Fül"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Előző Chat Fül"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Következő Chat Fül"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Ok Kiválasztása"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignore input 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignore input 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Mozgás lefelé"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Mozgás balra"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Mozgás jobbra"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Karakter változtatása"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Szerver"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Kijelöl és Támad"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Jelszó módosítása"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Email cím módosírása"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Üzletelés Engedélyezése/Tiltása"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Állítsd át, vagy a játék érdekesen fog viselkedni."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Nem tudod felvenni a tárgyat."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Zsákmányod%s [@@%d|%s@@]."
+msgstr[1] "Zsákmányod%s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Kapott tárgy: %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opciók:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Konfigurációs fájl használata"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Konfigurációs fájl használata"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Megmutatja a verziót"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Megmutatja ezt a súgót"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Konfigurációs fájl használata"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Bejelentkezés ezzel a felhasználónévvel"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Bejelentkezés ezzel a jelszóval"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Bejelentkezés ezzel a karakterrel"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Szerver neve vagy IP címe"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Bejelentkezési port"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : A frissítési szerver kijelölésére használjuk"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Válaszd ki az alapértelmezett szervert és karaktert"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Frissítés átugrása"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Könyvtár ahonnan betöltöd a játékot"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Könyvtár használata gyökérkönyvtárként"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Könyvtár használata gyökérkönyvtárként"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : OpenGL kikapcsolása erre az időszakra"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Erő"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Erő %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Mozgékonyság"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Mozgékonyság %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Ügyesség"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Ügyesség %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Egészség"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Egészség %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligencia"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligencia %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Akaraterő:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Akaraterő: %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Meghaltál."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "A karaktered elvérzett a csatában."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Nem vagy már az élők sorában."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "A kaszás eljött érted, hogy elvigye a lelked."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Vége a játéknak!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Nem, gyerekek. A karakter nem meghalt, ..ööö... hanem egy szebb világba "
+"került."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"A tervet, amiben a torkoddal támadsz az ellenség kardjába sikertelennek "
+"bizonyult."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Úgy látszik nem futottál túl gyorsan."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Meg akarod bánni a bűneid?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Kövesd a fényt az alagút végén."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Megöltek."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Kezedbe adták a fejed."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "Sikolyok közepette kerültél a másvilágra."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Nyomj Ok-t a feléledéshez"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Meghaltál."
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Már be van jelentkezve"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "A felhasználónév foglalt"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Karakter statok rendben"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Karakter statok rendben"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Ismeretlen hiba"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Infó"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Karakter törölve."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Válaszd ki mennyi tárggyal akarsz üzletelni."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Ismeretlen hiba"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Nincs elérhető játékszerver."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Téma: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Sebzéskor"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Parancs: /join <csatorna>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Kapcsolódási kérelem a %s nevű csatornába."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s csatlakozott a csapathoz."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Ismeretlen parancs."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Klán létrehozva."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Hiba a klán létrehozása közben."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Meghívás elküldve."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "A tag előléptetése sikeres."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "A tag előléptetése sikertelen."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Helytelen magic_token"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Már be van jelentkezve"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "A fiók lejárt"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Az új jelszó hibás"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "A régi jelszó hibás"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "A fiók nem kapcsolódott. Kérlek jelentkezz be előbb."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Az új email cím hibás."
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "A régi email cím hibás."
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Az új email cím már foglalt."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "A kliens verziója túl régi"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Hibás felhasználónév vagy jelszó"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "A fiók lejárt"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Hibás felhasználónév, jelszó, vagy email cím"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "A felhasználónév foglalt"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Az email cím foglalt"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Csatlakoztál a csapathoz."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s csatlakozott a csapathoz."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s visszautasította a csapatba hívást."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Elfogadod a bejövő üzleti ajánlatokat."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Elutasítod a bejövő üzleti ajánlatokat."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s üzletelni akar veled. Te akarsz vele?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Üzlet Te és %s között"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Az üzlet megszakadt."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Sikeres üzlet."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Kirúgás sikertelen!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Kirúgás sikeres!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Nincs mit eladni."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Öröm volt veled üzletet kötni!"
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Nem tudod megvenni."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Öröm volt veled üzletet kötni!"
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Nem tudod eladni."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Nem használhatod ez a nevet."
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Ismeretlen hiba"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Nem tudod létrehozni a karaktert. Valószínű a neve használatban van."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Karakter törölve."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Karakter törlése sikertelen."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Erő:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Mozgékonyság:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Egészség:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligencia:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Ügyesség:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Szerencse:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "A privát üzenet nem lett elküldve, mert a játékos nem elérhető."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "A privát üzenet nem lett elküldve, mert le lettél tiltva."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Játékos"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Játékos"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "A csatornák le vannak tiltva!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Név"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Üzleti ajánlat"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Erő %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Mozgékonyság %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Egészség %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligencia %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Ügyesség %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Szerencse %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Azonosítás sikertelen"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Nincs elérhető szerver"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Valaki más megprobál belépni erre a fiókra"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Ez a fiók már be van lépve"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Speed hack észlelve"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Duplikált bejelentkezés"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Ismeretlen kapcsolati hiba"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Lekapcsolódtál a szerverről!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Szerencse"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Fizikális védelem:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "Mágikus támadás:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "Mágikus védelem:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "Találati esély (%):"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "Kitérés (%):"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Kritikális ütéskor"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Támadás %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Támadás %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Sérüléskor"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Megmutatja ezt a súgót."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Játékos meghívása a csapatba"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Jelenlegi csapat elhagyása"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Valaki kirúgása a csapatból"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Parancs: /invite <név>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Ez a parancs csapatba hívja a <név> alatt megadott nevű játékost."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Parancs: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Ezzel a paranccsal a játékos elhagyja a csapatát."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Hiba a klán létrehozása közben."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "%s részéről ismeretlen válasz a meghívásra."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Klán"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Klán"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Szint: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Max. szint"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Klán"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Klán létrehozva."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Klán létrehozva."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s mostantól a csapatod tagja."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "%s részéről ismeretlen válasz a meghívásra."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Kiléptél a csapatból."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s elhagyta a csapatot."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s mostantól a csapatod tagja."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Játékos meghívása a csapatba"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Jelenlegi csapat elhagyása"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Valaki kirúgása a csapatból"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Tárgyak elosztását nézhetjük/átállíthatjuk vele"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Tapasztalat elosztását nézhetjük/átállíthatjuk vele"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Ezzel a paranccsal a játékos elhagyja a csapatát."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Parancs: /item <szabály>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Ez a parancs a tárgyak megosztását szabályozza a csapaton belül."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<szabály> lehet \"1\", \"yes\", \"true\" a tárgyak megosztásához, vagy "
+"\"0\", \"no\", \"false\" a tárgyak megosztásának kikapcsolásához."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Parancs: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "Ez a parancs megmutatja a csapat jelenlegi tárgymegosztási-szabályát."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Parancs: /exp <szabály>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Ez a parancs a tapasztalat megosztását szabályozza a csapaton belül."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<szabály> lehet \"1\", \"yes\", \"true\" a tapasztalat megosztásához, vagy "
+"\"0\", \"no\", \"false\" a tapasztalat megosztásának kikapcsolásához."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Parancs: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+"Ez a parancs megmutatja a csapat jelenlegi tapasztalatmegosztási-szabályát."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Tárgy megosztás engedélyezve."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Tárgy megosztás tiltva."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "A tárgy megosztás nem lehetséges."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Tárgy megosztás engedélyezve."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Tapasztalat megosztás engedélyezve."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Tapasztalat megosztás tiltva."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "A tapasztalat megosztás nem lehetséges."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Tapasztalat megosztás engedélyezve."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Nem tudod bevetni a tárgyat."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Nem tudod használni."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Fiók nem található. Kérem jelentkezzen be újra."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Az új jelszó túl rövid"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Az ID nincs regisztrálva"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Hibás jelszó"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "A fiók lejárt"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Visszautasított a szerver"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Véglegesen kitiltottak a szerverről. Kérlek vedd fel a kapcsolatot a GM "
+"csapattal."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Ki vagy tiltva a szerverről hátralévő idő a feloldásig %s\n"
+"Kérlek vedd fel a kapcsolatot a GM csapattal."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Ez a felhasználónév már foglalt."
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Nem tudod eladni."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Csatlakozás a térkép szerverhez...."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Nem tudtad a csapatot létrehozni."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Csapat létrehozása sikeres."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s eleve tagja a csapatnak."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s visszautasította a csapatba hívást."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s mostantól a csapatod tagja."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "%s részéről ismeretlen válasz a meghívásra."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Kiléptél a csapatból."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s elhagyta a csapatot."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Egy ismeretlen csapattárs mondja: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s nincs a csapatodban!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Dobj be egy érmét a folytatáshoz."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Nem haltál meg...csak alszol..."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Nem létezel többé."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Megszüntél létezni."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Véged és elindultál találkozni a készítőddel."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Hulla vagy."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Megfosztottak az életedtől. Nyugodj békében."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "Szép vagy mikor alszol..."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Történelem vagy."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Elég gallyul nézel ki."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Feldobtad a talpad."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr "Megfulladtál a saját véredben."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Ex-játékos lettél."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Az örök búzamezőkön kaszálgatsz."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Üzenet"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "Több tárgy van nálad mint a súlyod fele. Nem töltődik az életed."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr "Több tárgy van nálad mint a súlyod fele. Nem töltődik az életed."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Zsákmányod "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Kapott tárgy: %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Előbb tegyél be nyílvesszőt."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Üzlet sikertelen!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Hangulatjel küldése sikertelen!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Ülés sikertelen!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Beszélgetés létrehozása sikertelen."
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Nem tudsz csatlakozni a csapatba."
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Nem tudsz ordítani!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Nem érted még el a megfelelő szintet!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Kevés az életed!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Kimerültél."
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Nincs feljegyzésed."
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Most nem csinálhatod!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Úgy néz ki több pénzre van szükséged... ;)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Ezzel a fegyverrel nem tudod ezt a képességet használni!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Egy másik piros kőre van szükséged!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Egy másik kék kőre van szükséged!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Túl sok dolgot cipelsz, hogy ezt csináld!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Huh? Mi volt ez?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Teleport sikertelen..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Nem tudsz semmit ellopni..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "A méregnek nem volt hatása..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Az üzlet nem lehetséges. A partner túl messze van."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Az üzlet nem lehetséges. A partner nem létezik."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Az üzlet ismeretlen okból megszakadt."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Üzlet: Te és %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Te és %s üzlete megszakadt."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Lekezeletlen üzlet elutasító csomag."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Tárgy hozzáadása sikertelen. Az üzleti partner túl van terhelve."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "Tárgy hozzáadása sikertelen. Az üzleti partnernek nincs elég helye."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Ismeretlen okból a tárgy hozzáadása sikertelen."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Teljesen letiltod %s-t@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Támadás %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Védelem %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "Élet: %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "Varázserő %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Ismeretlen tárgy"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "Névtelen"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Effektek részletessége"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Környezeti effektek"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Hangulatjel Gyorsmenü %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Sebzéskor"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Téma: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Név: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "Minitérkép Ablak"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Beszélgetés rögzítése külső fájlba"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "parancs: /record <fájlnév>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Ez a parancs elkezdi felvenni a beszélgetést a <fájlnév> alatt megadott "
+#~ "fájlba."
+
+#~ msgid "Command: /record"
+#~ msgstr "Parancs: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Befejezi a beszélgetés rögzítését."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "A látogatottság rögzíve lessz."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Rögzítés befejezése."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Jelenleg nem rögzítesz."
+
+#~ msgid "Already recording."
+#~ msgstr "Már rögzítesz."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Rögzítés megkezdése..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Sikertelen rögzítés."
+
+#~ msgid "Recording..."
+#~ msgstr "Rögzítés..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Rögzítés leállítása"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Útvonal Keresése a Kurzorig"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "Élet:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "Varázserő:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "TP:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Pénz: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Munka:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Szint: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Csapat létrehozása sikeres."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "A privát üzenet nem lett elküldve, mert le lettél tiltva."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Konfigurációs fájl használata"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Konfigurációs fájl használata"
+
+#~ msgid "Sound"
+#~ msgstr "Hang"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Hozzáférés megtagadva"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Ismeretlen hiba a karakter választásnál."
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Meghívás jelenleg nem lehetséges."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s a csapatába hívott."
+
+#~ msgid "Willpower:"
+#~ msgstr "Akaraterő:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "A szerver tele van"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Üzlet Te és %s között"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Privát üzenet"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Felvenni %s-t a barátok közé@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Semmibevett"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Teljesen letiltod %s-t@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|%s meghívása a klánodba@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|%s meghívása a csapatodba@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Kirúgás sikertelen!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Privát Te és %s között@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Szörny kirúgása@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Felvesz"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Nem tudsz üres üzenetet küldeni!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Nem tudod eltenni."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Szövegárnyék"
+
+#~ msgid "Text Outline"
+#~ msgstr "Szöveg körvonala"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Töltésjelző cimkék"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "A tárgy túl drága"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "A tárgy használatban van"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Játékos"
+
+#~ msgid "Whisper"
+#~ msgstr "Privát üzenet"
+
+#~ msgid "Is"
+#~ msgstr "Is"
+
+#~ msgid "Server"
+#~ msgstr "Szerver"
+
+#~ msgid "Logger"
+#~ msgstr "Rögzítő"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Ismeretlen tárgy típus"
+
+#~ msgid "Generics"
+#~ msgstr "Gyógyszer"
+
+#~ msgid "Hats"
+#~ msgstr "Fejfedő"
+
+#~ msgid "Usables"
+#~ msgstr "Bevethető"
+
+#~ msgid "Shirts"
+#~ msgstr "Felső"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "1 kezes fegyverek"
+
+#~ msgid "Pants"
+#~ msgstr "Nadrág"
+
+#~ msgid "Shoes"
+#~ msgstr "Cipő"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "1 kezes fegyverek"
+
+#~ msgid "Shields"
+#~ msgstr "Pajzsok"
+
+#~ msgid "Rings"
+#~ msgstr "Gyűrűk"
+
+#~ msgid "Necklaces"
+#~ msgstr "Nyaklánc"
+
+#~ msgid "Arms"
+#~ msgstr "Kezek"
+
+#~ msgid "Ammo"
+#~ msgstr "Töltény"
+
+#~ msgid "HP Bar"
+#~ msgstr "Élet csík"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 élet csík"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 élet csík"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 Élet csík"
+
+#~ msgid "no"
+#~ msgstr "Nem"
+
+#~ msgid "Buddy"
+#~ msgstr "Partner"
+
+#~ msgid "Buddy List"
+#~ msgstr "Partnerlista"
+
+#~ msgid "Description: %s"
+#~ msgstr "Leírás: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Hatás: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Előző"
+
+#~ msgid "New"
+#~ msgstr "Új"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Munka szint: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Közel van: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Klán elhagyása"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Recent:"
+#~ msgstr "Előzmény:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Teszt Varázs 1 Bevetése"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Teszt Varázs 2 Bevetése"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Teszt Varázs 3 Bevetése"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "2 kezes fegyverek"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Nem használ@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Használ@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Eldob@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Szétválaszt@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Raktároz@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Válassza ki a szervert"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Nem lehet erre váltani: "
+
+#~ msgid "windowed"
+#~ msgstr "ablakban"
+
+#~ msgid "fullscreen"
+#~ msgstr "teljes képernyőn"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Misztikus képesség"
+
+#~ msgid "Weapons"
+#~ msgstr "Fegyverek"
+
+#~ msgid "Crafts"
+#~ msgstr "Mesterségek"
+
+#~ msgid "Stats"
+#~ msgstr "Statok"
+
+#~ msgid "Total"
+#~ msgstr "Összes"
+
+#~ msgid "Cost"
+#~ msgstr "Költség"
+
+#~ msgid "Attack:"
+#~ msgstr "Fizikális sebzés:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "Reflex (%):"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Elosztható pontok: %d"
+
+#~ msgid "curl error "
+#~ msgstr "curl hiba "
+
+#~ msgid " host: "
+#~ msgstr " kiszolgáló: "
+
+#~ msgid "Buddys"
+#~ msgstr "Partnerek"
+
+#~ msgid "Party Window"
+#~ msgstr "Csapat Ablak"
+
+#~ msgid "Unarmed"
+#~ msgstr "Ököl"
+
+#~ msgid "Knife"
+#~ msgstr "Kés"
+
+#~ msgid "Sword"
+#~ msgstr "Kard"
+
+#~ msgid "Staff"
+#~ msgstr "Bot"
+
+#~ msgid "Whip"
+#~ msgstr "Ostor"
+
+#~ msgid "Bow"
+#~ msgstr "Íj"
+
+#~ msgid "Shooting"
+#~ msgstr "Lőfegyver"
+
+#~ msgid "Mace"
+#~ msgstr "Buzogány"
+
+#~ msgid "Axe"
+#~ msgstr "Fejsze"
+
+#~ msgid "Craft"
+#~ msgstr "Mesterség"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Ismeretlen Képesség"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " -t nem lehet létrehozni és nincs létrehozva! Kilépés."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Nem lehet beállítani: "
+
+#~ msgid " video mode: "
+#~ msgstr " videó mód: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Csatlakozás a karakter szerverhez...."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Csatlakozás a fiók szerverhez..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Ugyanaz, mint a /create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Parancs: /new <csapatnév>"
+
+#~ msgid "a"
+#~ msgstr ":"
+
+#~ msgid "Unnamed"
+#~ msgstr "Névtelen"
diff --git a/po/id.po b/po/id.po
new file mode 100644
index 000000000..457e0dfcc
--- /dev/null
+++ b/po/id.po
@@ -0,0 +1,3632 @@
+# Indonesian translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-11-21 12:11+0000\n"
+"Last-Translator: Rainfeed <Unknown>\n"
+"Language-Team: Indonesian <id@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "Atur"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Menyambung..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "Login"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Pilih Karakter"
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Kesalahan"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Kata Sandi:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "Ubah"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Tidak terdaftar"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Perintah tidak dikenal."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr ""
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Pengumuman global (khusus GM)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "Perintah: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "Perintah: /announce <pesan>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** hanya tersedia bagi GM ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "Perintah: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Perintah: /announce <pesan>"
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Perintah: /clear"
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Perintah: /announce <pesan>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "Beli"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Keluar"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Jual"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "Batal"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Panjang username setidak-tidaknya %d karakter"
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Panjang username setidak-tidaknya %d karakter"
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Kata Sandi:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Panjang kata-sandi setidak-tidaknya %d karakter"
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Panjang kata-sandi setidak-tidaknya %d karakter"
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Buat Karakter"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "Nama:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Warna Rambut:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Gaya Rambut:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "Buat"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Tolong distribusikan %d point"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Nama anda sekurang-kurangnya harus 4 karakter"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Stats Karakter OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Tolong hilangkan %d point"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Apakah anda bersungguh-sungguh ingin menghapus karakter ini?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Tidak terdaftar"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Ubah"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Hapus"
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Ya"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Tidak"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "Nama: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "MiniMap"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Perlengkapan"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "Inventaris"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Gunakan"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "Jatuh"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "Pecah"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "Jatuh"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "Pilih jumlah item yang mau di perdagangkan"
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "Pilih jumlah item yang mau di buang"
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "Pilih jumlah item yang mau di pisahkan"
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Efek: %s"
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "Login"
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Mendaftar"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Ubah"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Berikutnya"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Berikutnya"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "@@trade|Dagang Dengan %s@@"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "Serangan %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "Ganti Server"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "Ganti Karakter"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "Konfirmasi:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Panjang username setidak-tidaknya %d karakter"
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Panjang kata-sandi setidak-tidaknya %d karakter"
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Kata sandi tidak sama."
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "Menyambung..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "Tolong tulis address dan port dari server"
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "Suara"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "Suara"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Volume sfx"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Volume Musik"
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Terapkan"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "Tekan tombol untuk memulai kalibrasi"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "Kalibrasi"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Membolehkan joistik"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "Berhenti"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "Memutar tongkat"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "mati"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "rendah"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "tinggi"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "Layar penuh"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Batas FPS"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Tidak"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Mengganti ke layar penuh"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "Memulai dari awal di butuhkan untuk melihat efek"
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Mengubah OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "Mendaftar perubahan ke OpenGL membutuhkan memulai dari awal"
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Keahlian"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Keahlian"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Tingkatan: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Tingkatan: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Apakah anda bersungguh-sungguh ingin menghapus karakter ini?"
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Apakah anda bersungguh-sungguh ingin menghapus karakter ini?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Buat Karakter"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Tingkatan: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Uang: %d"
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Stats Karakter OK"
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Tingkatan: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "Menawarkan tukar menukar"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "Tambah"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Anda memberikan:"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "Anda memberikan:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "Ubah"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nama: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "Menyambung..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Perintah: /help"
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "Tombol Singkat"
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "Ubah"
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "Kekuatan"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "Daya/Tenaga Hidup"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "Kecerdasan"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "Ketangkasan"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "Nama:"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Pertahanan %+d"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "Serangan %+d"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "Pertahanan %+d"
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Perintah tidak dikenal."
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Tidak terdaftar"
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "Anda memberikan:"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Stats Karakter OK"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Stats Karakter OK"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Pilih jumlah item yang mau di perdagangkan"
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Perintah tidak dikenal."
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "Ketekunan"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Perintah tidak dikenal."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "Ketekunan"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "Serangan %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "Pertahanan %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Description: %s"
+#~ msgstr "Deskripsi: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Sebelumnya"
+
+#~ msgid "New"
+#~ msgstr "Buat baru"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@attack|Serang%s@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@cancel|Batal@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Melengkapi@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@use|Gunakan@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Buang@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Pisah@@"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Ambil %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Radius gulungan"
diff --git a/po/it.po b/po/it.po
new file mode 100644
index 000000000..53d8fed94
--- /dev/null
+++ b/po/it.po
@@ -0,0 +1,5676 @@
+# Italian translation of The Mana World.
+# Copyright (C) 2007 The Mana World Development Team
+# This file is distributed under the same license as the The Mana World package.
+# Eugenio Favalli <eugeniofavalli@gmail.com>, 2007.
+# , fuzzy
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: The Mana World 0.1.0\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-02-18 14:01+0000\n"
+"Last-Translator: Gabriel Rota <gabriel.rota@gmail.com>\n"
+"Language-Team: Italian\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Impostazioni"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Connessione al server della mappa..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Autenticazione"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Scelta Personaggio"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Connessione al server della mappa..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Server"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Errore"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Password:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Cambia"
+
+#: src/client.cpp:1093
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Cancella registrazione"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Host di aggiornamento non valido: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Errore durante la creazione della directory degli aggiornamenti"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Comando sconosciuto."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Aiuto --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Mostra questo aiuto"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Mostra il nome della mappa"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Mostra il numero di utenti in linea"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Scrivi un messaggio riguardante te"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Pulisce questa finestra"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Invia un messaggio privato ad un utente"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Equivale a \"msg\""
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Equivale a \"msg\""
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Apre una scheda per i messaggi privati con un altro utente"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Equivale a \"query\""
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Chiude la scheda del sussurro"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Disprezza %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Mostra tutti i canali pubblici"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Partecipa o crea un canale"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Crea un nuovo party"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Crea un nuovo party"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Invita un utente nel party"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Determina se <invio> apre/chiude il registro della chat"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Ottiene una lista dei giocatori presenti (inviato al registro di "
+"chat, se è attivo)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Annuncio globale (solo GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Chiude la scheda del sussurro"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Invia un messaggio privato ad un utente"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Per maggiori informazioni, digitare /help <comando>."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Comando: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Questo comando mostra una lista di tutti i comandi disponibili."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Comando: /help <comando>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Questo comando mostra l'aiuto per <comando>."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Comando: /announce <msg>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** disponibile solo ai GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Questo comando invia un messaggio <msg> a tutti i giocatori in linea."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Comando: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Questo comando pulisce il registro della chat precedente"
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Comando: /item <politica>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Questo comando mostra il numero dei giocatori attualmente connessi."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Comando: /join <canale>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Questo comando effettua l'accesso al <canale> specificato."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Se il <canale> non esiste, viene creato."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Comando: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Questo comando mostra una lista di tutti i canali."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Comando: /me <messaggio>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Questo comando mostra agli altri ciò che stai <messaggio>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Comando: /msg <nick> <messaggio>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Comando: /whisper <nick> <messaggio>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Comando: /w <nick> <messaggio>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Questo comando invia il testo <messaggio> all'utente <nick>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Se il <nick> contiene spazi, racchiuderlo tra virgolette (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Comando: /query <nick>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Comando: /q <nick>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Questo comando tenta di creare una scheda per i sussurri tra te e l'utente "
+"<nick>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Comando: /w <nick> <messaggio>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Questo comando imposta l'argomento a <messaggio>"
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Comando: /create <nome-gruppo>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Questi comandi creano un nuovo gruppo chiamato <nome-gruppo>."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Comando: /create <nome-gruppo>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Questi comandi creano un nuovo gruppo chiamato <nome-gruppo>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Comando: /party <nick>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Questo comando invita <nick> nel tuo party."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Comando: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Questo comando crea una lista dei giocatori che hai attorno e la invia o "
+"alla registrazione della chat se attivata, o alla chat altrimenti."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Comando: /toggle <stato>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Questo comando imposta la chiusura del registro della conversazione premendo "
+"il tasto Invio oppure automaticamente."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<stato> può essere \"1\", \"yes\", \"true\" per attivarlo, oppure \"0\", \"no"
+"\", \"false\" per disattivarlo."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Comando: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Questo comando mostra se il tasto Invio è attivato o meno."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Comando: /item <politica>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Comando: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Questo comando mostra il nome della mappa attuale."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Questo comando mostra il numero dei giocatori attualmente connessi."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Digitare /help per una lista dei comandi."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Impossibile inviare un sussurro vuoto!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Impossibile creare una scheda per sussurrare a \"%s\"! Esiste già, oppure "
+"sei tu."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Richiesta per accedere al canale %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Manca il nome del party."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Manca il nome del party."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Invio attiva/disattiva la conversazione."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "I messaggi chiudono la conversazione."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "\"Invio\" adesso attiva/disattiva la conversazione."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "I messaggi adesso chiudono la conversazione."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Amico"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Disprezzato"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutrale"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Il bisbiglio non può essere inviato, ignorato dall'utente."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Party creato con successo."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Il bisbiglio non può essere inviato, ignorato dall'utente."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Il bisbiglio non può essere inviato, ignorato dall'utente."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Il bisbiglio non può essere inviato, ignorato dall'utente."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Party creato con successo."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Il bisbiglio non può essere inviato, ignorato dall'utente."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Le opzioni per /%s sono \"yes\" (sì), \"no\", \"true\" (vero), \"false"
+"\" (falso), \"1\", \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Generale"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Schermata salvata in ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Salvataggio della schermata fallito!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "La connessione al server è caduta. Il programma sarà ora chiuso."
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Errore di rete"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Le richieste di scambio in arrivo saranno ignorate"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Le richieste di scambio in arrivo saranno accettate"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Impossibile caricare la mappa"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Errore durante il caricamento di %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Party (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Gilde"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Finestra della Chat"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Nome"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Attacco"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Parla"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Muoviti verso l'alto"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Reimposta"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Compra"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Prezzo: %s / Totale: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Esci"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Massimo"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Negozio"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Vendi"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Annulla"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Cambia l'indirizzo Email"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Account: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Inserire il nuovo indirizzo email due volte:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Il nome utente deve contenere almeno %d caratteri."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Il nome utente deve avere meno di %d caratteri."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Il nuovo indirizzo e-mail esiste già."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Cambia la Password"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Password:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Inserire la nuova password due volte:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "La password deve essere lunga almeno %d caratteri."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "La password deve contenere meno di %d caratteri."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Crea Personaggio"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Nome:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Colore Capelli:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Stile Capelli:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Crea"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Maschio"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Femmina"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Distribuire %d punti"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Il tuo nome deve contenere almeno 4 caratteri."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Statistiche personaggio OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Rimuovere %d punti"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Conferma la cancellazione del personaggio"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Sei sicuro di voler cancellare questo personaggio?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Gestione dell'account e del personaggio"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Cancella registrazione"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Cambia l'indirizzo Email"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Elimina"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Chiudi"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Predefinito"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Amico"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Verde: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Blu: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "Basso"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Collegamento ipertestuale"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Deviato"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Arcobaleno"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Arcobaleno"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Arcobaleno"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "Sono presenti %d giocatori."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Sussurra a %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Sì"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "No"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignorato"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Volume musica"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Nome: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Mini mappa"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Effetti particelle"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Statistiche personaggio OK"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Il giocatore colpisce il mostro"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Muoviti verso sinistra"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Punta Giocatore"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Punta Giocatore"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Punta Giocatore"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Punta Giocatore"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Cursore personalizzato"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Equipaggiamento"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Rimuovi"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Aiuto"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Chiudi"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventario"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Storage"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Slot:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Equipaggia"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Usa"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Lascia"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Dividi"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Peso:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Recupera"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Lascia"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Tutti"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Seleziona la quantità di oggetti da scambiare."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Seleziona la quantità di oggetti da lasciare."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Selezionare la quantità di oggetti da riporre."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Seleziona la quantità di oggetti da ritirare"
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Seleziona la quantità di oggetti da dividere."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Errore sconosciuto"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Peso: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Finestra degli Status"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Reimposta"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Reimposta"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Livello: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Esperienza:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Muoviti verso sinistra"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Chiudi"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Autenticazione"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Ricorda nome utente"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registra"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Mappa"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "In attesa del server"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Prossimo"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Invia"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Asta"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Prossimo"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "A:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Invia"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "La lettera non è valida oppure non è stato possibile inviarla."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Soldi: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Rimuovi"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Scambia Con %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Attacca %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@usa|Usa@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Cancella@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+msgid "@@friend|Befriend@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Disprezza %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignora %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@usa|Usa@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Non ignorare %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Ignora completamente %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Invita un utente nel party"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Espelli giocatore@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Espelli giocatore@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Invita un utente nel party"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Espelli giocatore@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Non ignorare %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@usa|Usa@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Attacca %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Espelli giocatore@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Aggiungi nome alla conversazione@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Cancella@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Raccogli %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Aggiungi alla chat@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@usa|Usa@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Evidenziazione scheda"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Evidenziazione scheda"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Cambia"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Storage"
+
+#: src/gui/popupmenu.cpp:1094
+msgid "Store half"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Storage"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Recupera"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Recupera"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Recupera"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Aggiungi alla chat@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Cambia server"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Cambia personaggio"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Conferma:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Il nome utente deve contenere almeno %d caratteri."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Il nome utente deve avere meno di %d caratteri."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "La password deve essere lunga almeno %d caratteri."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "La password deve contenere meno di %d caratteri."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Le password non corrispondono."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Scegliere il proprio server"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Porta:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Connessione..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Cursore personalizzato"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Per favore inserisci l'indirizzo e la porta del server."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "In attesa del server"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Abilita joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Abilita joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Volume effetti sonori"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Volume musica"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Nessun testo"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Impossibile acquistare."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Impossibile acquistare."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Mostra nomi"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Come appaiono i colori"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Colori"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Tipo: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statico"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulsazione"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Arcobaleno"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Gamma"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Ritardo: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Rosso: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Verde: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Blu: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Applica"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Resetta finestre"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Premi il pulsante per cominciare la calibrazione"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Calibra"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Abilita joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Ferma"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Ruota la manopola"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Tastiera"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Imposta"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Imposta"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Predefinito"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Sono stati rilevati conflitti nei tasti."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Evidenziazione"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Mostra nomi"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Abilita joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Evidenziazione"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Abilita/Disabilita Scambi"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Impossibile acquistare."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Impossibile acquistare."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Abilita joystick"
+
+#: src/gui/setup_other.cpp:169
+msgid "Show warps particles"
+msgstr ""
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relazione"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutrale"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Amico"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Disprezzato"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignorato"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Permetti scambi"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Permetti sussurri"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Sposta tutti i sussurri in schede"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Mostra nomi"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Giocatori"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Quando si ignora:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Mostra nomi"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Mostra nomi"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Punta Giocatore"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Effetti particelle"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Aiuto"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Cambia"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Per applicare le modifiche, è necessario riavviare il client."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Minuscolo"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Piccolo"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Medio"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Largo"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Nessun testo"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Testo"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Nuvolette senza nomi"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Nuvolette con nomi"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "Spento"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "Basso"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "Alto"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "medio"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "massimo"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Schermo intero"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relazione"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Cursore personalizzato"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Nomi visibili"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Effetti particelle"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "in chat"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Abilita joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Sfondo"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Limita FPS:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "Limita FPS:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Testo sovrastante"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Opacità IU"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Suoni ambientali"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Dettagli particelle"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Dimensione caratteri"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "No"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "e il ripristino della precedente è fallito."
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "e il ripristino della precedente è fallito."
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Modalità a schermo intero"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Riavvio necessario affinchè i cambiamenti abbiano effetto."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Modifica OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Applicare le modifiche ad OpenGL richiede il riavvio."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Risoluzione schermo modificata"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Impostazione effetti particelle modificato."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "I cambi saranno effettuati al cambio della mappa."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Aggiungi"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Richiesta di commercio"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s vuole commerciare con te, accetti?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Abilità"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Su"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Punti abilità: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Punti abilità: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Abilità"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Livello: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Livello: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Gilda"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "La gilda è stata creata."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Crea una Gilda"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Sei sicuro di voler uscire?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Party"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Invita un utente nel party"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Invita un utente nel party"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Sei sicuro di voler uscire?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Crea una Gilda"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Crea Personaggio"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Invita un utente"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Largo"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Invito accettato da %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Invito rifiutato da %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Invito accettato da %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Invito rifiutato da %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Errore durante la creazione della gilda."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Gilda"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Scegliere il proprio server"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Ricevuta richiesta di party, ma ne esiste già una."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s ti ha invitato ad unirti al party %s."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Accetta invito nel party"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Ricevuta richiesta di party, ma ne esiste già una."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s ti ha invitato ad unirti al suo party."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s ti ha invitato ad unirti al party %s."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s ti ha invitato ad unirti al suo party."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s ti ha invitato ad unirti al party %s."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Accetta invito nel party"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Party"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Scegliere il proprio server"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Livello: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Soldi: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Esperienza:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Lavoro: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Lavoro:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Statistiche personaggio OK"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Livello: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Punti abilità: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Muoviti verso sinistra"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Permetti scambi"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Muoviti verso sinistra"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Generale"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magia"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magia"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Comando: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magia"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Comando: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Punta Giocatore"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Livello massimo"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Mostra nomi"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Inizia uno scambio"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Confermato. In attesa..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Accetta scambio"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Accettato. In attesa..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Commercia: Tu"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Commercia"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Hai ottenuto %s"
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Dai:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Cambia"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Aggiunta dell'oggetto fallita. Non puoi sovrapporre un tipo di oggetto sulla "
+"finestra."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Non hai abbastanza denaro."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nome: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Aggiornamento..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Connessione..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Gioca"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 L'aggiornamento è stato completato."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 È fortemente raccomandato"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 prova più tardi"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Completato"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Essere"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Amico"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Disprezzato"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignorato"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "Nomi dei GM"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Nomi degli altri giocatori"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Proprio nome"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Nomi dei GM"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Mostri"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Il mostro colpisce il giocatore"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Party"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Gilda"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Effetti particelle"
+
+#: src/gui/userpalette.cpp:125
+#, fuzzy
+msgid "Pickup Notification"
+msgstr "Notifica Esperienza"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Notifica Esperienza"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Il giocatore colpisce il mostro"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Il mostro colpisce il giocatore"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Nomi degli altri giocatori"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Colpo critico"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Il giocatore colpisce il mostro"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Il giocatore colpisce il mostro"
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr ""
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Perde"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Evidenziazione scheda"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Evidenziazione"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Evidenziazione scheda"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Il mostro colpisce il giocatore"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Lista gli utenti nel canale corrente"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Setta l'argomento del canale corrente"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Abbandona un canale"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Trasforma un utente in operatore"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Espelle un utente dal canale"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Comando: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Questo comando mostra gli utenti nel canale."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Comando: /topic <messaggio>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Questo comando imposta l'argomento a <messaggio>"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Comando: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Con questo comando si esce dal canale corrente."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Se sei l'ultima persona nel canale, questo sarà cancellato."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Comando: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Questo comando rende <nick> un operatore del canale"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Gli operatori possono rendere operatiori o cacciare gli altri utenti dal "
+"canale."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Comando: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Questo comando fa uscire <nick> dal canale."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Specificare un utente da rendere operatore!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Si deve specificare un utente da rimuovere!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Annuncio generale:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Annuncio generale da %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s sospira: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Chiude la scheda del sussurro"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Comando: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Questo comando chiude la scheda del sussurro attiva."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Comando: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Questo comando mostra il numero dei giocatori attualmente connessi."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "Questo comando attiva la registrazione della chat nel file <nome file>"
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Finestra della Chat"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+msgid "Smiles"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Stato"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Scorciatoia"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Seleziona OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Cambia"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Scegliere il proprio server"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Muoviti verso l'alto"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Muoviti verso il basso"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Muoviti verso sinistra"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Muoviti verso destra"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Mirino e attacco"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Muoviti verso sinistra"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Ferma attacco"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Punta Più vicino"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Punta NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Punta Giocatore"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Raccogli"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Nascondi la Finestra"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Siediti"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Screenshot"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Abilita/Disabilita Scambi"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Cambia l'indirizzo Email"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Scorciatoia %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Scorciatoia %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Finestra di Aiuto"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Finestra degli Status"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Finestra dell'Inventario"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Finestra dell'Equipaggiamento"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Finestra delle Capacità"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Finestra Minimappa"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Finestra della Chat"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Finestra Scorciatoia Oggetti"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Finestra del Setup"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Finestra di debug"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Finestra delle Capacità"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Finestra degli Status"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Finestra del Setup"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Nascondi la Finestra"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Finestra degli Status"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Comando: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Finestra della Chat"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Scheda Chat Precedente"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Scheda Chat Successiva"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Attiva Chat"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Scorre la chat in alto"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Scorre la chat in basso"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Scheda Chat Precedente"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Scheda Chat Successiva"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Scheda Chat Precedente"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Scheda Chat Successiva"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Seleziona OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignora input 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignora input 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Muoviti verso il basso"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Muoviti verso sinistra"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Muoviti verso destra"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Cambia personaggio"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Server"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Mirino e attacco"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Cambia la Password"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Cambia l'indirizzo Email"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Abilita/Disabilita Scambi"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+"Se non vengono risolti, il gioco potrebbe comportarsi in modo inaspettato."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Impossibile raccogliere l'oggetto."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Hai raccolto %s [@@%d|%s@@]."
+msgstr[1] "Hai raccolto %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Hai ottenuto %s"
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opzioni"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : File di configurazione da utilizzare"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : File di configurazione da utilizzare"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Mostra la versione"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Mostra questo aiuto"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : File di configurazione da utilizzare"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Accedi con questo nome utente"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Accedi con questa password"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Accedi con questo personaggio"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Nome o IP del server di login"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -s --server : Nome o IP del server di login"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Usa questo host per gli aggiornamenti"
+
+#: src/main.cpp:61
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Salta i download degli update"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Diectory dalla quale caricare i dati di gioco"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Directory da usare come home directory"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Directory da usare come home directory"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Disabilita OpenGL per questa sessione"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Forza"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Forza %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Agilità"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Agilità %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Destrezza"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Destrezza %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Vitalità"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Vitalità %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligenza"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligenza %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Volontà:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Volontà:"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Sei morto."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+"Ci dispiace informarti che il tuo personaggio è stato ucciso in battaglia."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Non sei più così vivo."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Le fredde mani della morte stanno afferrando la tua anima."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"No, figliolo. Il tuo personaggio non è veramente morto. È... ehm... andato "
+"in un posto migliore."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Il tuo piano di spezzare le armi dei tuoi nemici colpendole con la tua gola "
+"ha fallito."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Suppongo non sia andata troppo bene."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Tristemente, nessuna traccia di te è stata mai trovata..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Annichilito."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:336
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Sei morto"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Nome utente già esistente"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Statistiche personaggio OK"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Statistiche personaggio OK"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Errore sconosciuto"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Informazioni"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Personaggio cancellato."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Seleziona la quantità di oggetti da scambiare."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Errore sconosciuto"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Nessun gameserver è disponibile."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Il giocatore colpisce il mostro"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Comando: /join <canale>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Richiesta per accedere al canale %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s si è unito al party."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Comando sconosciuto."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "La gilda è stata creata."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Errore durante la creazione della gilda."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Invito spedito."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:89
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "La registrazione è già in corso."
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Account scaduto"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Nuova password errata"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Vecchia password non corretta"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Nuovo indirizzo email errato"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Vecchio indirizzo email errato"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Il nuovo indirizzo e-mail esiste già."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "La varsione del client è troppo vecchia"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Nome utente o password errati"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Account scaduto"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Nome utente, password o indirizzo email errati"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Nome utente già esistente"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Indirizzo email già esistente"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s si è unito al party."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s ha rifiutato il tuo invito."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignora la richiesta di commercio."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s vuole commerciare con te, accetti?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Commerciando con %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Scambio cancellato."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Scambio completato."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Espulsione fallita!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Kick riuscito!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Niente da vendere."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Grazie per l'acquisto."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Impossibile acquistare."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Grazie per la vendita."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Impossibile vendere."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Impossibile usare questo ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Errore sconosciuto"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+"Creazione del personaggio fallita. E' molto probabile che il nome sia già "
+"stato preso."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Personaggio cancellato."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Cancellazione del personaggio fallita."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Forza:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agilità:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitalità:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligenza:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Destrezza:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Fortuna:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Il bisbiglio non può essere inviato, l'utente è offline."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Il bisbiglio non può essere inviato, ignorato dall'utente."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Giocatore"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Giocatore"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "I canali non sono supportati!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Nome"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Richiesta di commercio"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Forza %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Agilità %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Vitalità %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligenza %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Destrezza %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Fortuna %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Autenticazione non riuscita"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Nessun server disponibile"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Qualcun'altro sta cercando di usare questo account"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Questo accaunt ha già effettuato l'accesso"
+
+#: src/net/tmwa/generalhandler.cpp:148
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Accesso duplicato"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Errore di connessione sconosciuto"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Disconnesso dal server!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Fortuna"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Difesa:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "Attacco Magico:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "Difesa Magica:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Accuratezza:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Evasione:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Colpo critico"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Attacco %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Attacco %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Il mostro colpisce il giocatore"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Mostra questo messaggio di aiuto"
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Invita un giocatore al tuo party"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Abbandona il party"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Escludi qualcuno dal gruppo in cui ti trovi"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Comando: /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Questo comando invita <nick> nel tuo party."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Comando: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Questo comando fa abbandonare il gruppo ad un giocatore."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Errore durante la creazione della gilda."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Errore sconosciuto"
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Gilda"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Gilda"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Livello: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Livello massimo"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Gilda"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "La gilda è stata creata."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "La gilda è stata creata."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s è ora un membro del tuo party."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Hai lasciato il party."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s ha lasciato il tuo party."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s è ora un membro del tuo party."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Invita un giocatore al tuo party"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Abbandona il party"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Escludi qualcuno dal gruppo in cui ti trovi"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+"/item > Mostra/modifica le opzioni di condivisione degli oggetti nel gruppo"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+"/item > Mostra/modifica le opzioni di condivisione dei punti esperienza nel "
+"gruppo"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Questo comando fa abbandonare il gruppo ad un giocatore."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Comando: /item <politica>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+"Questo comando modifica la politica di condivisione degli oggetti nel gruppo."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<politica> può essere uno fra \"1\", \"yes\", \"true\" per abilitare la "
+"condivisione degli oggetti o \"0\", \"no\", \"false\" per disabilitarla."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Comando: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "Questo comando mostra la corrente politica di condivisione oggetti."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Comando: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Abilitata la condivisione degli oggetti."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Disabilitata la condivisione degli oggetti"
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Impossibile condividere gli oggetti."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Abilitata la condivisione degli oggetti."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Abilitata la condivisione dell'esperienza."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Disabilitata la condivisione dell'esperienza."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Impossibile condividere l'esperienza."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Abilitata la condivisione dell'esperienza."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Impossibile equipaggiare."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Account non trovato. Perfavore riesegui il login."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Nuova password troppo corta"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Cancella registrazione"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Password errata"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Account scaduto"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Respinto dal server"
+
+#: src/net/tmwa/loginhandler.cpp:173
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Questo nome utente è già stato preso"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Impossibile vendere."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Connessione al server della mappa..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Non puoi creare un party."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Party creato con successo."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s è già membro di un party."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s ha rifiutato il tuo invito."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s è ora un membro del tuo party."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Hai lasciato il party."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s ha lasciato il tuo party."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s non è nel tuo party!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Inserisci un gettone per continuare."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Non sei morto. Stai riposando."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Non sei più."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Hai smesso di esistere."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Sei spirato e sei andato a incontrare il tuo creatore."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Sei cadavere."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Privato della vita, riposi in pace."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "I tuoi processi metabolici sono storia ora."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Hai tirato le cuoia."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Sei un ex-giocatore."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Messaggio"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Stai trasportando più della metà del tuo peso. Non puoi recuperare le "
+"energie."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Stai trasportando più della metà del tuo peso. Non puoi recuperare le "
+"energie."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Hai raccolto "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Hai ottenuto %s"
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Equipaggia prima le frecce"
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Scambio fallito!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Creazione della chat fallita!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Non puoi unirti al party!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Non hai ancora raggiunto un livello abbastanza alto."
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "HP insufficienti!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "SP insufficienti!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Non puoi farlo ora!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Sembra tu abbia bisogno di più denaro... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Non puoi usare questa abilità con questo tipo di arma!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Hai bisogno di un'altra gemma rossa!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Hai bisogno di un'altra gemma blu!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Huh? Cos'è quello?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Il veleno non ha avuto effetto..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:184
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Ignora completamente %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Attacco %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Difesa %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "PF %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "PM %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Oggetto sconosciuto"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Dettagli particelle"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Suoni ambientali"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Scorciatoia %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Il giocatore colpisce il mostro"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Nome: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "Mini mappa"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record> Inizia la registrazione della chat in un file esterno"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Comando: /record <nome file>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Questo comando attiva la registrazione della chat nel file <nome file>"
+
+#~ msgid "Command: /record"
+#~ msgstr "Comando: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Questo comando termina la sessione di registrazione."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Numero dei presenti registrato."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Registrazione terminata."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Nessuna registrazione in corso."
+
+#~ msgid "Already recording."
+#~ msgstr "La registrazione è già in corso."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Inizio registrazione..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Impossibile iniziare la registrazione."
+
+#~ msgid "Recording..."
+#~ msgstr "Registrazione..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Ferma registrazione"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Trova il percorso sino al mouse"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Esperienza:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Soldi: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Lavoro:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Livello: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Party creato con successo."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Il bisbiglio non può essere inviato, ignorato dall'utente."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : File di configurazione da utilizzare"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : File di configurazione da utilizzare"
+
+#~ msgid "Sound"
+#~ msgstr "Suono"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Accesso negato"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Cancellazione del personaggio fallita."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s ti ha invitato ad unirti al suo party."
+
+#~ msgid "Willpower:"
+#~ msgstr "Volontà:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Il server è pieno"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Commerciando con %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Sussurro"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Amico con %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Disprezzato"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Ignora completamente %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Invita %s ad entrare nella tua gilda@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Invita %s ad entrare nel tuo party@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Espulsione fallita!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Parla a %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Espelli mostro@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Raccogli"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Non puoi inviare un messaggio vuoto!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Impossibile equipaggiare."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Ombra del testo"
+
+#~ msgid "Text Outline"
+#~ msgstr "Contorno del testo"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Etichetta della barra di progresso"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "L'oggetto è troppo costoso"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "L'oggetto è equipaggiato"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Giocatore"
+
+#~ msgid "Whisper"
+#~ msgstr "Sussurro"
+
+#~ msgid "Is"
+#~ msgstr "è"
+
+#~ msgid "Server"
+#~ msgstr "Server"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Tipo di oggetto sconosciuto"
+
+#~ msgid "Generics"
+#~ msgstr "Generici"
+
+#~ msgid "Hats"
+#~ msgstr "Cappelli"
+
+#~ msgid "Usables"
+#~ msgstr "Utilizzabili"
+
+#~ msgid "Shirts"
+#~ msgstr "Magliette"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Armi da mano singola"
+
+#~ msgid "Pants"
+#~ msgstr "Pantaloni"
+
+#~ msgid "Shoes"
+#~ msgstr "Scarpe"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Armi da mano singola"
+
+#~ msgid "Shields"
+#~ msgstr "Scudi"
+
+#~ msgid "Rings"
+#~ msgstr "Anelli"
+
+#~ msgid "Necklaces"
+#~ msgstr "Collane"
+
+#~ msgid "Arms"
+#~ msgstr "Armi"
+
+#~ msgid "Ammo"
+#~ msgstr "Munizioni"
+
+#~ msgid "HP Bar"
+#~ msgstr "Barra HP"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 della barra degli HP"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 della barra degli HP"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 della barra degli HP"
+
+#~ msgid "no"
+#~ msgstr "no"
+
+#~ msgid "Buddy"
+#~ msgstr "Amico"
+
+#~ msgid "Buddy List"
+#~ msgstr "Lista degli amici"
+
+#~ msgid "Description: %s"
+#~ msgstr "Descrizione : %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effetto : %s"
+
+#~ msgid "Previous"
+#~ msgstr "Precedente"
+
+#~ msgid "New"
+#~ msgstr "Nuovo"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Livello lavoro: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Present: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Esci dalla Gilda"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Recent:"
+#~ msgstr "Recenti:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Invoca l'incantesimo Test Spell 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Invoca l'incantesimo Test Spell 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Invoca l'incantesimo Test Spell 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Armi da due mani"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Togli@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Equipaggia@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Lascia@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Lascia@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Selezione server"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Impossibile passare a modalità "
+
+#~ msgid "windowed"
+#~ msgstr "finestra"
+
+#~ msgid "fullscreen"
+#~ msgstr "schermo intero"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Abilità misteriosa"
+
+#~ msgid "Weapons"
+#~ msgstr "Armi"
+
+#~ msgid "Stats"
+#~ msgstr "Statistiche"
+
+#~ msgid "Total"
+#~ msgstr "Totale"
+
+#~ msgid "Cost"
+#~ msgstr "Costo"
+
+#~ msgid "Attack:"
+#~ msgstr "Attacco:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Riflessi:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Punti Stato rimanenti: %d"
+
+#~ msgid "curl error "
+#~ msgstr "errore di curl "
+
+#~ msgid " host: "
+#~ msgstr " host: "
+
+#~ msgid "Buddys"
+#~ msgstr "Amici"
+
+#~ msgid "Party Window"
+#~ msgstr "Finestra del Party"
+
+#~ msgid "Unarmed"
+#~ msgstr "Disarmato"
+
+#~ msgid "Knife"
+#~ msgstr "Coltello"
+
+#~ msgid "Sword"
+#~ msgstr "Spada"
+
+#~ msgid "Staff"
+#~ msgstr "Staffa"
+
+#~ msgid "Whip"
+#~ msgstr "Frusta"
+
+#~ msgid "Bow"
+#~ msgstr "Arco"
+
+#~ msgid "Mace"
+#~ msgstr "Mazza"
+
+#~ msgid "Axe"
+#~ msgstr "Ascia"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Capacità sconosciuta"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " non può essere creato, perché non esiste! Uscita."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Impossibile impostare "
+
+#~ msgid " video mode: "
+#~ msgstr " modalità video: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Connessione al server del personaggio..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Connessione al server dell'account..."
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Comando: /new <nome-gruppo>"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Raccogli %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Raggio dello scroll"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Lentezza dello scroll"
diff --git a/po/ja.po b/po/ja.po
new file mode 100644
index 000000000..74ebc683c
--- /dev/null
+++ b/po/ja.po
@@ -0,0 +1,3991 @@
+# Japanese translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2010-02-28 13:40+0000\n"
+"Last-Translator: swimmy <Unknown>\n"
+"Language-Team: Japanese <ja@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "設定"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "マップサーバと接続中…"
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "ログイン"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "キャラを選択"
+
+#: src/client.cpp:768
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "マップサーバと接続中…"
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "エラー"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "パスワード:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "変更"
+
+#: src/client.cpp:863
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "本メンバーが無事に昇進された。"
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "登録解除"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "無効なアップデートホスト: "
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr "更新フォルダの作成エラー"
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "不明なコマンド"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-ヘルプ-"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/helpを入力すると、ヘルプメニューを表示します。"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where を入力すると、現在のマップ名を表示します。"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who を入力すると、オンラインであるユーザーの数を表示します。"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me を入力すると、自分に関する情報を教えます。"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear を入力すると、チャットウィンドウをきれいにします。"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg を入力すると、他のユーザーにプライベートメッセージを送信します。"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper は/msgと同じです。"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w は/msgと同じです。"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+"/query を入力すると、他のユーザーとのプライベートなチャットタブを作成します。"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q は/queryと同じです。"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list を入力するとすべての公共なチャンネルを表示します。"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+"/join (+チャンネル名)をと入力すると、新しいチャンネルを作成するか、既にある"
+"チャンネルに参加します。"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/createで新パーティ作成"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+"/party (+ユーザー名)を入力すると、そのユーザーにパーティ招待を送ります。"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/recordを入力すると、外部のファイルでチャットを記録します。"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+"/toggleを入力すると、<リターン>がチャットログを留めておくかどうかを決定しま"
+"す。"
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/presentを入力すると、現在のプレイヤーリストを表示します。(記録している場合"
+"は、チャットログに送信されます。)"
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+"/announce を入力すると、グローバルアナウンスをすることができます。(ゲームマ"
+"スターのみ)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "もっと情報を得たい場合は、/help (コマンド)と入力してください。"
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "コマンド: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "このコマンドは有効なすべてのコマンドを表示します。"
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "コマンド: /help <コマンド>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "このコマンドは入力したコマンドのヘルプを表示します。"
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "コマンド: /announce <メッセージ>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** GMに限り有効 ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"このコマンドでは、オンラインである全てのプレイヤーにメッセージを送信します。"
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "コマンド: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "このコマンドでは、以前のチャットのログを消去します。"
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "コマンド: /item <ポリシ>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "このコマンドは現在オンライン状態であるプレイヤーの数を表示します。"
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "コマンド: /join <チャンネル>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "このコマンドで、入力したチャンネルに参加します。"
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "もしそのチャンネルがない場合は、新しく作られます。"
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "コマンド: /list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "このコマンドでは、チャンネルリストを表示します。"
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "コマンド: /me <メッセージ>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr "このコマンドでは、他の人に入力した状態であることを教えます。"
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "コマンド: /msg <ニックネーム><メッセージ>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "コマンド: /whisper <ニックネーム> <メッセージ>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "コマンド: /w <ニックネーム> <メッセージ>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "このコマンドでは、メッセージを入力した人へ送信します。"
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"入力するニックネームにスペースが入っている場合、ダブルコーテーション(\")で囲"
+"んでください。"
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "コマンド: /query <ニックネーム>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "コマンド: /q <ニックネーム>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr "このコマンドでは、入力したプレイヤーとのチャットタブを作成します。"
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "コマンド: /create <パーティ名>"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "本コマンドでは、引数の名前で新パーティ作成"
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "コマンド: /party <ニックネーム>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr "このコマンドでは、入力したプレイヤーを自分のパーティーに招待します。"
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "コマンド: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+"このコマンドは見えている範囲内にいるプレイヤーのリストを得て、記録しているな"
+"ら記録ログに、そうでなければチャットログに送られます。"
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "コマンド: /record <ファイル名>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr "このコマンドでは、入力したファイルにチャットログの記録を開始します。"
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "コマンド: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr "このコマンドでは、記録セッションを終了させます。"
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr "コマンド: /toggle <状態>"
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"このコマンドはリターンキーがチャットログを留めておくか、もしくはチャットログ"
+"が自動的に消えるかどうかを設定します。"
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<状態>の部分は切り替えをオンにするには\"1\",\"yes\",\"true\"のどれか一つを、"
+"オフにするには\"0\",\"no\",\"false\"のどれかになります。"
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr "コマンド: /toggle"
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr "このコマンドでは、トグルのスイッチ状態を表示します。"
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "コマンド: /item <ポリシ>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "コマンド: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "このコマンドは現在地点のマップの名前を表示します。"
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "コマンド: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "このコマンドは現在オンライン状態であるプレイヤーの数を表示します。"
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "/help を入力すると、可能なコマンドのリストを表示します。"
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr "空のメッセージを送信することはできません!"
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"%sと言うメッセージタブの作成ができません!それはもう既に存在しているか、自分"
+"です。"
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "%sというチャンネルへの参加を要求しています。"
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr "パーティ名がない。"
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr "リターンはチャットを留めておきます。"
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr "メッセージはチャットを閉じます。"
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr "リターンはこれからチャットを留めておきます。"
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr "メッセージはこれからチャットを閉じます。"
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+#, fuzzy
+msgid "Player successfully ignored!"
+msgstr "パーティ作成成功"
+
+#: src/commandhandler.cpp:486
+#, fuzzy
+msgid "Player could not be ignored!"
+msgstr "プライベートなメッセージが送れなかった、ユーザに無視された。"
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "プライベートなメッセージが送れなかった、ユーザに無視された。"
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"/%sへの可能なオプションは:\"yes\", \"no\", \"true\", \"false\", \"1\", \"0"
+"\"。"
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "一般"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "~/にスクリーンショットを保存しました。"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "スクリーンショットを保存することに失敗しました!"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "サーバが切断されたので、プログラムは終了します。"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "ネットワークエラー"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr "他人からのトレードリクエストを無視します。"
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "他人からのトレードリクエストを受け入れます。"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "マップをロードすることができませんでした。"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "%sをロードしている間にエラーが起きました。"
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "パーティ (%s)"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "買う"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "価格:%s /合計:%s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "終了"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "最大"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "店"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "売る"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "キャンセル"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "メールアドレスを変える。"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "アカウント: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "新しいメールアドレスを二回入力してください:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "ユーザ名は少なくとも%d文字以上長くなくてはいけません。"
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "ユーザ名は%d文字より短くなくてはいけません。"
+
+#: src/gui/changeemaildialog.cpp:141
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "新メールアドがもう存在している。"
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "パスワードの変更"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "パスワード:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "新しいパスワードを二回入力してください:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "パスワードは少なくとも%d文字以上長くなくてはいけません。"
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "パスワードは%d文字より短くなくてはいけません。"
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "キャラクターを作成"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "名前:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "髪の色:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "髪型:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "作成"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "男性"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "女性"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "%d ポイントを振り分けてください"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "名前には4文字以上必要です。"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "キャラクターの能力ポイント配分量は問題ありません。"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "%dポイントを取り除いてください。"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "キャラクターの削除してもよいか確認してください"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "このキャラクターを消してもよろしいでしょうか?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "アカウントとキャラクター管理"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "登録解除"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "メールアドレスを変える。"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "削除"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "閉じる"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "チャット"
+
+#: src/gui/chat.cpp:287
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "オンラインプレイヤーは%d人です。"
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr "出席者は記録ログに書かれました。"
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "%sに送信中: %s"
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "はい"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "いいえ"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, fuzzy, c-format
+msgid "Music: %s"
+msgstr "トピック:%s"
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "名前: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "小さなマップウィンドウ"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "特有の効果"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "粒子の詳細"
+
+#: src/gui/debugwindow.cpp:121
+#, fuzzy, c-format
+msgid "Ambient FX: %s"
+msgstr "環境FX"
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "装備"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "外す"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "ヘルプ"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "閉じる"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "アイテム"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "装備する"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "使う"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "落とす"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "分割する"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr "スロット"
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "重量"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "落とす"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "全て"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "交換するアイテムの量を選択してください。"
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "落とすアイテムの量を選択してください"
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr "保管するアイテムの量を選択してください。"
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr "取り出すアイテムの量を選択してください。"
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "分割するアイテムの量を選択してください。"
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "重量: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "ログイン"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "ユーザネームを保存する"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "登録する"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "サーバ"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "地図"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "サーバを待っています…"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "次へ"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr "決定"
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "リセット"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "次へ"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr "宛先:"
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "送信する"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "文字か差出人が無効なので送信に失敗しました。"
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "外す"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "テキスト"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "文字の影"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr "文字の外線"
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr "進行状況バーのラベル"
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "背景色"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr "強調"
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr "タブの強調"
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "アイテムが買えない"
+
+#: src/gui/palette.cpp:94
+#, fuzzy
+msgid "Item Is Equipped"
+msgstr "アイテムが装備されている"
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr "ゲームマスター"
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "プレイヤー"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr "プライベートメッセージ"
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr "等しい"
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "パーティー"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr "ギルド"
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "サーバ"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr "ロガー"
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr "ハイパーリンク"
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr "人"
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "他のプレイヤー名"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr "自分の名前"
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "ゲームマスター名"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "NPCたち"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "モンスター"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr "不明なアイテムタイプ"
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr "非使用アイテム"
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "帽子"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr "回復アイテム"
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "シャツ"
+
+#: src/gui/palette.cpp:119
+#, fuzzy
+msgid "One Handed Weapons"
+msgstr "武器1"
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "ズボン"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "靴"
+
+#: src/gui/palette.cpp:122
+#, fuzzy
+msgid "Two Handed Weapons"
+msgstr "武器1"
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "盾"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "指輪"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "首飾り"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr "腕パーツ"
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "矢、弾薬など"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr "特有の効果"
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr "収集通知"
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr "経験値通知"
+
+#: src/gui/palette.cpp:133
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "プレイヤーがモンスターをアタックした時"
+
+#: src/gui/palette.cpp:135
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "モンスターがプレイヤーをアタックした時"
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr "クリティカルヒット"
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr "ミス"
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr "HPバー"
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr "HPが3/4のとき"
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr "HPが1/2のとき"
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr "HPが1/4のとき"
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "%sと取引中"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "攻撃力 %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "プライベートメッセージ"
+
+#: src/gui/popupmenu.cpp:101
+#, fuzzy, c-format
+msgid "Befriend %s"
+msgstr "@@friend|%sと友達になる@@"
+
+#: src/gui/popupmenu.cpp:106
+#, fuzzy, c-format
+msgid "Disregard %s"
+msgstr "無視"
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "無視する"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, fuzzy, c-format
+msgid "Completely ignore %s"
+msgstr "@@Ignore|%sを完璧に無視する@@"
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, fuzzy, c-format
+msgid "Invite %s to join your guild"
+msgstr "@@guild|%sにギルドへの参加の招待を送る@@"
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "@@party|%sにパーティへの参加の招待を送る@@"
+
+#: src/gui/popupmenu.cpp:144
+#, fuzzy
+msgid "Kick player"
+msgstr "キック失敗"
+
+#: src/gui/popupmenu.cpp:153
+#, fuzzy, c-format
+msgid "Talk to %s"
+msgstr "@@talk|%sと会話@@"
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "@@admin-kick|モンスターを追い出す@@"
+
+#: src/gui/popupmenu.cpp:174
+#, fuzzy
+msgid "Add name to chat"
+msgstr "@@name|名前をチャットに追加@@"
+
+#: src/gui/popupmenu.cpp:191
+#, fuzzy, c-format
+msgid "Pick up %s"
+msgstr "拾う"
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|チャットに追加@@"
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr "保存"
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr "取り戻す"
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "サーバーを切り替える"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "キャラクターを切り替える"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr "記録を終えます。"
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr "現在記録していません。"
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr "既に記録しています。"
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr "記録を始めます…。"
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr "記録を開始することに失敗しました。"
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr "記録しています…。"
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr "記録を停止"
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "確認:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "Eメール:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "ユーザ名は少なくとも%d文字以上長くなくてはいけません。"
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "ユーザ名は%d文字より短くなくてはいけません。"
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "パスワードは少なくとも%d文字以上長くなくてはいけません。"
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "パスワードは%d文字より短くなくてはいけません。"
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "パスワードが一致していません。"
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "サーバーを選んでください。"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "サーバ:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "ポート:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "サーバ:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "接続しています..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "カスタムカーソル"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "サーバのアドレスとポート番号を両方入力してください。"
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "サーバを待っています…"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "音"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "オーディオ"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Sfx音量"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "音楽の音量"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "テキストなし"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr "これがその色がどのように見えるかです。"
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "色彩"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "種類 "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr "穏やか"
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "点滅"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "カラフル"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "スペクトル"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "遅れ: "
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "赤色: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "緑色: "
+
+#: src/gui/setup_colors.cpp:137
+#, fuzzy
+msgid "Blue:"
+msgstr "青色: "
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "適用"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "ウィンドウをリセットする"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "ボタンを押すと較正が始まります。"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "変化させる"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "ジョイスティックを使用可能にする"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "ジョイスティック"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "停止"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "スティックを回転させる"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "キーボード"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "割り当てる"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "標準に戻す"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr "キーが重複しています。"
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "名前"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr "関係"
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "普通"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "友達"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr "無視"
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "無視する"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "交換を承認する"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr "プライベートメッセージを受け取ることを承認する"
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr "プライベートメッセージをタブに出す。"
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "名前を表示"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "プレイヤー"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr "無視の際には:"
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr "とても小さい"
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "小さい"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "中"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "大"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "テキストなし"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr "バブル、名前表示なし"
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr "バブル、名前表示あり"
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "オフ"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "低"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "高"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "中"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "最大"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "フールスクリーン"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "カスタムカーソル"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr "名前を表示する"
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr "粒子効果"
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "名前を表示"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr "ピックアップ通知表示"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr "チャット中"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr "画面内で"
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS限界値:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "ビデオ"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "名前を表示"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr "ヘッダーテキスト"
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "GUI不透明"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr "環境FX"
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "粒子の詳細"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "フォントサイズ"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "いいえ"
+
+#: src/gui/setup_video.cpp:381
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "現在のモードでも前のモードの復元もまた失敗しました!"
+
+#: src/gui/setup_video.cpp:387
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "現在のモードでも前のモードの復元もまた失敗しました!"
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "全画面に変更"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "設定変更のため、再起動をしてください。"
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "OpenGLを変える"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "OpenGLの設定を変更するため、再起動をしてください。"
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "スクリーンの解像度が変わりました。"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr "設定変更のため、アプリケーションを再起動してください。"
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "粒子の効果の設定が変わりました。"
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr "変化はマップがかわったときから影響します。"
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "スキル"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "上げる"
+
+#: src/gui/skilldialog.cpp:262
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "スキルポイント: %d"
+
+#: src/gui/skilldialog.cpp:314
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "スキルポイント: %d"
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "スキル"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "レベル: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "レベル: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "ギルド作成成功"
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "ギルドを作成する"
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "本当に終了してもよろしいですか?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr ""
+"/party (+ユーザー名)を入力すると、そのユーザーにパーティ招待を送ります。"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr ""
+"/party (+ユーザー名)を入力すると、そのユーザーにパーティ招待を送ります。"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "本当に終了してもよろしいですか?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr "ギルドを作成する"
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "キャラクターを作成"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "ユーザーを招待する"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "大"
+
+#: src/gui/socialwindow.cpp:394
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "%sからの招待を受け入れました。"
+
+#: src/gui/socialwindow.cpp:400
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "%sからの招待を拒否しました。"
+
+#: src/gui/socialwindow.cpp:413
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "%sからの招待を受け入れました。"
+
+#: src/gui/socialwindow.cpp:419
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "%sからの招待を拒否しました。"
+
+#: src/gui/socialwindow.cpp:463
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "ギルド作成エラー"
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "ギルド"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "サーバーを選んでください。"
+
+#: src/gui/socialwindow.cpp:497
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "パーティへの招待を受け取りましたが、もう既に存在しています。"
+
+#: src/gui/socialwindow.cpp:502
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%sはあなたを%sというパーティに招待しました。"
+
+#: src/gui/socialwindow.cpp:507
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "パーティ招待を受け入れます。"
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr "パーティへの招待を受け取りましたが、もう既に存在しています。"
+
+#: src/gui/socialwindow.cpp:529
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%sはあなたをパーティに招待しました。"
+
+#: src/gui/socialwindow.cpp:533
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%sはあなたを%sというパーティに招待しました。"
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%sはあなたをパーティに招待しました。"
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%sはあなたを%sというパーティに招待しました。"
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr "パーティ招待を受け入れます。"
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "パーティー"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "サーバーを選んでください。"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "レベル: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "GP:%s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr "経験値:"
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr "ジョブ: %d"
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr "ジョブポイント:"
+
+#: src/gui/statuswindow.cpp:194
+#, fuzzy
+msgid "HP"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:200
+#, fuzzy
+msgid "MP"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:206
+#, fuzzy
+msgid "Exp"
+msgstr "経験値:"
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "GP: %d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "ジョブポイント:"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "キャラクターの能力ポイント配分量は問題ありません。"
+
+#: src/gui/statuswindow.cpp:235
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "スキルポイント: %d"
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "レベル: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr "倉庫"
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "交換の提案"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr "確認しました。待っています…。"
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr "交換を了承する"
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr "了承しました。待っています…。"
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr "交換:あなたと"
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "交換"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "追加"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "%sを貰いました。"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "あげる物:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "変更"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"アイテムを追加することに失敗しました。アイテム一種類を一つのウインドウ上で重"
+"複して追加することは出来ません!"
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "現金不足です。"
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "名前: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "更新しています..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "接続しています..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr "プレイ"
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr "##1 アップデートは完了していません。"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr "##1 とても推奨されます。"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 もう一度やってみてください。"
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "完了"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/usersで現在いるチャンネルのユーザのリストを表示します。"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topicで現在いるのチャンネルのトピックを表示します。"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quitでチャンネルを去ります。"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/opでユーザーをチャンネルのオペレーターにします。"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kickでユーザーをチャンネルから一時的に追い出します。"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "コマンド: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "このコマンドはチャンネル内のユーザーを表示します。"
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "コマンド: /topic <メッセージ>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "このコマンドでは、トピックを設定します。"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "コマンド: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "このコマンドでは、現在いるチャンネルを去ります。"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "もしそのチャンネルの最後の人ならば、そのチャンネルは削除されます。"
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "コマンド: /op <ニックネーム>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "このコマンドでは、入力したユーザーをチャンネルのオペレータとなる"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"チャンネルのオペレーターはチャンネルからオペレーター以外のユーザーを追い出す"
+"ことができます。"
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "コマンド: /kick <ニックネーム>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "このコマンドでは、ユーザをチャンネルから追い出すことができます。"
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "オペレーターになる人が必要です!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "追い出すことができるメンバーが必要です!"
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "アナウンス:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "%sからのアナウンス:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%sからのPM: "
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr "空のチャットを送ることはできません!"
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr "/closeでプライベートメッセージのタブを閉じます。"
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr "コマンド: /close"
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+"このコマンドでは、現在開いているプライベートメッセージのタブを閉じます。"
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "コマンド: /item"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "このコマンドは現在オンライン状態であるプレイヤーの数を表示します。"
+
+#: src/gui/widgets/whispertab.cpp:94
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "このコマンドでは、入力したファイルにチャットログの記録を開始します。"
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "状態"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "ショートカット"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "OKを選択する"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "変更"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "サーバーを選んでください。"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr "上移動"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr "下移動"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr "左移動"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr "右移動"
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr "攻撃"
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr "ターゲットと攻撃"
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr "スマイリー"
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr "話す"
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr "攻撃を止める"
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "一番近い物を狙う"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr "NPCを狙う"
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr "プレイヤーを狙う"
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr "拾う"
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr "ウィンドウを隠す"
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr "座る"
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "スクリーンショット"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr "取引を可能/不可能にする"
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr "マウスまでの道を表示する"
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "アイテムショートカット: %d"
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr "ヘルプウィンドウ"
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr "ステータス・ウィンドウ"
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr "在庫ウィンドウ"
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr "装備ウィンドウ"
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr "スキルウィンドウ"
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr "小さなマップウィンドウ"
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr "チャットウィンドウ"
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr "アイテムショートカットウィンドウ"
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr "設定ウィンドウ"
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr "デバグウィンドウ"
+
+#: src/keyboardconfig.cpp:80
+#, fuzzy
+msgid "Social Window"
+msgstr "スキルウィンドウ"
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr "表情ショートカットウィンドウ"
+
+#: src/keyboardconfig.cpp:82
+#, fuzzy
+msgid "Outfits Window"
+msgstr "ステータス・ウィンドウ"
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "スマイリーショートカット: %d"
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr "トグルチャット"
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr "チャットを上にスクロールする"
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr "チャットを下にスクロールする"
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr "前のチャットタブ"
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr "次のチャットタブ"
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr "OKを選択する"
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr "インプット1無視"
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr "インプット2無視"
+
+#: src/keyboardconfig.cpp:178
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "修正しなければ、ゲームプレイが変なふるまいになります。"
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr "アイテムを拾うことができない。"
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "%s [@@%d|%s@@]を拾った。"
+msgstr[1] "%s [@@%d|%s@@]を拾った。"
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr "オプション:"
+
+#: src/main.cpp:45
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : バーション番号表示"
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help:ヘルプ表示"
+
+#: src/main.cpp:47
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file :使用されている設定ファイル"
+
+#: src/main.cpp:48
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username: 本ユーザ名でログインする。"
+
+#: src/main.cpp:49
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password :ログインに対するパスワード設定"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character :本キャラでログインする"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : ログインサーバ名あるいはIPアドレス"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : ログインサーバのポート番号"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host :本ホストは更新ホストとして使用"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default: デフォールトキャラクタサーバとキャラクタ選択"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : 更新ダウンロードをスキップする。"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data :本レポジトリからゲームデータをロードする。"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir :ホームレポジトリとして使用しているフォルダ"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir :ホームレポジトリとして使用しているフォルダ"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : 本セッションでOpenGLが使用不可"
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr "キック失敗"
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr "キック成功"
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr "売り物がございません。"
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr "買ってくださり、ありがとうございました。"
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr "購買不可能"
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr "売ってくださり、ありがとうございました。"
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr "売ること不可能"
+
+#: src/net/ea/charserverhandler.cpp:103
+#, fuzzy
+msgid "Access denied."
+msgstr "アクセス拒否"
+
+#: src/net/ea/charserverhandler.cpp:106
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "ID使用不可"
+
+#: src/net/ea/charserverhandler.cpp:109
+#, fuzzy
+msgid "Unknown failure to select character."
+msgstr "キャラクター選択時、不明なエラーが発生した。"
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "キャラクター作成失敗。本名はのう使われている。"
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr "情報"
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr "キャラクターを削除した。"
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr "キャラ削除失敗"
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "筋力:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "素早さ:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "体力:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "知性:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "敏捷:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr "運:"
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+"プライベートなメッセージが送れなかった、相手ユーザーがオフライン状態である。"
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr "プライベートなメッセージが送れなかった、ユーザに無視された。"
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "プレイヤー"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr "チャンネルはサポートされていない。"
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "名前"
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "取引要求"
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr "強さ %+d"
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr "俊敏さ%+d"
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr "活力 %+d"
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr "知能 %+d"
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr "正確さ %+d"
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr "運 %+d"
+
+#: src/net/ea/generalhandler.cpp:130
+#, fuzzy
+msgid "Authentication failed."
+msgstr "認証失敗"
+
+#: src/net/ea/generalhandler.cpp:133
+#, fuzzy
+msgid "No servers available."
+msgstr "どんなサーバでも使用不可"
+
+#: src/net/ea/generalhandler.cpp:137
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "他人が本アカウントを使用してみている。"
+
+#: src/net/ea/generalhandler.cpp:140
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "本アカウントはもうオンライン中。"
+
+#: src/net/ea/generalhandler.cpp:143
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "スピードハック発見"
+
+#: src/net/ea/generalhandler.cpp:146
+#, fuzzy
+msgid "Duplicated login."
+msgstr "重複ログイン"
+
+#: src/net/ea/generalhandler.cpp:149
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "不明な接続エラー"
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr "サーバーから切断された。"
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "強さ"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "素早さ"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "活力"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "知能"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "器用さ"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "運"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "防御力:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "魔法攻撃力:"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "魔法防御力:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "命中率(%):"
+
+#: src/net/ea/generalhandler.cpp:228
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "回避率(%):"
+
+#: src/net/ea/generalhandler.cpp:229
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "クリティカルヒット"
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr "/helpでこのヘルプを表示する。"
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/inviteでパーティにプレーヤーを招待する。"
+
+#: src/net/ea/gui/guildtab.cpp:63
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leaveで既存のパーティから離れる。"
+
+#: src/net/ea/gui/guildtab.cpp:64
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kickで既存のパーティから一人を追い出してみる。"
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr "コマンド: /invite <プレイヤー名>"
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "このコマンドでは、入力したプレイヤーを自分のパーティーに招待します。"
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr "コマンド: /leave"
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "本コマンドではパティからプレイヤーを追い出させる。"
+
+#: src/net/ea/gui/guildtab.cpp:89
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "パーティ名がない。"
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%sは今からパーティのメンバーになった。"
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "%sからの未知招待返信"
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr "/inviteでパーティにプレーヤーを招待する。"
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr "/leaveで既存のパーティから離れる。"
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kickで既存のパーティから一人を追い出してみる。"
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr "/item でパーティ内のアイテムシェアモードを表示および変更する。"
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp でパーティ内の経験分割モードを表示および変更する。"
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr "本コマンドではパティからプレイヤーを追い出させる。"
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr "コマンド: /item <ポリシ>"
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr "本コマンドでは、アイテム共有モードを変更する。"
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<ポリシ>を有効するためには「1」、「yes」か「true」を設定ください。無効にす"
+"るために、「0」、「no」か「false」を設定ください。"
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr "コマンド: /item"
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr "本コマンドでは、アイテム共有モードを表示する。"
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr "コマンド: /exp <ポリシ>"
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr "本コマンドでは、経験分割モードを変更する。"
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<ポリシ>を有効するためには、「1」、「yes」か「true」を設定ください。無効にす"
+"る場合、「0」、「no」か「false」を設定ください。"
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr "コマンド: /exp"
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr "本コマンドでは、パーティメンバー以内の経験分割方針を表示する。"
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr "アイテムシェア有効"
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr "アイテムシェア無効"
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr "アイテムシェア不可能"
+
+#: src/net/ea/gui/partytab.cpp:141
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "アイテムシェア有効"
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr "経験シェア有効"
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr "経験シェア無効"
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr "経験シェア不可能"
+
+#: src/net/ea/gui/partytab.cpp:176
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "経験シェア有効"
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr "アイテム使用失敗"
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr "装備不可能"
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr "装備を外すのは不可能。"
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr "アカウントが見つからなかった。再ログインをください。"
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "旧パスワードが間違っている。"
+
+#: src/net/ea/loginhandler.cpp:85
+#, fuzzy
+msgid "New password too short."
+msgstr "新パスワードは短すぎている。"
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "不明エラー"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "登録されていないID"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "パースワードが間違っている。"
+
+#: src/net/ea/loginhandler.cpp:155
+#, fuzzy
+msgid "Account expired."
+msgstr "アカウントの有効期限が切られた。"
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "サーバからリジェクトされた。"
+
+#: src/net/ea/loginhandler.cpp:161
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "永久にゲームからバーンされた。ゲームマスターたちにご連絡ください。"
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"あなたは%sまでゲームからバーンされた。\n"
+"ゲームマスターたちにご連絡ください。"
+
+#: src/net/ea/loginhandler.cpp:172
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "本ユーザ名はもう使われている。"
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "売ること不可能"
+
+#: src/net/ea/network.cpp:414
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "マップサーバと接続中…"
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr "パーティ作成失敗"
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr "パーティ作成成功"
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%sはもうパーティのメンバーである。"
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%sは招待を拒んだ。"
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%sは今からパーティのメンバーになった。"
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr "%sからの未知招待返信"
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr "パーティから離れた。"
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr "%sがパーティから離れた。"
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "不明なメンバーが言おうとした事: %s"
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr "このような招待することは現時点ではまたサポートされていない。"
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%sはパーティにはいない!"
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr "あなたは死にました。"
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "残念なお知らせですが、あなた様のキャラは戦闘中亡くなってしまいました。"
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr "今から生きていない。"
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "死神の冷たい手に魂が取られてしまった。"
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr "ゲームオーバー!"
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr "ゲームを続けるためにはコインを入れてください。"
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"ううん、棒ややち。あなたのキャラは本当にしんでなかった。もっと綺麗なところに"
+"向かっただけ。"
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr "喉で的の武器を潰す予定だったが…失敗した。"
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr "あんまり上手くいかなかったぜー"
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr "持ち物を確定して欲しい?"
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr "悲しさのあまり、痕跡でさえ見つからなかった。"
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr "全滅された。"
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr "相手から自分の頭が渡されたみたい。"
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "もう一回倒された、水道管から死体を這ってみた後、新体を受け取ってみて"
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr "まだ死ななかった。休憩中だけである。"
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr "あなたはもう存在していない。"
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr "生きることなく、いなくなった。"
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr "あなたは息を引き取り、あなたを作った人へ逢いに行ってしまった。"
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr "あなたは死体である。"
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr "命を失い、天国に向かった。"
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+"もしあなたがそんなにも生気に満ちていなかったならば、死んで葬られていたんじゃ"
+"ないか?"
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr "あなたのがんばりは今や歴史となったらしい。"
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr "クタバッタみたいな。"
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr "人間界から追い出された。"
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr "最後の呼吸だった。死神に会った後、無と結合しちゃった。"
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr "旧プレイヤーである。"
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr "お前の魂は北極まで飛ばれた。"
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr "メッセージ"
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "持っているアイテムは体重より半分以上なので、体力が回復できない。"
+
+#: src/net/ea/playerhandler.cpp:333
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "を拾った。 "
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr "矢を先に装備してください。"
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr "取引失敗"
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr "スマイリー表示失敗"
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr "触ることが失敗した。"
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr "チャット作成失敗"
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr "パーティに参加できなかった!"
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr "叫べない!"
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr "あなたは十分で高いレベルにまだ達してないよ!"
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr "HP不足!"
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr "SP不足!"
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr "メモなし!"
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr "今この行動は無理。"
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr "金欠みたいんじゃないか…"
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "本スキルがこの武器と使えない。"
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr "他の赤宝石が必要となった!"
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr "他の青宝石が必要となった!"
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr "アイテムが持ちすぎている状態!"
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr "うん?何それ?"
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr "ワープが失敗した。"
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr "何も盗めなかった…"
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr "毒は不効果"
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr "取引要求"
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%sはあなたと取引したいみたいが、応じる?"
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "取引は不可能。取引の相手は遠すぎる。"
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "取引は不可能。本キャラが存在していない。"
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr "不明な理由で取引が中止された。"
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr "あなたと%sとの取引"
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "%sとの取引が中止された。"
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr "できなかった取引キャンセルパケット"
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "アイテム追加失敗。相手はアイテムを持ちすぎている状態である。"
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "アイテム追加失敗。相手の空いているスロットはない。"
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr "不明な理由でアイテム追加失敗"
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr "取引中止"
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr "取引完了"
+
+#: src/net/manaserv/beinghandler.cpp:324
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " OKを押すと、復活させる。"
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "死んじゃった。"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+#, fuzzy
+msgid "Not logged in."
+msgstr "既にサインインできた。"
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "ユーザーネームは既に存在している。"
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "キャラクターの能力ポイント配分量は問題ありません。"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "キャラクターの能力ポイント配分量は問題ありません。"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+#, fuzzy
+msgid "Player deleted."
+msgstr "キャラクターを削除した。"
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "交換するアイテムの量を選択してください。"
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "不明エラー"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr "全サーバは現在フールである。"
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "意志力"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr "トピック:%s"
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "プレイヤーがモンスターをアタックした時"
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "コマンド: /join <チャンネル>"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Listing channels."
+msgstr "%sというチャンネルへの参加を要求しています。"
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%sがパーティに参加した。"
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "不明なコマンド"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr "意志力 %+d"
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "意志力"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr "ギルド作成成功"
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr "ギルド作成エラー"
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr "招待送信成功"
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr "本メンバーが無事に昇進された。"
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr "メンバー昇進失敗"
+
+#: src/net/manaserv/loginhandler.cpp:87
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "違うmagic_token"
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+#, fuzzy
+msgid "Already logged in."
+msgstr "既にサインインできた。"
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+#, fuzzy
+msgid "Server is full."
+msgstr "サーバーが満席である。"
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "新パスワードが間違っている。"
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr "アカウントが接続されていない。最初にログインしてください。"
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "新メールアドが間違っている。"
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "旧メールアドが間違っている。"
+
+#: src/net/manaserv/loginhandler.cpp:158
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "新メールアドがもう存在している。"
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+#, fuzzy
+msgid "Client version is too old."
+msgstr "アプリケーションバージョンが古すぎる。"
+
+#: src/net/manaserv/loginhandler.cpp:266
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "ユーザ名かパスワードが間違ってる。"
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "ユーザ名、パスワードかメールアドが間違ってる。"
+
+#: src/net/manaserv/loginhandler.cpp:306
+#, fuzzy
+msgid "Username already exists."
+msgstr "ユーザーネームは既に存在している。"
+
+#: src/net/manaserv/loginhandler.cpp:309
+#, fuzzy
+msgid "Email address already exists."
+msgstr "メールアドは既に存在します。"
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr "パーティに参加した。"
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr "%sがパーティに参加した。"
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%sは招待を拒んだ。"
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr "取引要求を受け取り中"
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr "取引要求を無視にしている。"
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr "%sと取引中"
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@Ignore|%sを完璧に無視する@@"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "攻撃力 %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "守備力 %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr "不明なアイテム"
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr "名前なし"
+
+#~ msgid "no"
+#~ msgstr "いいえ"
+
+#~ msgid "Buddy"
+#~ msgstr "仲間"
+
+#~ msgid "Buddy List"
+#~ msgstr "仲間リスト"
+
+#~ msgid "Description: %s"
+#~ msgstr "詳細: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "効果: %s"
+
+#~ msgid "Previous"
+#~ msgstr "前へ"
+
+#~ msgid "New"
+#~ msgstr "新規"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "ジョブレベル: %d"
+
+#~ msgid "Present: "
+#~ msgstr "出席者: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "ギルドを辞める"
+
+#~ msgid "Ok"
+#~ msgstr "OK"
+
+#~ msgid "Recent:"
+#~ msgstr "最近:"
+
+#~ msgid "Magic"
+#~ msgstr "魔法"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "テストスペル1を唱える"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "テストスペル2を唱える"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "テストスペル3を唱える"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "武器2"
+
+#~ msgid "@@trade|Trade With %s@@"
+#~ msgstr "@@trade|%sと取引@@"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@attack|%sを攻撃する@@"
+
+#~ msgid "@@disregard|Disregard %s@@"
+#~ msgstr "@@disregard|%sを無視する@@"
+
+#~ msgid "@@ignore|Ignore %s@@"
+#~ msgstr "@@Ignore|%sを無視する@@"
+
+#~ msgid "@@unignore|Un-Ignore %s@@"
+#~ msgstr "@@unignore|%sの無視を解除する@@"
+
+#~ msgid "@@admin-kick|Kick player@@"
+#~ msgstr "@@管admin-kick|プレイヤーを追い出す@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@cancel|キャンセル@@"
+
+#~ msgid "@@pickup|Pick up %s@@"
+#~ msgstr "@@pickup|%sを拾う@@"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|外す@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|装備する@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@use|使う@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|落とす@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|分割@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|保管する@@"
+
+#~ msgid "@@retrieve|Retrieve@@"
+#~ msgstr "@@retrieve|取り戻す@@"
+
+#~ msgid "Select Server"
+#~ msgstr "サーバを選択"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "に変更失敗 "
+
+#~ msgid "windowed"
+#~ msgstr "ウィンドウ内"
+
+#~ msgid "fullscreen"
+#~ msgstr "フルスクリーン"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "不思議なスキル"
+
+#~ msgid "Weapons"
+#~ msgstr "武器"
+
+#~ msgid "Crafts"
+#~ msgstr "技術"
+
+#~ msgid "Stats"
+#~ msgstr "ステータス"
+
+#~ msgid "Total"
+#~ msgstr "合計"
+
+#~ msgid "Cost"
+#~ msgstr "コスト"
+
+#~ msgid "Attack:"
+#~ msgstr "攻撃力:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "反射作用率(%):"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "残りステータスポイント:%d"
+
+#~ msgid "Max level"
+#~ msgstr "最大レベル"
+
+#~ msgid "curl error "
+#~ msgstr "curlエラー "
+
+#~ msgid " host: "
+#~ msgstr " ホスト: "
+
+#~ msgid "Guilds"
+#~ msgstr "ギルド"
+
+#~ msgid "Buddys"
+#~ msgstr "仲間"
+
+#~ msgid "Party Window"
+#~ msgstr "パーティウィンドウ"
+
+#~ msgid "Unarmed"
+#~ msgstr "武器を使わない"
+
+#~ msgid "Knife"
+#~ msgstr "ナイフ"
+
+#~ msgid "Sword"
+#~ msgstr "剣"
+
+#~ msgid "Polearm"
+#~ msgstr "ポール腕"
+
+#~ msgid "Staff"
+#~ msgstr "杖"
+
+#~ msgid "Whip"
+#~ msgstr "むち"
+
+#~ msgid "Bow"
+#~ msgstr "弓"
+
+#~ msgid "Shooting"
+#~ msgstr "射撃"
+
+#~ msgid "Mace"
+#~ msgstr "笏"
+
+#~ msgid "Axe"
+#~ msgstr "斧"
+
+#~ msgid "Thrown"
+#~ msgstr "捨てられた"
+
+#~ msgid "Craft"
+#~ msgstr "技術"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "不明なスキル"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " の作成は不可能が、存在していない!終了中..."
+
+#~ msgid "Couldn't set "
+#~ msgstr "設定不可能 "
+
+#~ msgid " video mode: "
+#~ msgstr " ビデオモード: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "キャラクターサーバーに接続中…"
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "アカウントサーバーに接続中…"
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/newは/createのショートカット。"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "コマンド: /new <パーティ名>"
+
+#~ msgid "a"
+#~ msgstr "一つの"
+
+#~ msgid "Unnamed"
+#~ msgstr "名前なし"
diff --git a/po/ka.po b/po/ka.po
new file mode 100644
index 000000000..9d9b5c538
--- /dev/null
+++ b/po/ka.po
@@ -0,0 +1,3563 @@
+# Georgian translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-07-23 22:14+0000\n"
+"Last-Translator: Mpa4Hu <ymen9@pisem.net>\n"
+"Language-Team: Georgian <ka@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr ""
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+msgid "Password Change"
+msgstr ""
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "უცნობი კომანდა."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- დახმარება --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/help > დახმარების გამოტანა"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > რუქის სახელის გამოტანა"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > ონლაინ მომხმარებლების რაოდენობა"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > მოყევით რამე თქვენს შესახებ"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > ფანჯრის გასუფთავება"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > პრივატული მესიჯის გაგზავნა მომხმარებლისთვის"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "ამ კომანდას გამოაქ კონკრეტული რუქის სახელი"
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "ამ კომანდას გამოაქ კონკრეტული რუქის სახელი"
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr ""
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:134
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:123
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+msgid "Change Email"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, c-format
+msgid "Map: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+msgid "None"
+msgstr ""
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:416
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+msgid "Create Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+msgid "Level"
+msgstr ""
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "ამ კომანდას გამოაქ კონკრეტული რუქის სახელი"
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "/help > დახმარების გამოტანა"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Game"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+msgid "Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "ამ კომანდას გამოაქ კონკრეტული რუქის სახელი"
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "უცნობი კომანდა."
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "უცნობი კომანდა."
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "უცნობი კომანდა."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
diff --git a/po/manaplus.pot b/po/manaplus.pot
new file mode 100644
index 000000000..43307a34b
--- /dev/null
+++ b/po/manaplus.pot
@@ -0,0 +1,4889 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR The Mana Developers
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:798
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:829
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:984
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:994
+msgid "Changing game servers"
+msgstr ""
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr ""
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+msgid "Password Change"
+msgstr ""
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:1093
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1113
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr ""
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr ""
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr ""
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+msgid "/desregard > Disregard a player"
+msgstr ""
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:324
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:325
+msgid "/createguild > Create a new guild"
+msgstr ""
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:335
+msgid "/closeall > Close all opened whisper tabs"
+msgstr ""
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+msgid "/mail > Send offline message to player"
+msgstr ""
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:379
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:380
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:417
+msgid "Command: /away <afk reason>"
+msgstr ""
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+msgid "Command: /away"
+msgstr ""
+
+#: src/commandhandler.cpp:421
+msgid "This command clears the away status and message."
+msgstr ""
+
+#: src/commandhandler.cpp:425
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:426
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:430
+msgid "Command: /createguild <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:431
+msgid "This command creates a new guild called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:443
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:601
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:700
+msgid "friend"
+msgstr ""
+
+#: src/commandhandler.cpp:705
+msgid "disregarded"
+msgstr ""
+
+#: src/commandhandler.cpp:710
+msgid "neutral"
+msgstr ""
+
+#: src/commandhandler.cpp:729
+#, c-format
+msgid "Player already %s!"
+msgstr ""
+
+#: src/commandhandler.cpp:743
+#, c-format
+msgid "Player successfully %s!"
+msgstr ""
+
+#: src/commandhandler.cpp:751
+#, c-format
+msgid "Player could not be %s!"
+msgstr ""
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:799
+msgid "Player already erased!"
+msgstr ""
+
+#: src/commandhandler.cpp:810
+msgid "Player successfully erased!"
+msgstr ""
+
+#: src/commandhandler.cpp:812
+msgid "Player could not be erased!"
+msgstr ""
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:482
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:1373
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:89
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:102
+#, c-format
+msgid "Guild: %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+msgid "Bot Checker"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:297
+msgid "Move"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr ""
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr ""
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:129
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:136
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:143
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:124
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:155
+msgid "Change Email"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:425
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+msgid "default"
+msgstr ""
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+msgid "red"
+msgstr ""
+
+#: src/gui/chat.cpp:94
+msgid "green"
+msgstr ""
+
+#: src/gui/chat.cpp:95
+msgid "blue"
+msgstr ""
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+msgid "yellow"
+msgstr ""
+
+#: src/gui/chat.cpp:98
+msgid "pink"
+msgstr ""
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+msgid "brown"
+msgstr ""
+
+#: src/gui/chat.cpp:102
+msgid "rainbow 1"
+msgstr ""
+
+#: src/gui/chat.cpp:103
+msgid "rainbow 2"
+msgstr ""
+
+#: src/gui/chat.cpp:104
+msgid "rainbow 3"
+msgstr ""
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr ""
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:554
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:49
+msgid "Ignore"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+msgid "Music:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+msgid "Map:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+msgid "Minimap:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:84
+#, c-format
+msgid "Map actors count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+msgid "Player Position:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+msgid "Target:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+msgid "Target Id:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+msgid "Target Level:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+msgid "Target Party:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+msgid "Target Guild:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+msgid "Cursor:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+msgid "Unknown."
+msgstr ""
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+msgid "Kill stats"
+msgstr ""
+
+#: src/gui/killstats.cpp:61
+msgid "Reset stats"
+msgstr ""
+
+#: src/gui/killstats.cpp:62
+msgid "Reset timer"
+msgstr ""
+
+#: src/gui/killstats.cpp:66
+msgid "Level: "
+msgstr ""
+
+#: src/gui/killstats.cpp:70
+msgid "Exp: "
+msgstr ""
+
+#: src/gui/killstats.cpp:71
+msgid " Left: "
+msgstr ""
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+msgid "Auto Close"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr ""
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:117
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr ""
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+msgid "Clear"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, c-format
+msgid "Key: %s"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:83
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+msgid "@@trade|Trade@@"
+msgstr ""
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+msgid "@@attack|Attack@@"
+msgstr ""
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+msgid "@@whisper|Whisper@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+msgid "@@heal|Heal@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+msgid "@@friend|Befriend@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+msgid "@@disregard|Disregard@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+msgid "@@ignore|Ignore@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+msgid "@@erase|Erase@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+msgid "@@unignore|Unignore@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+msgid "@@ignore|Completely ignore@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+msgid "@@party|Invite to party@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+msgid "@@kick party|Kick from party@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+msgid "@@guild-kick|Kick from guild@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+msgid "@@guild|Invite to guild@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+msgid "@@undress|Undress@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+msgid "@@sell|Sell@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:226
+msgid "@@talk|Talk@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:240
+msgid "@@admin-kick|Kick@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+msgid "@@name|Add name to chat@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+msgid "@@pickup|Pick up@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:376
+msgid "@@chat|Add to chat@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+msgid "@@edit spell|Edit spell@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+msgid "Disable highlight"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:459
+msgid "Enable highlight"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+msgid "Change guild position"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+msgid "Store 10"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1094
+msgid "Store half"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1096
+msgid "Store all"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1110
+msgid "Retrieve 10"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1113
+msgid "Retrieve half"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1115
+msgid "Retrieve all"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:207
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:223
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:247
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+msgid "Enable music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Enable mumble voice chat"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:117
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+msgid "Enable trade tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+msgid "Enable battle tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:104
+msgid "Show battle events"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:72
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:109
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:124
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:139
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Unassign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+msgid "Highlight map portals"
+msgstr ""
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+msgid "Cycle monster targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:124
+msgid "Enable bot checker"
+msgstr ""
+
+#: src/gui/setup_other.cpp:127
+msgid "Highlight floor items"
+msgstr ""
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+msgid "Enable shop mode"
+msgstr ""
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+msgid "Enable debug log"
+msgstr ""
+
+#: src/gui/setup_other.cpp:153
+msgid "Enable server side attack"
+msgstr ""
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+msgid "Enable quick stats"
+msgstr ""
+
+#: src/gui/setup_other.cpp:169
+msgid "Show warps particles"
+msgstr ""
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:248
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_players.cpp:301
+msgid "Show level"
+msgstr ""
+
+#: src/gui/setup_players.cpp:305
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:309
+msgid "Target dead players"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+msgid "Particle font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:113
+msgid "Help font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:223
+msgid "Theme Changed"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:143
+msgid "Tiny (10)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Small (11)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Medium (12)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:146
+msgid "Large (13)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "Fast OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:173
+msgid "Safe OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:277
+msgid "Hw acceleration"
+msgstr ""
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+msgid "Enable opacity cache"
+msgstr ""
+
+#: src/gui/setup_video.cpp:302
+msgid "Show background"
+msgstr ""
+
+#: src/gui/setup_video.cpp:307
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+msgid "Alt FPS limit: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:329
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+msgid "None"
+msgstr ""
+
+#: src/gui/setup_video.cpp:528
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:534
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:545
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:558
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:707
+#, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:290
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:374
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:384
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:469
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:477
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:195
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+msgid "Create Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:848
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:975
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:985
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1002
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1012
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1056
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1094
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1108
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1114
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1120
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1146
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1150
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1193
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d (GM %d)"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:299
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:109
+msgid "No Target"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:110
+msgid "Allow Target"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:111
+msgid "Need Target"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:116
+msgid "General Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:117
+msgid "Life Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:118
+msgid "War Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+msgid "Command Editor"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:181
+msgid "magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+msgid "Command:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+msgid "Target Type:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+msgid "Magic level:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+msgid "School level:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr ""
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr ""
+
+#: src/gui/userpalette.cpp:110
+msgid "Friend Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:111
+msgid "Disregarded Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:112
+msgid "Ignored Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:113
+msgid "Erased Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/userpalette.cpp:119
+msgid "Monster HP bar"
+msgstr ""
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+msgid "Party Members"
+msgstr ""
+
+#: src/gui/userpalette.cpp:123
+msgid "Guild Members"
+msgstr ""
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/userpalette.cpp:127
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/userpalette.cpp:128
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/userpalette.cpp:130
+msgid "Other Player Hits Local Player"
+msgstr ""
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/userpalette.cpp:133
+msgid "Local Player Hits Monster"
+msgstr ""
+
+#: src/gui/userpalette.cpp:135
+msgid "Local Player Critical Hit"
+msgstr ""
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr ""
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr ""
+
+#: src/gui/userpalette.cpp:139
+msgid "Portal Highlight"
+msgstr ""
+
+#: src/gui/userpalette.cpp:141
+msgid "Collision Highlight"
+msgstr ""
+
+#: src/gui/userpalette.cpp:143
+msgid "Walkable Highlight"
+msgstr ""
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+msgid "Monster Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:177
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:121
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:122
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:128
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Bot checker"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+msgid "Smiles"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "Shortcuts"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:79
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:80
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Move to Target"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:61
+msgid "Target Closest"
+msgstr ""
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Change Map View Mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Item Shortcuts Key"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:136
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:140
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:142
+msgid "Shop Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:143
+msgid "Quick drop Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:145
+msgid "Kills Stats Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:147
+msgid "Commands Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:149
+msgid "Bot Checker Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+msgid "Previous Social Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:155
+msgid "Next Social Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:262
+msgid "Previous chat tab line"
+msgstr ""
+
+#: src/keyboardconfig.cpp:264
+msgid "Next chat tab line"
+msgstr ""
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+msgid "Direct Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:279
+msgid "Direct Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:280
+msgid "Direct Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+msgid "Switch magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:300
+msgid "Change move type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+msgid "Change Attack Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:306
+msgid "Change Follow mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:308
+msgid "Change Imitation mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+msgid "Enable / Disable away mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+msgid "You see "
+msgstr ""
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -l --log-file : Log file to use"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:55
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:60
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:63
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:64
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:66
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:68
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:166
+#, c-format
+msgid "Strength %+.1f"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:179
+#, c-format
+msgid "Agility %+.1f"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:192
+#, c-format
+msgid "Dexterity %+.1f"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:205
+#, c-format
+msgid "Vitality %+.1f"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:218
+#, c-format
+msgid "Intelligence %+.1f"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:224
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/attributes.cpp:231
+#, c-format
+msgid "Willpower %+.1f"
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:336
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:337
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:168
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+msgid "Unknown error."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:206
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:218
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:221
+#, c-format
+msgid "Unknown error (%d)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:213
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+msgid "Unknown channel event."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:89
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:95
+msgid "Account banned."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:120
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:155
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:163
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:273
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:279
+msgid "Account banned"
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:313
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:316
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:113
+msgid "Unknown char-server failure."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr ""
+
+#: src/net/tmwa/chathandler.cpp:103
+#, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr ""
+
+#: src/net/tmwa/chathandler.cpp:111
+#, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr ""
+
+#: src/net/tmwa/chathandler.cpp:333
+msgid "MVP player."
+msgstr ""
+
+#: src/net/tmwa/chathandler.cpp:337
+msgid "MVP player: "
+msgstr ""
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+msgid "Game"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:135
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:138
+msgid "No servers available."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:142
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:145
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:148
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:151
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:154
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:255
+msgid "Defense"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:256
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:257
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:261
+msgid "Attack Delay"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:263
+msgid "Walk Delay"
+msgstr ""
+
+#: src/net/tmwa/generalhandler.cpp:265
+msgid "Attack Range"
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+msgid "You already in guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+msgid "Unknown server response."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, c-format
+msgid "Guild name: %s"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, c-format
+msgid "Guild master: %s"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, c-format
+msgid "Guild level: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, c-format
+msgid "Average level: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, c-format
+msgid "Guild exp: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, c-format
+msgid "Guild next exp: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, c-format
+msgid "Guild castle: %s"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:475
+msgid "You have left the guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, c-format
+msgid "%s has left your guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, c-format
+msgid "%s has kicked from your guild."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:154
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:193
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:96
+msgid "New password too short."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:161
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:164
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:167
+msgid "Account expired."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:170
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:173
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/tmwa/loginhandler.cpp:184
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/tmwa/network.cpp:421
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:337
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, c-format
+msgid "You spent %s."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:184
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/playerrelations.cpp:404
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr ""
diff --git a/po/nb.po b/po/nb.po
new file mode 100644
index 000000000..c3ef82e4b
--- /dev/null
+++ b/po/nb.po
@@ -0,0 +1,3685 @@
+# Norwegian Bokmal translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-09-02 17:55+0000\n"
+"Last-Translator: Øyvind Øritsland <Unknown>\n"
+"Language-Team: Norwegian Bokmal <nb@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Venter på server"
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Feil"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Passord:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Avregistrer"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Ukjent kommando"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- Hjelp --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/hjelp > Hvis denne hjelpen"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > Viser kartnavn"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > Viser antall påloggede brukere"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > Si noe om deg selv"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > Tømmer vinduet"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Send en privat melding til en bruker"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alternativ for msg"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > Alternativ for msg"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+"/query > Åpner en fane for å sende private meldinger med en annen bruker"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q > Alternativ for query"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > Viser alle offentlige kanaler"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/delta > Delta i eller opprett en kanal"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/party > Inviter en bruker til en gruppe"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "/party > Inviter en bruker til en gruppe"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/innspilling > Start innspilling av chat til en ekstern fil"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "For mer informasjon, skriv /help <kommando>"
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "Kommando: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "Denne kommandoen viser en liste med alle tilgjengelige kommandoer."
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "Kommando: /help <kommando>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "Kommando: /announce <msg>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** kun tilgjengelig for GM ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Denne kommandoen sender meldingen <msg> til alle påloggede spillere."
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "Kommando: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "Denne kommandoen klarer chatte-loggen."
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Kommando: /join <kanal>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Denne kommandoen viser antall påloggede spillere -"
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "Kommando: /join <kanal>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "Denne kommandoen åpner <kanal>"
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "<kanal> blir opprettet om den ikke eksisterer."
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "Kommando: /list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "Denne kommandoen viser en liste med alle kanaler."
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "Kommando: /me <melding>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Denne kommandoen forteller andre at du er (eller gjør) <melding>"
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "Kommando: /msg <brukernavn> <melding>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "Kommando: /whisper <brukernavn> <melding>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "Kommando: /w <brukernavn> <melding>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "Denne kommandoen sender teksten <melding> til <brukernavn>."
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Hvis <brukernavn> inneholder mellomrom, skriv det mellom to anførselstegn "
+"(\")."
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "Kommando: /query <brukernavn>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "Kommando: /q <brukernavn>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Denne kommandoen prøver å opprette en fane for private meldinger mellom deg "
+"og <brukernavn>."
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Kommando: /party <brukernavn>"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Denne kommandoen åpner <kanal>"
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "Kommando: /party <brukernavn>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr "Denne kommandoen inviterer <brukernavn> til en gruppe med deg."
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "Kommando: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "Kommando: /record <filnavn>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr "Denne kommandoen starter opptak av chatte-loggen til filen <filnavn>."
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "Kommando: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Kommando: /announce <msg>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "Denne kommandoen viser antall påloggede spillere -"
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "Skriv /help for en liste over kommandoer."
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr "Kan ikke sende tomme meldinger!"
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "Generelt"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Skjermbilde lagret til ~/"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "Lagring av skjermbilde feilet!"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Forbindelsen til serveren mistet, programmet vil nå avsluttes"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "Nettverksfeil"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Kunne ikke laste inn kart."
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "Feil i lastingen av %s"
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Gruppe (%s)"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "Kjøp"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Pris: %s / Totalt: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Avslutt"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "Maks"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "Butikk"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Selg"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "Avbryt"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Endre epost-adresse"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Konto: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Skriv ny epost-adresse to ganger:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Brukernavnet må minst være %d bokstaver."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Brukernavnet må være mindre enn %d bokstaver."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "Endre passord"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Passord:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Skriv nytt passord to ganger:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Passordet må minst være %d bokstaver."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Passordet må være mindre enn %d bokstaver."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Lag karakter:"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "Navn:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Hårfarge:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Frisyre:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "Lag"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "Mann"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "Kvinne"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Vennligst distribuer %d poeng"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Navnet ditt må minst være 4 bokstaver."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Vennligst fjern %d poeng"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "Bekreft karakter-sletting"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Er du sikker på at du vil slette denne karakteren?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "Konto- og karakter"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Avregistrer"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Endre epost-adresse"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Slett"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "Lukk"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Ja"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Nei"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "Navn: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "Penger: %s"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Partikkeleffekter"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "Partikkeldetalje"
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Utstyr"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "Hjelp"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "Lukk"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Bruk"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "Del opp"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "Vekt:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "Alt"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Vekt:"
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "Husk brukernavn"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Registrer"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "Kart"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "Venter på server"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Neste"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr "Bekreft"
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "Tilbakestill"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Neste"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr "Til:"
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "Send"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "Tekst"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "Tekstskygge"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "Bakgrunn"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "Spiller"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "Gruppe"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "Server"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr "Hyperlenke"
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "Andre Spilleres Navn"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr "Eget Navn"
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "GM Navn"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "NPCer"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "Monstre"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "Skjorter"
+
+#: src/gui/palette.cpp:119
+#, fuzzy
+msgid "One Handed Weapons"
+msgstr "Én-håndsvåpen"
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "Bukser"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "Sko"
+
+#: src/gui/palette.cpp:122
+#, fuzzy
+msgid "Two Handed Weapons"
+msgstr "Én-håndsvåpen"
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "Skjold"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "Ringer"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "Halsbånd"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "Ammunisjon"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr "Partikkeleffekter"
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "Ignorert"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "%s har invitert deg til sin gruppe."
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "Monstre"
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr "Tar opp …"
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "Bekreft:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "E-post:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Brukernavnet må minst være %d bokstaver."
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Brukernavnet må være mindre enn %d bokstaver."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Passordet må minst være %d bokstaver."
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Passordet må være mindre enn %d bokstaver."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Passordene stemmer ikke."
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Velg server"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "Kobler til..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Server"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "Vennligst skriv inn både adresse og port til en server."
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Venter på server"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "Lyd"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Lydeffekt-volum"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Musikk-volum"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "Ingen tekst"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr "Slik ser fargen ut"
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "Farger"
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr "Statisk"
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "Puls"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "Regnbue"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "Spektrum"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "Forsinkelse: "
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "Rød: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "Grønn: "
+
+#: src/gui/setup_colors.cpp:137
+#, fuzzy
+msgid "Blue:"
+msgstr "Blå: "
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Bruk"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "Trykk knappen for å starte kalibrasjon"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "Stopp"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Tastatur"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Tildel"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "Standard"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "Navn"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "Nøytral"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "Venn"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "Ignorert"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "Tillat handel"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "Vis navn"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "Spillere"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr "Bitteliten"
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "Liten"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "Medium"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "Stor"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "Ingen tekst"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr "Bobler, ingen navn"
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr "Bobler med navn"
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "av"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "lav"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "høy"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "medium"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "maks"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "Fullskjerm"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr "Synlige navn"
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr "Partikkeleffekter"
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "Vis navn"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr "som partikkel"
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS-grense:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "Vis navn"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "GUI-gjennomsiktighet"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "Partikkeldetalje"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "Skriftstørrelse"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Nei"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Bytter til fullskjerm"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Bytter OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "Endringer av OpenGL krever restart."
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Skjermresolusjon endret"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Partikkeleffekt-instillinger endret."
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Ferdigheter"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "Opp"
+
+#: src/gui/skilldialog.cpp:262
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Ferdighetspoeng: %d"
+
+#: src/gui/skilldialog.cpp:314
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Ferdighetspoeng: %d"
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Ferdigheter"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Nivå: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Nivå: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Er du sikker på at du vil avslutte?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Inviter en bruker til en gruppe"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Inviter en bruker til en gruppe"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Er du sikker på at du vil avslutte?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Lag karakter:"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "Inviter Bruker"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "Stor"
+
+#: src/gui/socialwindow.cpp:394
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Godta invitasjon fra %s."
+
+#: src/gui/socialwindow.cpp:400
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Avslo invitasjon fra %s."
+
+#: src/gui/socialwindow.cpp:413
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Godta invitasjon fra %s."
+
+#: src/gui/socialwindow.cpp:419
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Avslo invitasjon fra %s."
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "GM Navn"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Velg server"
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s har invitert deg til sin gruppe."
+
+#: src/gui/socialwindow.cpp:507
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Godta Gruppeinvitasjon"
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s har invitert deg til sin gruppe."
+
+#: src/gui/socialwindow.cpp:533
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s har invitert deg til sin gruppe."
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s har invitert deg til sin gruppe."
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr "Godta Gruppeinvitasjon"
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "Gruppe"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Velg server"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Nivå: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "Penger: %s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr "Jobb: %d"
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+#, fuzzy
+msgid "HP"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+#, fuzzy
+msgid "Exp"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Penger: %d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "Jobb: %d"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Ferdighetspoeng: %d"
+
+#: src/gui/statuswindow.cpp:235
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Ferdighetspoeng: %d"
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Nivå: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Navn: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "Kobler til..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Kommando: /record"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Denne kommandoen viser antall påloggede spillere -"
+
+#: src/gui/widgets/whispertab.cpp:94
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "Denne kommandoen starter opptak av chatte-loggen til filen <filnavn>."
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "Velg Server"
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "Velg server"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "Monstre"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "/hjelp > Hvis denne hjelpen"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Kan ikke sende tomme meldinger!"
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "Spiller"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "Navn"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Slett"
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/party > Inviter en bruker til en gruppe"
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Denne kommandoen inviterer <brukernavn> til en gruppe med deg."
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Denne kommandoen sender teksten <melding> til <brukernavn>."
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Ukjent kommando"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Avregistrer"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "Endre passord"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Avslo invitasjon fra %s."
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Ukjent kommando"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Kommando: /join <kanal>"
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Ukjent kommando"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Skriv nytt passord to ganger:"
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Skriv ny epost-adresse to ganger:"
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "Avslo invitasjon fra %s."
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "no"
+#~ msgstr "nei"
+
+#~ msgid "Buddy"
+#~ msgstr "Venn"
+
+#~ msgid "Buddy List"
+#~ msgstr "Venneliste"
+
+#~ msgid "Description: %s"
+#~ msgstr "Beskrivelse: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effekt: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Forrige"
+
+#~ msgid "New"
+#~ msgstr "Ny"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Jobb-nivå: %d"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Magic"
+#~ msgstr "Magi"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "To-håndsvåpen"
+
+#~ msgid "windowed"
+#~ msgstr "i vindu"
+
+#~ msgid "fullscreen"
+#~ msgstr "fullskjerm"
+
+#~ msgid "Weapons"
+#~ msgstr "Våpen"
diff --git a/po/nds.po b/po/nds.po
new file mode 100644
index 000000000..ac1647c5e
--- /dev/null
+++ b/po/nds.po
@@ -0,0 +1,3587 @@
+# German, Low translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-06-08 22:07+0000\n"
+"Last-Translator: Thorbjørn Lindeijer <bjorn@lindeijer.nl>\n"
+"Language-Team: German, Low <nds@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "Setup"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "verbinde..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "Login"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Fehler"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Passwort:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr ""
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr ""
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "kaufen"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Beenden"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Verkaufen"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Email-Adresse ändern"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Account: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Der Username muss mindestens %d Buchstaben beinhalten."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Der Username muss weniger als %d Buchstaben beinhalten."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "Passwort ändern"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Passwort:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Das Passwort muss mindestens %d Buchstaben beinhalten."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Das Passwort muss weniger als %d Buchstaben beinhalten."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Charakter erstellen"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "Name:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Haarfarbe:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Frisur:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "erstellen"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "männlich"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "weiblich"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Bitte verteile %d Punkte"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Dein Name muss aus mindestens 4 Buchstaben bestehen."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Bitte entferne %d Punkte"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "Der Löschung des Charakters zustimmen"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Bist du dir sicher, dass du diesen Charakter löschen möchtest?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Email-Adresse ändern"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Löschen"
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Ja"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Nein"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, c-format
+msgid "Map: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Account: %s"
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Ausrüstung"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "Ablegen"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "Inventar"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "Ausrüsten"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Benutzen"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "Ablegen"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "Ablegen"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Wirkung: %s"
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "Login"
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Registrieren"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Server:"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "Ablegen"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "Server wechseln"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "Charakter wechseln"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "Bestätigen:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Der Username muss mindestens %d Buchstaben beinhalten."
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Der Username muss weniger als %d Buchstaben beinhalten."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Das Passwort muss mindestens %d Buchstaben beinhalten."
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Das Passwort muss weniger als %d Buchstaben beinhalten."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Die Passwörter stimmen nicht überein."
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "verbinde..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "Sound"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Sfx Lautstärke"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Musiklautstärke"
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Zustimmen"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "einstellen"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Joystick einschalten"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "Stop"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Tastatur"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "aus"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "niedrig"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "hoch"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Nein"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Fähigkeiten"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Fähigkeiten"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Level: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Level: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Bist du dir sicher, dass du diesen Charakter löschen möchtest?"
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Bist du dir sicher, dass du diesen Charakter löschen möchtest?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Charakter erstellen"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Level: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Geld: %d"
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Level: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "Hinzufügen"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Du gibst:"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "Du gibst:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "verbinde..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "Stärke"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "Intelligenz"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "Name:"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Löschen"
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+msgid "Unknown error."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "Passwort ändern"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "Du gibst:"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, c-format
+msgid "Unknown error (%d)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "Willenskraft"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+msgid "Unknown channel event."
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "Willenskraft"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Description: %s"
+#~ msgstr "Beschreibung: %s"
+
+#~ msgid "New"
+#~ msgstr "Neu"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
diff --git a/po/nl.po b/po/nl.po
new file mode 100644
index 000000000..335e0c991
--- /dev/null
+++ b/po/nl.po
@@ -0,0 +1,5642 @@
+# Dutch translation of The Mana World.
+# Copyright (c) 2007 The Mana World Development Team
+# This file is distributed under the same license as the The Mana World package.
+# Bjørn Lindeijer <bjorn@lindeijer.nl>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: The Mana World 0.1.0\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2009-07-15 12:21+0000\n"
+"Last-Translator: Yentl <y.v.t@scarlet.be>\n"
+"Language-Team: Dutch\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Configureren"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Verbinden met de map server..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Inloggen"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Kies Personage"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Verbinden met de map server..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Server"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Fout"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Wachtwoord:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Veranderen"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Lid is succesvol gepromoveerd."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Registreren"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Ongeldige updatahost: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Fout bij het creëren van de update map!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Onbekend commando."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Help --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Deze help weergeven"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Mapnaam weergeven"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Aantal online gebruikers weergeven"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Vertel iets over jezelf"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Maak dit venster leeg"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Zend een privébericht naar een gebruiker"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > zelfde functie als msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > zelfde als msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Maakt een tabblad voor privéberichten met andere gebruikers"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > zelfde functie als query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Sluit de fluistertab"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+msgid "/desregard > Disregard a player"
+msgstr ""
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Alle publieke kanalen weergeven"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Een kanaal creëren of bij aansluiten"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Creëer een nieuwe groep"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Creëer een nieuwe groep"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Een gebruiker uitnodigen in de groep"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Bepalen of <return> de chatlog wisselt"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Lijst weergeven met alle aanwezige spelers (opgeslagen in "
+"chatlog, als logging aanstaat)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Globale aankondiging (enkel GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Sluit de fluistertab"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Zend een privébericht naar een gebruiker"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Voor meer informatie, typ /help <commando>."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Commando: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Dit commando geeft een lijst weer van alle mogelijke commando's"
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Commando: /help <commando>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Dit commando geeft help weer van <commando>"
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Commando: /announce <msg>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** enkel mogelijk door een GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"Dit commando stuurt het bericht <msg> naar alle spelers momenteel online."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Commando: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Dit commando maakt de chatlog van vorige chatsessies leeg"
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Commando: /item <beleid>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Dit commando geeft het aantal spelers dat momenteel online is weer."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Commando: /join <kanaal>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Dit commando voegt je toe op kanaal <kanaal>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Als <kanaal> niet bestaat, wordt het aangemaakt."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Commando: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Dit commando geeft een lijst weer van alle kanalen."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Commando /me <bericht>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Dit commando vertelt anderen dat je <msg> bent/doet."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Commando: /msg <nick> <bericht>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Commando: /msg <nick> <bericht>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Commando: /w <nick> <bericht>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Dit commando zendt de tekst <bericht> aan <nick>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Als de <nick> spaties bevat, omsluit het dan met dubbele aanhalingstekens "
+"(\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Commando: /query <nick>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Commando: /q <nick>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Dit commando probeert een tabblad aan te maken voor alle whispers tussen jou "
+"en <nick>"
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Commando: /w <nick> <bericht>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Commando: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Dit commando zet het onderwerp naar <bericht>."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Commando: /create <groepsnaam>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Dit commando creëert een nieuwe groep genaamd <groepsnaam>"
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Commando: /create <groepsnaam>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Dit commando creëert een nieuwe groep genaamd <groepsnaam>"
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Commando: /party <nick>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Dit commando nodigt <nick> uit om een groep te vormen met jou."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Commando: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Dit commando haalt een lijst op van spelers die je kunnen horen en zendt dit "
+"naar ofwel het logboek als dit opgeslagen wordt, of anders naar de chatlog."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Commando: /toggle <status>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<status> kan \"1\", \"yes\", \"true\" zijn om het in te schakelen, of \"0\", "
+"\"no\", \"false\" om het uit te schakelen."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Commando: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Commando: /item <beleid>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Commando: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Dit commando geeft de naam weer van de huidige map."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Commando: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Dit commando geeft het aantal spelers dat momenteel online is weer."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Type /help voor een lijst van commando's."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Kan geen lege berichten sturen!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Aanvragen om bij kanaal %s toegevoegd te worden."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Groepsnaam ontbreekt."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Groepsnaam ontbreekt."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Bericht sluit chat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Bericht sluit nu chat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Vriend"
+
+#: src/commandhandler.cpp:705
+msgid "disregarded"
+msgstr ""
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutraal"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Fluisterbericht kon niet verzonden worden, genegeerd door gebruiker."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Groep succesvol aangemaakt."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Fluisterbericht kon niet verzonden worden, genegeerd door gebruiker."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Fluisterbericht kon niet verzonden worden, genegeerd door gebruiker."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Fluisterbericht kon niet verzonden worden, genegeerd door gebruiker."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Groep succesvol aangemaakt."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Fluisterbericht kon niet verzonden worden, genegeerd door gebruiker."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Opties voor /%s zijn \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Algemeen"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Screenshot opgeslagen naar ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Opslaan van screenshot mislukt!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr ""
+"De verbinding met de server is verloren gegaan, het programma zal nu "
+"afsluiten"
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Netwerkfout"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Inkomende handelsaanvragen negeren"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Inkomende handelsaanvragen accepteren"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Kan de map niet laden"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Fout bij het laden van %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Groep (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Guilds"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Gespreksvenster"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Naam"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Aanvallen"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Spreken"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Omhoog"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Reset"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Kopen"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Prijs: %s / Totaal: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Afsluiten"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Maximum"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Winkel"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Verkopen"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Annuleren"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Emailadres wijzigen"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Account: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Typ nieuw emailadres tweemaal:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "De gebruikersnaam moet uit ten minste %d tekens bestaan."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "De gebruikersnaam moet uit minder dan %d tekens bestaan."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Het nieuwe emailadres bestaat al."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Wijzig wachtwoord"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Wachtwoord:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Typ nieuw wachtwoord tweemaal:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Het wachtwoord moet uit ten minste %d tekens bestaan."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Het wachtwoord moet uit minder dan %d tekens bestaan."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Personage Aanmaken"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Naam:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Haarkleur:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Haarstijl:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Aanmaken"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Mannelijk"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Vrouwelijk"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Nog %d punten te verdelen"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Je naam moet uit tenminste 4 tekens bestaan"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Attributen van personage OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Verwijder alstublieft %d punten"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Bevestig het verwijderen van het personage"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Weet je zeker dat je deze personage wilt verwijderen?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Account en personage beheer"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Registreren"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Emailadres wijzigen"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Verwijderen"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Sluiten"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Standaard"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Vriend"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Groen: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Blauw: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "laag"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Hyperlink"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Geworpen"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Regenboog"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Regenboog"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Regenboog"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d spelers zijn aanwezig."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Fluisteren naar %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Ja"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Nee"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Genegeerd"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Onderwerp: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Naam: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Kaartje"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Deeltjes effecten"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Attributen van personage OK"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Speler raakt Monster"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Naar links"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Speler viseren"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Speler viseren"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Speler viseren"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Speler viseren"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Aangepaste cursor"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Uitrusting"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Afdoen"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Help"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Sluiten"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventaris"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Opslag"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Sloten:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Uitrusten"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Gebruiken"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Neerleggen"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Splitsen"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Gewicht:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Opslaan"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Afhalen"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Neerleggen"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Alle"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Selecteer het aantal exemplaren om te verhandelen"
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Selecteer het aantal exemplaren om neer te leggen"
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Selecteer hoeveelheid voorwerpen te bewaren."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Selecteer hoeveelheid voorwerpen terug te nemen."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Selecteer hoeveelheid voorwerpen om te splitsen."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Onbekende foutmelding"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Gewicht "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Statusvenster"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Reset"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Reset"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Level: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Ervaring:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Naar links"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Sluiten"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Inloggen"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Onthoud Naam"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Aanmelden"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Map"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Wachten op server"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Volgende"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Indienen"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Sluiten"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Volgende"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Aan:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Verzenden"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Kon niet zenden als zender, of de brief is ongeldig."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Geld: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Afdoen"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Handelen met %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|%s aanvallen@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Gebruiken@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Annuleren@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+msgid "@@friend|Befriend@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+msgid "@@disregard|Disregard@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+msgid "@@ignore|Ignore@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Gebruiken@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+msgid "@@unignore|Unignore@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "Voltooid"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Een gebruiker uitnodigen in de groep"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+msgid "@@kick party|Kick from party@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+msgid "@@guild-kick|Kick from guild@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Een gebruiker uitnodigen in de groep"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+msgid "@@undress|Undress@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Gebruiken@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|%s aanvallen@@"
+
+#: src/gui/popupmenu.cpp:240
+msgid "@@admin-kick|Kick@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+msgid "@@name|Add name to chat@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Annuleren@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|%s oppakken@@"
+
+#: src/gui/popupmenu.cpp:376
+msgid "@@chat|Add to chat@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Gebruiken@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Tab Accentuering"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Tab Accentuering"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Veranderen"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Opslaan"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Opslaan"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Opslaan"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Afhalen"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Afhalen"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Afhalen"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Van server wisselen"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Van personage wisselen"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Bevestigen:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "E-mail:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "De gebruikersnaam moet uit ten minste %d tekens bestaan."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "De gebruikersnaam moet uit minder dan %d tekens bestaan."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Het wachtwoord moet uit ten minste %d tekens bestaan."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Het wachtwoord moet uit minder dan %d tekens bestaan."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Wachtwoorden komen niet overeen."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Kies jouw server"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Poort:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Verbinden..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Aangepaste cursor"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Typ aub zowel het adres van de server, als de poort."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Wachten op server"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Joystick activeren"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Joystick activeren"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Audio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Volume van geluiden"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Muziek volume"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Geen tekst"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Kan niets kopen."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Kan niets kopen."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Naam tonen"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Dit is hoe de kleur eruit ziet"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Kleuren"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Type: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statisch"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Puls"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Regenboog"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Spectrum"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Vertraging: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Rood: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Groen: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Blauw: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Toepassen"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Vensters in beginstand"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Druk op de knop om het kalibreren te starten"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Kalibreren"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Joystick activeren"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Stoppen"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Maak rondjes met de stick"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Toetsenbord"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Toewijzen"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Toewijzen"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Standaard"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Conflict(en) tussen toetsen gevonden."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Accentueren"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Naam tonen"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Joystick activeren"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Accentueren"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Handelen inschakelen/uitschakelen"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Kan niets kopen."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Kan niets kopen."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Joystick activeren"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "als deeltje"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relatie"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutraal"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Vriend"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Genegeerd"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Handelen toestaan"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Fluisteren toestaan"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Naam tonen"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Spelers"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Tijdens negeren:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Naam tonen"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Naam tonen"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Speler viseren"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Deeltjes effecten"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Help"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Veranderen"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Herstart de client om de wijzigingen in werking te doen treden."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Klein"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Klein"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Middelmatig"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Groot"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Geen tekst"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Tekst"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Bellen, geen namen"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Bellen met namen"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "uit"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "laag"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "hoog"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "gemiddeld"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Volledig scherm"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relatie"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Aangepaste cursor"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Zichtbare namen"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Deeltjes effecten"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Notificatie bij oprapen weergeven"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "in chat"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "als deeltje"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Joystick activeren"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Achtergrond"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS limiet:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "FPS limiet:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Dekking van de GUI"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Omgevingseffecten"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Deeltjes details"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Lettergrootte"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Nee"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "modus en herstel van oude modus ook gefaald!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "modus en herstel van oude modus ook gefaald!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Overgaan naar volledig scherm"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "De veranderingen worden pas actief na opnieuw opstarten"
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Veranderen van OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Het wisselen van of naar OpenGL wordt pas actief na opnieuw opstarten"
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Schermresolutie veranderd"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Deeltjes effecten instellingen gewijzigd."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Wijzigingen treden in werking bij het wisselen van map."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Toevoegen"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Handel aanvragen"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s wil met jou handelen, aanvaard je dit?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Vaardigheden"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Omhoog"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Vaardigheidspunten: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Vaardigheidspunten: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Vaardigheden"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Level: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Level: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Guild"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Guild aangemaakt."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Guild aanmaken"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Weet u zeker dat u wilt afsluiten?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Groep"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Een gebruiker uitnodigen in de groep"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Een gebruiker uitnodigen in de groep"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Weet u zeker dat u wilt afsluiten?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Guild aanmaken"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Personage Aanmaken"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Gebruiker uitnodigen"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Groot"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Uitnodiging van %s aanvaard."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Uitnodiging van %s geweigerd."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Uitnodiging van %s aanvaard."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Uitnodiging van %s geweigerd."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Fout bij het creëren van guild."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Guild"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Kies jouw server"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Uitnodiging tot groep ontvangen, maar er is er al één."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s heeft je uitgenodigd om je bij groep %s te voegen."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Groepsuitnodiging aanvaarden"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Uitnodiging tot groep ontvangen, maar er is er al één."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s heeft je uitgenodigd om je bij hun groep te voegen."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s heeft je uitgenodigd om je bij groep %s te voegen."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s heeft je uitgenodigd om je bij hun groep te voegen."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s heeft je uitgenodigd om je bij groep %s te voegen."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Groepsuitnodiging aanvaarden"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Groep"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Kies jouw server"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Level: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Geld: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "Leven:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Ervaring:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "Magie:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Job: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Job:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Attributen van personage OK"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Level: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Vaardigheidspunten: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Naar links"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Handelen toestaan"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Naar links"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Algemeen"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magie"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magie"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Commando: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magie"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Commando: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Speler viseren"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Maximum level"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Naam tonen"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Handelen voorstellen"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Bevestigd. Wachten..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Handel goedkeuren"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Goedgekeurd. Wachten..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Handel: Jij"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Handel"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Jij krijgt %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Je geeft:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Veranderen"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Kan dat voorwerp niet toevoegen. Je kan één type voorwerp niet overlappen in "
+"het venster."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Je hebt niet genoeg geld."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Naam: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Actualiseren..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Verbinden..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Spelen"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Het updateproces is onvolledig."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Het is ten sterkste aanbevolen dat"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 je later opnieuw probeert"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Voltooid"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Wezen"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Vriend"
+
+#: src/gui/userpalette.cpp:111
+msgid "Disregarded Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Genegeerd"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "GM Namen"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Namen van andere Spelers"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Eigen Naam"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "GM Namen"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monsters"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monster raakt Speler"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Groep"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Guild"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Deeltjes effecten"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Notificatie bij opnemen"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Ervaring Notificatie"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Speler raakt Monster"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Monster raakt Speler"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Namen van andere Spelers"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Kritieke aanval"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Speler raakt Monster"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Speler raakt Monster"
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr ""
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Missers"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Tab Accentuering"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Accentueren"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Tab Accentuering"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monster raakt Speler"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Lijst van gebruikers in het huidig kanaal weergeven"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > stel het onderwerp van het huidig kanaal in"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Verlaat een kanaal"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Maakt een gebruiker een kanaalbeheerder"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Verwijdert een gebruiker van het kanaal"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Commando: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Dit commando geeft de gebruikers in het kanaal weer."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Commando: /topic <bericht>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Dit commando zet het onderwerp naar <bericht>."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Commando: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Dit commando verlaat het huidige kanaal."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+"Als je de laatste persoon in het kanaal bent, zal het kanaal worden "
+"verwijderd."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Commando: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Dit commando maakt van <nick> een kanaalbeheerder."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Kanaalbeheerders kunnen andere gebruikers uit het kanaal verwijderen en "
+"andere gebruikers kanaalbeheerders maken."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Commando: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Dit commando maakt <nick> het kanaal verlaten."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Een gebruiker nodig om kanaalbeheerder te maken!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Een gebruiker nodig om uit het kanaal te verwijderen!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Globale aankondiging:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Globale aankondiging van %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s fluistert: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Sluit de fluistertab"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Commando: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Dit commando sluit de huidige fluistertab."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Commando: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Dit commando geeft het aantal spelers dat momenteel online is weer."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Dit commando begint de chat log op te slaan naar het bestand <bestandsnaam>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Gespreksvenster"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Smilie"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Sneltoets"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "OK selecteren"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Veranderen"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Kies jouw server"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Omhoog"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Omlaag"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Naar links"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Naar rechts"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Viseren en Aanvallen"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Naar links"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Smilie"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Aanval stoppen"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Dichtstbijzijnde viseren"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "NPC viseren"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Speler viseren"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Oprapen"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Vensters verbergen"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Zitten"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Schermafdruk"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Handelen inschakelen/uitschakelen"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Emailadres wijzigen"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Snelkopeling naar voorwerp %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Snelkopeling naar voorwerp %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Help venster"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Statusvenster"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Uitrustingsvenster"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Vaardigheidsvenster"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Minimapvenster"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Gespreksvenster"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Voorwerpsnelkoppelingsvenster"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Instellingenvenster"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Debugvenster"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Vaardigheidsvenster"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Emoticonsnelkoppelingsvenster"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Statusvenster"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Instellingenvenster"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Vensters verbergen"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Statusvenster"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Commando: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Gespreksvenster"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Vorige chattab"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Volgende chattab"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Emoticon snelkoppeling %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Chat omhoogscrollen"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Chat omlaagscrollen"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Vorige chattab"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Volgende chattab"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Vorige chattab"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Volgende chattab"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "OK selecteren"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ingave 1 negeren"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ingave 2 negeren"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Omlaag"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Naar links"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Naar rechts"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Van personage wisselen"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Server"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Viseren en Aanvallen"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Wijzig wachtwoord"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Emailadres wijzigen"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Handelen inschakelen/uitschakelen"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Los deze problemen op, of het spel kan raar gedrag vertonen."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Kan het voorwerp niet oprapen."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Je raapte %s [@@%d|%s@@] op."
+msgstr[1] "Je raapte %s [@@%d|%s@@] op."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Jij krijgt %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opties:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Gebruikte configuratiebestand"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Gebruikte configuratiebestand"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Versie weergeven"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Deze help weergeven"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Gebruikte configuratiebestand"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Login met deze gebruikersnaam"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Login met dit wachtwoord"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Login met dit personage"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Loginserver naam of IP-adres"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Loginserver poort"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Gebruik deze updatehost"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Kies standaard personageserver en personage"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Sla update downloads over"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Map waarvan speldata geladen wordt"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Map te gebruiken als home"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Map te gebruiken als home"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : OpenGL uitschakelen voor deze sessie"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Kracht"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Kracht %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Behendigheid"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Behandigheid %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Vaardigheid"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Vaardigheid %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Vitaliteit"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Vitaliteit %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligentie"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligentie %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Wilskracht:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Wilskracht %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Je bent dood."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+"We betreuren het om je te melden dat jouw personage is gestorven in een "
+"gevecht."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Je bent niet langer levend."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "De koude handen van Pietje de Dood grijpen naar jouw ziel."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Game Over!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Neen, kinderen. Jouw personage is niet echt gestorven. Het... euhm... is "
+"naar een beter plaats gegaan."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Jouw plan om vijandelijke wapens te vernietignen door ermee tegen jouw keel "
+"te slaan is mislukt."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Dit verliep niet zoals gepland."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Wil je dat jouw bezittingen geïdentificeerd worden?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Spijtig genoeg, was er geen spoor van jou gevonden..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Verslagen"
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+"Je hebt het weer verknald, dump jouw lichaam en ga er een nieuw halen."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Druk op OK om te respawnen"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Je stierf"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Reeds aangemeld"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Gebruikersnaam bestaat al"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Attributen van personage OK"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Attributen van personage OK"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Onbekende foutmelding"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Info"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Personage verwijderd."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Selecteer het aantal exemplaren om te verhandelen"
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Onbekende foutmelding"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Geen gameservers beschikbaar."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Onderwerp: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Speler raakt Monster"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Commando: /join <kanaal>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Aanvragen om bij kanaal %s toegevoegd te worden."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s heeft zich bij de groep gevoegd."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Onbekend commando."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Guild aangemaakt."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Fout bij het creëren van guild."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Uitnodiging verzonden."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Lid is succesvol gepromoveerd."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Kon lid niet promoveren."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Verkeerd magie_teken"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Reeds aangemeld"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Account verlopen"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Nieuw wachtwoord is incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Oud wachtwoord incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Account niet verbonden. Log eerst in aub."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Nieuw emailadres is incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Oud emailadres is incorrect"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Het nieuwe emailadres bestaat al."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Te oude Client versie"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Verkeerde gebruikersnaam of wachtwoord"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Account verlopen"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Verkeerde gebruikersnaam, wachtwoord of emailadres"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Gebruikersnaam bestaat al"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "emailadres bestaat al"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Bijgevoegd bij groep."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s heeft zich bij de groep gevoegd."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s wees jouw uitnodiging af."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Inkomende handelsaanvragen accepteren."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Inkomende handelsaanvragen negeren."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s wil met jou handelen, aanvaard je dit?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Handelen met %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Handel geannuleerd."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Handel voltooid."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Kick gefaald!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Kick succesvol!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Niets te verkopen."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Bedankt voor de aankopen."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Kan niets kopen."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Bedankt voor het verkopen."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Kan niets verkopen."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Kan deze ID niet gebruiken"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Onbekende foutmelding"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Kan personage niet aanmaken. Waarschijnlijk bestaat de naam al."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Personage verwijderd."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Kon personage niet verwijderen."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Sterkte:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agiliteit:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitaliteit:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligentie:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Dexteriteit:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Geluk:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Fluisterbericht kon niet verzonden worden, gebruiker is offline."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Fluisterbericht kon niet verzonden worden, genegeerd door gebruiker."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Speler"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Speler"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Kanalen worden niet ondersteund!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Naam"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Handel aanvragen"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Kracht %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Behandigheid %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Vitaliteit %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligentie %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Vaardigheid %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Geluk %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Authenticatie mislukt"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Geen servers beschikbaar"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Iemand anders probeert deze account te gebruiken"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Deze account is reeds aangemeld"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Speedhack gedetecteerd"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Dubbele login"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Onbekenden connectiefout"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "De verbinding met de server werd verbroken!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Geluk"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Verdediging:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "Magische Aanval:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "Magische Verdediging:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Nauwkeurigheid:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Ontwijking:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Kritieke aanval"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Aanval %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Aanval %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monster raakt Speler"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Geeft deze help weer."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Nodig een speler uit voor jouw groep"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Verlaat de groep waarin je je bevindt"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Verwijder iemand vanuit de groep waarin je bent"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Commando: /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Dit commando nodigt <nick> uit om een groep te vormen met jou."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Commando: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Dit commando zorgt ervoor dat de speler de groep verlaat."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Fout bij het creëren van guild."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Onbekend uitnodigingsantwoord van %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Guild"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Guild"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Level: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Maximum level"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Guild"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Guild aangemaakt."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Guild aangemaakt."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s is nu een lid van jouw groep."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Onbekend uitnodigingsantwoord van %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Je hebt de groep verlaten."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s heeft jouw groep verlaten."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s is nu een lid van jouw groep."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Nodig een speler uit voor jouw groep"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Verlaat de groep waarin je je bevindt"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Verwijder iemand vanuit de groep waarin je bent"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Geeft weer/wijzigt de opties voor voorwerpdeling"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Geeft weer/wijzigt de ervaringsdelingsopties"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Dit commando zorgt ervoor dat de speler de groep verlaat."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Commando: /item <beleid>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Dit commando wijzigt het voorwerpdelingsbeleid van de groep."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<beleid> kan een van de volgende zijn om voorwerpdeling in te schakelen: "
+"\"1\", \"yes\", \"true\". Of om voorwerpdeling uit te schakelen: \"0\", \"no"
+"\", \"false\"."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Commando: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+"Dit commando geeft het huidige voorwerpdelingsbeleid van de groep weer."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Commando: /exp <beleid>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Dit commando wijzigt het ervaringsdelingsbeleid van de groep."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<beleid> kan een van de volgende zijn om ervaringsdeling in te schakelen: "
+"\"1\", \"true\", \"yes\". Of om ervaringsdeling uit te schakelen: \"0\", "
+"\"false\", \"no\"."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Commando: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+"Dit commando geeft het huidige ervaringsdelingbeleid van de groep weer."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Voorwerpdeling ingeschakeld."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Voorwerpdeling uitgeschakeld."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Voorwerpdeling is niet mogelijk."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Voorwerpdeling ingeschakeld."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Ervaringsdeling ingeschakeld."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Ervaringsdeling uitgeschakeld."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Ervaringsdeling is niet mogelijk."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Ervaringsdeling ingeschakeld."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Kan voorwerp niet gebruiken."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Kan dit niet uitrusten."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Account was niet gevonden. Probeer opnieuw in te loggen aub."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Nieuw wachtwoord is te kort"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Ongeregistreerde ID"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Onjuist wachtwoord"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Account verlopen"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Geweerd van server"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Je bent permanent geband van het spel. Neem aub contact op met het GM team."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Je bent tijdelijk geband van het spel tot %s.\n"
+"Neem aub contact op met het GM team via de forums."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Deze gebruikersnaam bestaat al"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Kan niets verkopen."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Verbinden met de map server..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Kan geen groep aanmaken."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Groep succesvol aangemaakt."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s is al een lid van een groep."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s wees jouw uitnodiging af."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s is nu een lid van jouw groep."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Onbekend uitnodigingsantwoord van %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Je hebt de groep verlaten."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s heeft jouw groep verlaten."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Een onbekend lid probeerde te zeggen: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s is niet in jouw groep!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Werp een muntstuk in om verder te spelen."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Je bent nog niet dood. Je bent maar aan het rusten."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Je bent niet langer."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Je hebt opgehouden te zijn."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Je bent verlopen en gaat een bezoekje maken bij jouw schepper."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Je bent stokstijf."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Beroofd van het leven, rust je in vrede."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Jouw metabolische processen behoren nu tot het verleden."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Je bent een ex-speler."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Bericht"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Je draagt meer dan de helft van jouw eigen gewicht. Je kan geen leven "
+"herstellen."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Je draagt meer dan de helft van jouw eigen gewicht. Je kan geen leven "
+"herstellen."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Je raapte op: "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Jij krijgt %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Handel mislukte!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Emoticon gefaald!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Zitten niet mogelijk!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Chatcreatie mislukte!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Kan je niet bij de groep voegen!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Kan niet roepen!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Je hebt nog geen hoog genoeg level bereikt!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Onvoldoende leven!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Onvoldoende Vaardigheidspunten!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Je hebt geen memo's!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Je kan dat nu niet doen!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Het lijkt erop dat je meer geld nodig hebt... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Je kan die vaardigheid niet gebruiken met dit type wapen!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Je hebt een andere rode edelsteen nodig!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Je hebt een andere blauwe edelsteen nodig!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Je draagt teveel bij je om dit te doen!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Huh? Wat is dat?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Warp mislukt..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Kon niets stelen..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Gif had geen effect..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Handelen is niet mogelijk. Partner is te ver weg."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Handelen is niet mogelijk. Personage bestaat niet."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Handel onderbroken vanwege een onbekende reden."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Handelen: Jij en %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Handel met %s geannuleerd."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Onbehandelde handelannulatiepakket."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Kan voorwerp niet toevoegen. Handelspartner is al te zwaar beladen."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "Kan voorwerp niet toevoegen. Handelspartner heeft geen vrij slot."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Kan voorwerp niet toevoegen voor een onbekende reden."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "Voltooid"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Aanval %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Verdediging %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "Leven %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "Magie %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Onbekend voorwerp"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "naamloos"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Deeltjes details"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Omgevingseffecten"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Emoticon snelkoppeling %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Speler raakt Monster"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Onderwerp: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Naam: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "Kaartje"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > De chat beginnen opnemen naar een extern bestand"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Commando: /record <bestandsnaam>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Dit commando begint de chat log op te slaan naar het bestand "
+#~ "<bestandsnaam>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Commando: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Dit commando beëindigt het opslaan van de chatlog."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Aanwezigheid geschreven in logbestand."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Opname voltooid."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Momenteel niet aan het opnemen."
+
+#~ msgid "Already recording."
+#~ msgstr "Reeds aan het opnemen."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Opname starten..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Kan de opname niet starten."
+
+#~ msgid "Recording..."
+#~ msgstr "Opnemen..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Stoppen met opnemen"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Pad naar Muis vinden"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "Leven:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "Magie:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Ervaring:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Geld: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Job:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Level: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Groep succesvol aangemaakt."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr ""
+#~ "Fluisterbericht kon niet verzonden worden, genegeerd door gebruiker."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Gebruikte configuratiebestand"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Gebruikte configuratiebestand"
+
+#~ msgid "Sound"
+#~ msgstr "Geluid"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Toegang geweigerd"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Onbekende fout bij het selecteren van personage"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Op deze manier iemand uitnodigen wordt momenteel niet ondersteund."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s heeft je uitgenodigd om je bij hun groep te voegen."
+
+#~ msgid "Willpower:"
+#~ msgstr "Wilskracht:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Server is volzet"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Handelen met %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Fluister"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "%s is niet in jouw groep!"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Kick gefaald!"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "Monsters"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Oprapen"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Kan geen leeg chatbericht sturen!"
+
+#~ msgid "Text Shadow"
+#~ msgstr "Tekstschaduw"
+
+#~ msgid "Text Outline"
+#~ msgstr "Tekstuitlijning"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Vooruitgangsbalk Labels"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Voorwerp te duur"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Voorwerp wordt al gedragen"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Speler"
+
+#~ msgid "Whisper"
+#~ msgstr "Fluister"
+
+#~ msgid "Is"
+#~ msgstr "is gelijk aan"
+
+#~ msgid "Server"
+#~ msgstr "Server"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Onbekend type voorwerp"
+
+#~ msgid "Generics"
+#~ msgstr "Generiek"
+
+#~ msgid "Hats"
+#~ msgstr "Hoeden"
+
+#~ msgid "Usables"
+#~ msgstr "Gebruiksvoorwerpen"
+
+#~ msgid "Shirts"
+#~ msgstr "Shirts"
+
+#~ msgid "Pants"
+#~ msgstr "Broeken"
+
+#~ msgid "Shoes"
+#~ msgstr "Schoenen"
+
+#~ msgid "Shields"
+#~ msgstr "Schilden"
+
+#~ msgid "Rings"
+#~ msgstr "Ringen"
+
+#~ msgid "Necklaces"
+#~ msgstr "Kettingen"
+
+#~ msgid "Arms"
+#~ msgstr "Wapens"
+
+#~ msgid "Ammo"
+#~ msgstr "Ammunitie"
+
+#~ msgid "HP Bar"
+#~ msgstr "Levensbalk"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 Levensbalk"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 Levensbalk"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 Levensbalk"
+
+#~ msgid "no"
+#~ msgstr "nee"
+
+#~ msgid "Buddy"
+#~ msgstr "Vriend"
+
+#~ msgid "Buddy List"
+#~ msgstr "Vriendenlijst"
+
+#~ msgid "Description: %s"
+#~ msgstr "Beschrijving: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effect: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Vorige"
+
+#~ msgid "New"
+#~ msgstr "Nieuw"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Beroep niveau: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Aanwezig: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Guild verlaten"
+
+#~ msgid "Ok"
+#~ msgstr "OK"
+
+#~ msgid "Recent:"
+#~ msgstr "Recent:"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Uitrusten@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Neerleggen@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Server Selecteren"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Kan niet wisselen naar "
+
+#~ msgid "windowed"
+#~ msgstr "in venster"
+
+#~ msgid "fullscreen"
+#~ msgstr "volledig scherm"
+
+#~ msgid "Weapons"
+#~ msgstr "Wapens"
+
+#~ msgid "Stats"
+#~ msgstr "statistieken"
+
+#~ msgid "Total"
+#~ msgstr "Totaal"
+
+#~ msgid "Cost"
+#~ msgstr "Kosten"
+
+#~ msgid "Attack:"
+#~ msgstr "Aanval:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Reflex:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Overblijvende statuspunten: %d"
+
+#~ msgid " host: "
+#~ msgstr " host: "
+
+#~ msgid "Buddys"
+#~ msgstr "Vrienden"
+
+#~ msgid "Party Window"
+#~ msgstr "Groepsvenster"
+
+#~ msgid "Unarmed"
+#~ msgstr "Ongewapend"
+
+#~ msgid "Knife"
+#~ msgstr "Mes"
+
+#~ msgid "Sword"
+#~ msgstr "Zwaard"
+
+#~ msgid "Staff"
+#~ msgstr "Staf"
+
+#~ msgid "Whip"
+#~ msgstr "Zweep"
+
+#~ msgid "Bow"
+#~ msgstr "Boog"
+
+#~ msgid "Shooting"
+#~ msgstr "Schieten"
+
+#~ msgid "Mace"
+#~ msgstr "Goedendag"
+
+#~ msgid "Axe"
+#~ msgstr "Bijl"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Onbekende vaardigheid"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " kan niet gecreëerd worden, maar het bestaat niet! Verlaten."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Kan niet instellen van "
+
+#~ msgid " video mode: "
+#~ msgstr " video modus: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Verbinden met de karakter server..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Verbinden met de account server..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Zelfde functie als create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Commando: /new <groepsnaam>"
+
+#~ msgid "a"
+#~ msgstr "een"
+
+#~ msgid "Unnamed"
+#~ msgstr "Naamloos"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Scroll radius"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Scroll vertraging"
diff --git a/po/pl.po b/po/pl.po
new file mode 100644
index 000000000..50203d8be
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,5759 @@
+# Polish translation of The Mana World.
+# Copyright (C) 2007 The Mana World Development Team
+# This file is distributed under the same license as the The Mana World package.
+# Mateusz Jedrasik <m.jedrasik@gmail.com>, 2007.
+# Zuzanna K. Filutowska <platyna@platinum.linux.pl>, 2007.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: The Mana World 0.1.0\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2009-09-14 06:59+0000\n"
+"Last-Translator: Maciej Benke <syngress_stc@vp.pl>\n"
+"Language-Team: <pl@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2)\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Konfiguracja"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Łączenie z serwerem map..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Użytkownik"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Wybierz postać"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Łączenie z serwerem map..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Serwer"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Błąd"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Hasło:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Zmień"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Członek został pomyślnie wypromowany."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Wyrejestruj"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Nieprawidłowy host aktualizacji: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Błąd podczas tworzenia katalogu aktualizacji!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Nieznane polecenie."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Pomoc --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Pokazuje tę pomoc"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Wyświetla nazwę mapy"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Wyświetla liczbę podłączonych użytkowników"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Powiedz coś o sobie"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Czyści to okno"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Wysyła prywatną wiadomość do użytkownika"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alias polecenia msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Alias polecenia msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+"/query > Tworzy zakładkę dla prywatnych wiadomości z innym użytkownikiem"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Alias polecenia query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Zamyka zakładkę szeptania"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Lekceważ %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Pokaż wszystkie publiczne kanały"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Dołącz lub utwórz kanał"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Utworzenie nowej grupy"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Utworzenie nowej grupy"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Zaproś użytkownika do grupy"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Określa czy <return> przełącza dziennik czatu"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Pobiera listę obecnych graczy (przesyła do dzienika czatu, jeżeli "
+"zapisywanie jest włączone)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Globalne ogłoszenie (tylko GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Zamyka zakładkę szeptania"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Wysyła prywatną wiadomość do użytkownika"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Aby uzyskać więcej informacji, wpisz /help <komenda>"
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Komenda: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Ta komenda wyświetla listę dostępnych komend."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Komenda: /help <komenda>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Ta komenda wyświetla pomoc dotyczącą <komenda>"
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Komenda: /announce <wiadomość>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** dostępne tylko dla GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"Ta komenda wysyła wiadomość <wiadomość> to wszystkich połączonych graczy."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Komenda: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Ta komenda czyści zawartość okna."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Komenda: /item <zasada>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Ta komenda wyświetla liczbę połączonych graczy."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Komenda: /join <kanał>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Ta komenda powoduje, iż wejdziesz do <kanał>"
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Jeżeli <kanał> nie istnieje, to zostanie utworzony."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Komenda: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Ta komenda pokazuje listę wszystkich kanałów."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Komenda: /me <wiadomość>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Ta komenda mówi innym co (robisz) <wiadomość>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Komenda: /msg <ksywka> <wiadomość>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Komenda: /whisper <ksywka> <wiadomość>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Komenda: /w <ksywka> <wiadomość>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Ta komenda wysyła tekst <wiadomość> do <ksywka>"
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Jeżeli <postać> ma spację, należy ją zapisać w cudzysłowie (\")"
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Komenda: /query <ksywka>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Komenda: /q <ksywka>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Ta komeda próbuje utworzyć zakładkę dla prywatnych wiadomości pomiędzy tobą "
+"i <ksywka>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Komenda: /w <ksywka> <wiadomość>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Komenda: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Ta komenda ustawia temat na <wiadomość>."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Komenda: /create <nazwa-grupy>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Te komendy utworzą nową grupę nazwaną <nazwa-grupy>."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Komenda: /create <nazwa-grupy>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Te komendy utworzą nową grupę nazwaną <nazwa-grupy>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Komenda: /party <ksywka>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Ta komenda zaprasza <ksywka> do twojej grupy."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Komenda: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Ta komenda pobiera listę graczy w zasięgu słuchu i wysyła ją do dziennika "
+"zapisu, lub dziennika czatu."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Komenda: /toggle <stan>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Ta komenda ustawia, czy klawisz return powinien włączać dziennik zapisu, lub "
+"czy dziennik zapisu powinien się automatycznie wyłączyć."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<stan> może być jednym z \"1\", \"yes\", \"true\" aby uaktywnić przełącznik, "
+"lub \"0\", \"no\", \"false\" by deaktywować przełącznik."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Komenda: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Ta komenda wyświetla status przełącznika"
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Komenda: /item <zasada>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Komenda: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Ta komenda wyświetla nazwę aktualnej mapy."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Komenda: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Ta komenda wyświetla liczbę połączonych graczy."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Wpisz /help aby usyskać listę komend."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Nie można wysłać pustych szeptów!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Nie można utworzyć zakładki szeptu dla ksywki \"%s\"! Już istnieje, albo to "
+"ty."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Prośba o dołączenie do kanału %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Brakuje nazwy grupy."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Brakuje nazwy grupy."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Return włącza czat."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Wiadomość zamyka czat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Return od teraz włącza czat."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Wiadomość od teraz zamyka czat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Przyjaciel"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Nielubiany"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutralny"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Szept nie mógł zostać wysłany, jesteś ignorowany przez odbiorcę."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Pomyślnie utworzono grupę."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Szept nie mógł zostać wysłany, jesteś ignorowany przez odbiorcę."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Szept nie mógł zostać wysłany, jesteś ignorowany przez odbiorcę."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Szept nie mógł zostać wysłany, jesteś ignorowany przez odbiorcę."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Pomyślnie utworzono grupę."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Szept nie mógł zostać wysłany, jesteś ignorowany przez odbiorcę."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr "Opcjami dla /%s są \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Ogólny"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Zrzut ekranu zapisany do ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Zapisywanie zrzutu ekranu nie powiodło się!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Połączenie z serwerem zostało utracone, program zakończy pracę"
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Błąd sieci"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignorowanie przychodzących próśb o handel"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Akceptowanie przychodzących próśb o handel"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Nie można załadować mapy"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Błąd podczas łądowania %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Grupa (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Gildie"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Okno Emotek"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Nazwa"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Atak"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Rozmowa"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Przesuń w górę"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Resetuj"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Kup"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Cena: %s/ Razem: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Wyjdź"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Maks."
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Sklep"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Sprzedaj"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Zmień adres Email"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Konto: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Wpisz dwukrotnie nowy adres email:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Nazwa użytkownika musi być długa na conajmniej %d znaków."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Nazwa użytkownika musi mieć mniej niż %d znaków."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Nowy Adres Email już istnieje"
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Zmień hasło"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Hasło:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Wpisz dwukrotnie nowe hasło:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Hasło musi mieć conajmniej %d znaków."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Hasło nie może mieć więcej jak %d znaków."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Stwórz postać"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Imię:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Kolor włosów:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Fryzura:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Utwórz"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Mężczyzna"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Kobieta"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Proszę wykorzystać %d punktów"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Twoje imię musi mieć conajmniej 4 znaki."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Statystyki postaci w porządku."
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Proszę usunąć %d punktów"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Potwierdź usunięcie postaci"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Czy jesteś pewien, że chcesz usunąć tę postać?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Zarządzanie kontem i postaciami"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Wyrejestruj"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Zmień adres Email"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Usuń"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Zamknij"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Domyślny"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Przyjaciel"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Zielony: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Niebieski: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "niskie"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Hiperłącze"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Rzucana"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Tęcza"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Tęcza"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Tęcza"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Czat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d graczy jest obecnych."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Szepczesz do %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Tak"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Nie"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignorowany"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Temat: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Imię: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "MiniMapa"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Efekty Cząsteczkowe"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Statystyki postaci w porządku."
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Gracz uderza Potwora"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Przesuń w lewo"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Namierz Gracza"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Namierz Gracza"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Namierz Gracza"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Namierz Gracza"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Własny kursor"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "Ok"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Ekwipunek"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Zdejmij"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Pomoc"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Zamknij"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inwentarz"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Magazyn"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Miejsc:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Załóż"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Użyj"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Upuść"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Podziel"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Waga:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Przechowaj"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Pobierz"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Upuść"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "wszystkie"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Wybierz ilość przedmiotów do handlu."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Wybierz ilość przedmiotów do upuszczenia."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Podaj ilość rzeczy do przechowania."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Wybierz ilość przedmiotów do pobrania."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Wybierz ilość przedmiotów do podziału."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Nieznany błąd"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Waga: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Okno statusu"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Resetuj"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Resetuj"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Poziom: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Przesuń w lewo"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Zamknij"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Użytkownik"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Serwer:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Zapamiętaj użytkownika"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Rejestruj"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Serwer"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Mapa"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Oczekiwanie na serwer"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Następna"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Zatwierdź"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Kij"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Następna"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Do:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Wyślij"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Nie powiodła się wysyłka jako nadawca, albo list jest nieprawidłowy."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Pieniądze: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Zdejmij"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Handel z %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Atakuj %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Użyj@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Anuluj@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Pobierz@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Lekceważ %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignoruj %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Użyj@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Przestań Ignorować %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Kompletnie ignoruj %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Zaproś użytkownika do grupy"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Wykop gracza@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Wykop gracza@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Zaproś użytkownika do grupy"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Wykop gracza@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Przestań Ignorować %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Użyj@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Atakuj %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Wykop gracza@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Dodaj imię do czatu@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Anuluj@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Podnieś %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Dodaj do czatu@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Użyj@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Podświetlenie zakładki"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Podświetlenie zakładki"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Zmień"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Przechowaj"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Przechowaj"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Przechowaj"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Pobierz"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Pobierz"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Pobierz"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Dodaj do czatu@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Zmień serwer"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Zmień postać"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Potwierdź:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Nazwa użytkownika musi być długa na conajmniej %d znaków."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Nazwa użytkownika musi mieć mniej niż %d znaków."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Hasło musi mieć conajmniej %d znaków."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Hasło nie może mieć więcej jak %d znaków."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Hasła nie zgadzają się."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Wybierz twój serwer"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Serwer:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Łączenie..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Własny kursor"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Proszę wpisać adres i port serwera"
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Oczekiwanie na serwer"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Włącz joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Włącz joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Dźwięk"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Głośność efektów dźwiękowych"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Głośność muzyki"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Brak tekstu"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Nie można kupić."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Nie można kupić."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Pokaż imię"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Kolor będzie wyglądał w ten sposób"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Kolory"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Typ: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statyczny"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Puls"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Tęcza"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Widmo"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Opóźnienie: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Czerwony: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Zielony: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Niebieski: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Zastosuj"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Zresetuj okna"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Naciśnij przycisk aby rozpocząć kalibrację"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Kalibruj"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Włącz joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Zatrzymaj"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Obróć drążek"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Klawiatura"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Przypisz"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Przypisz"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Domyślny"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Wykryto konflikt klawiszy."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Podświetlenie"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Pokaż imię"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Włącz joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Podświetlenie"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Włącz/Wysłącz Handlowanie"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Nie można kupić."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Nie można kupić."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Włącz joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "jako cząsteczkę"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relacja"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutralny"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Przyjaciel"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Nielubiany"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignorowany"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Zezwól na handel"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Zezwól na szepty"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Umieść wszystkie szepty w zakładkach"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Pokaż imię"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Gracze"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Gdy ignorowany:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Pokaż imię"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Pokaż imię"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Namierz Gracza"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Efekty Cząsteczkowe"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Pomoc"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Zmień"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Uruchom ponownie twojego klienta, aby mogły zajść zmiany."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Drobna"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Mała"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Średnia"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Duża"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Brak tekstu"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Tekst"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Bąbelki, brak imion"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Bąbelki z imionami"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "wyłączone"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "niskie"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "wysokie"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "średnie"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Pełen ekran"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relacja"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Własny kursor"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Widoczne imiona"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Efekty cząsteczkowe"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Pokaż powiadomienie o podniesieniu"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "w czacie"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "jako cząsteczkę"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Włącz joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Tło"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Limit FPS:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "Limit FPS:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Obraz"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Tekst nad głową"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Przezroczystość GUI"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Efekty otoczenia"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Detale cząsteczek"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Rozmiar czcionki"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Nie"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "tryb i przywrócenie starego trybu również nie powiodło się!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "tryb i przywrócenie starego trybu również nie powiodło się!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Przełączanie na pełen ekran"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Wymagane ponowne uruchomienie aby zastosować zmiany."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Zmień na OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Zastosowanie zmiany na OpenGL wymaga ponownego uruchomienia."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Zmieniono rozdzielczość ekranu"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Zmieniono ustawienia ef. cząsteczek"
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Efekty nastąpią po zmianie mapy."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Dodaj"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Prośba o Handel"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s chce handlować z tobą, zgadzasz się?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Zdolności"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Góra"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Punkty umiejętności: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Punkty umiejętności: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Zdolności"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Poziom: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Poziom: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Gildia"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Gildia została utworzona."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Utwórz Gildię"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Czy na pewno chcesz wyjść?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Grupa"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Zaproś użytkownika do grupy"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Zaproś użytkownika do grupy"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Czy na pewno chcesz wyjść?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Utwórz Gildię"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Stwórz postać"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Zaproś Użytkownika"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Duża"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Zaakceptowano zaproszenie od %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Odrzucono zaproszenie od %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Zaakceptowano zaproszenie od %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Odrzucono zaproszenie od %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Błąd podczas tworzenia gildii."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Gildia"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Wybierz twój serwer"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Otrzymano prośbę o założenie grupy, ale ona już istnieje."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s zaprosił ciebie, byś dołączył do grupy %s ."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Zaakceptuj zaproszenie do grupy"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Otrzymano prośbę o założenie grupy, ale ona już istnieje."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s zaprosił ciebie, byś dołączył do grupy."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s zaprosił ciebie, byś dołączył do grupy %s ."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s zaprosił ciebie, byś dołączył do grupy."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s zaprosił ciebie, byś dołączył do grupy %s ."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Zaakceptuj zaproszenie do grupy"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Grupa"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Wybierz twój serwer"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Poziom: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Pieniądze: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Praca: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Praca:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Statystyki postaci w porządku."
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Poziom: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Punkty umiejętności: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Przesuń w lewo"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Zezwól na handel"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Przesuń w lewo"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Ogólny"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magia"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magia"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Komenda: /przedmiot"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magia"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Komenda: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Namierz Gracza"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Maks. poziom"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Pokaż imię"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Oferuj handel"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Potwierdzono. Oczekiwanie..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Akceptuj handel"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Zaakceptowano. Oczekiwanie..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Handel: Ty"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Handel"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Otrzymujesz %s"
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Dajesz:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Zmień"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Dodanie przedmiotu nie powiodło się. Nie może zachodzić na siebie ten sam "
+"rodzaj przedmiotu w okienku."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Nie masz wystarczającej ilości pieniędzy."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Imię: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Aktualizacja..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Łączenie..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Graj"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Proces aktualizacji jest niekompletny."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Jest mocno zalecane abyś"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 spróbował później"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Zakończono"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Byty"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Przyjaciel"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Nielubiany"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignorowany"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "Imiona GM"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Imiona Innych Graczy"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Własne Imię"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Imiona GM"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPC"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Potwory"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Potwór uderza Gracza"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Grupa"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Gildia"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Efekty Cząsteczkowe"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Powiadomienie o podniesieniu"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Powiadomienie o Exp"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Gracz uderza Potwora"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Potwór uderza Gracza"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Imiona Innych Graczy"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Uderzenie Krytyczne"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Gracz uderza Potwora"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Gracz uderza Potwora"
+
+#: src/gui/userpalette.cpp:137
+#, fuzzy
+msgid "Local Player Miss"
+msgstr "Zapisz listę graczy"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Pudła"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Podświetlenie zakładki"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Podświetlenie"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Podświetlenie zakładki"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Potwór uderza Gracza"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Pokazuje listę użytkowników w obecnym kanale"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Ustawia temat obecnego kanału"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Opuszcza kanał"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Uczyń użytkownika operatorem kanału"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Wykop użytkownika z kanału"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Komenda: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Ta komenda pokazuje użytkowników w tym kanale."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Komenda: /topic <wiadomość>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Ta komenda ustawia temat na <wiadomość>."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Komenda: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Komenda powoduje opuszczenie obecnego kanału."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Jeżeli jesteś ostatnią osobą na kanale, zostanie on usunięty."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Komenda: /op <ksywka>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Ta komenda uczyni <ksywka> operatorem kanału."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr "Operatorzy kanału mogą wykopywać i dawać opy użytkownikom kanału."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Komenda: /kick <ksywka>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Komenda spowoduje, iż <ksywka> opuści kanał."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Wymagany użytkownik, aby przydzielić opa!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Wymagany użytkownk, aby go wykopać!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Ogłoszenie ogólne:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Ogłoszenie ogólne od %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s szepcze: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Zamyka zakładkę szeptania"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Komenda: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Komenda zamyka obecną zakładkę szeptania"
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Komenda: /przedmiot"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Ta komenda wyświetla liczbę połączonych graczy."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Ta komenda rozpoczyna zapisywanie dziennika czatu to pliku <nazwa_pliku."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Okno Emotek"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Emotikonka"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Stan"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Skrót"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Wybrano OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Zmień"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Wybierz twój serwer"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Przesuń w górę"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Przesuń w dół"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Przesuń w lewo"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Przesuń w prawo"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Namierz i Atakuj"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Przesuń w lewo"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Emotikonka"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Zatrzymaj Atak"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Namierz najbliższy cel"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Namierz NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Namierz Gracza"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Podnieś"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Ukryj Okna"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Usiądź"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Zrzut ekranu"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Włącz/Wysłącz Handlowanie"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Zmień adres Email"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Skrót Przedmiotu %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Skrót Przedmiotu %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Okno Pomocy"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Okno statusu"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Okno Inwentarza"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Okno Ekwipunku"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Okno Umiejętności"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Okno Minimapy"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Okno Czatu"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Okno Skrótów Przedmiotów"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Okno Ustawień"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Okno diagnostyczne"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Okno Umiejętności"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Okno Skrótów Emotek"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Okno statusu"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Okno Ustawień"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Ukryj Okna"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Okno statusu"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Komenda: /przedmiot"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Okno Emotek"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Poprzednia zakładka czatu"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Następna zakładka czatu"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Skrót Emotki %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Przełącznik Czatu"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Przewiń czat do góry"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Przewiń czat w doł"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Poprzednia zakładka czatu"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Następna zakładka czatu"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Poprzednia zakładka czatu"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Następna zakładka czatu"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Wybrano OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignoruj wprowadzenie 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignoruj wprowadzenie 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Przesuń w dół"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Przesuń w lewo"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Przesuń w prawo"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Zmień postać"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Serwer"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Namierz i Atakuj"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Zmień hasło"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Zmień adres Email"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Włącz/Wysłącz Handlowanie"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Rozwiąż je, albo granie może być utrudnione."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Nie można podnieść przedmiotu."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Podniosłeś %s [@@%d|%s@@]."
+msgstr[1] "Podniosłeś %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Otrzymujesz %s"
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opcje:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Plik konfiguracyjny do użycia"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Plik konfiguracyjny do użycia"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Pokazuje wersję"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Pokazuje tę pomoc"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Plik konfiguracyjny do użycia"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Zaloguj z tą nazwą użytkownika"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Zaloguj z tym hasłem"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Zaloguj z tą postacią"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Nazwa serwera logowania, lub IP"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Port serwera logowania"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Użyj tego hosta aktualizacji"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Wybierz domyślny serwer postaci i postać"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Pomiń pobieranie aktualizacji"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Katalog, z którego załadować dane gry"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Katalog do użycia jako katalog domowy"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Katalog do użycia jako katalog domowy"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Wyłącz OpenGL dla tej sesji"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Siła"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Siła %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Zwinność"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Zwinność %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Zręczność"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Zręczność %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Witalność"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Witalność %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Inteligencja"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Inteligencja %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Siła woli:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Siła woli %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Jesteś martwy."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "Ubolewamy, inforumując iż twoja postać została zabita w bitwie."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Już nie jesteś taki żywy."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Skostniałe łapy ponurego żniwiarza sięgają po twoją duszę."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Koniec gry!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Nie, dzieci. Wasza postać tak naprawdę nie zginęła. Ona... yyy... udała się "
+"do lepszego miejsca."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Twój plan zniszczenia broni wrogów poprzez uderzanie o nią twoim gardłem "
+"zawiódł."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Wydaje mi się, iż to nie poszło zbyt dobrze."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Czy chesz zidentyfikować twoje rzeczy?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Niestety, ślad po tobie zaginął..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Unicestwiony."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Wygląda na to, że podano tobie twoją głowę."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "Znowu nawaliłeś, wrzuć swoje ciało do rur i weź sobie nowe."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Naciśnij OK, aby się odrodzić"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Umarłeś"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Już zalogowany"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Nazwa użytkownika już istnieje"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Statystyki postaci w porządku."
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Statystyki postaci w porządku."
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Nieznany błąd"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Info"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Gracz usunięty"
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Wybierz ilość przedmiotów do handlu."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Nieznany błąd"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Brak dostępnych serwerów gier"
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Temat: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Gracz uderza Potwora"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Komenda: /join <kanał>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Prośba o dołączenie do kanału %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s dołączył do grupy."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Nieznane polecenie."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Gildia została utworzona."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Błąd podczas tworzenia gildii."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Zaproszenie wysłane."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Członek został pomyślnie wypromowany."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Promocja Członka nie powiodła się."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Zły magic_token"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Już zalogowany"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Konto wygasło"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Nowe hasło jest nieprawidłowe"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Stare hasło jest nieprawidłowe"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Konto niepołączone. Proszę najpierw się zalogować."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Nowy adres email jest niepoprawny"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Stary adres email jest niepoprawny"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Nowy Adres Email już istnieje"
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Wersja klienta jest zbyt stara"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Zła nazwa użytkownika lub hasło"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Konto wygasło"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Zła nazwa użytkownika, hasło, lub adres email"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Nazwa użytkownika już istnieje"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Adres email już istnieje"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Dołączono do grupy."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s dołączył do grupy."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s odmówił zaproszenia."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Akceptowanie nadchodzących próśb o handel."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignorowanie nadchodzących próśb o handel."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s chce handlować z tobą, zgadzasz się?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Handel z %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Handel anulowany."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Handel zakończony."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Wykopanie nie powiodło się!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Wykopanie powiodło się!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Nie masz niczego do sprzedania."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Dziękuję za kupno."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Nie można kupić."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Dziękuję za sprzedaż."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Nie można sprzedać."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Nie można uzyć tego ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Nieznany błąd"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+"Utworzenie postaci nie powiodło się. Najprawdopodobniej imię jest już zajęte."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Usunięto postać."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Usunięcie gracza nie powiodło się."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Siła:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Zwinność:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Witalność:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Inteligencja:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Zręczność:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Szczęście:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Szept nie mógł zostać wysłany, użytkownik jest offline."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Szept nie mógł zostać wysłany, jesteś ignorowany przez odbiorcę."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Gracz"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Gracz"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Kanały nie są wspierane!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Nazwa"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Prośba o Handel"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Siła %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Zwinność %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Witalność %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Inteligencja %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Zręczność %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Szczęście %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Uwierzytelnienie nie powiodło się"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Brak dostępnych serwerów"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Ktoś inny próbuje użyć tego konta"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "To konto jest już zalogowane"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Wykryto Speed hack"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Zduplikowany login"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Nieznany błąd połączenia"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Rozłączono z serwerem!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Szczęście"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Obrona:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "Atak M.:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "Obrona M.:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Celność:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Unik:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Uderzenie Krytyczne"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Atak %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Atak %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Potwór uderza Gracza"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Wyświetla tą pomoc"
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Zaproszenie gracza do twojej grupy"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Opuszenie grupy, w której jesteś"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Wykopanie kogoś z grupy, w której jesteś"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Komenda: /invite <ksywka>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Ta komenda zaprasza <ksywka> do twojej grupy."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Komenda: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Komenda powoduje opuszczenie grupy przez gracza"
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Błąd podczas tworzenia gildii."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Nieznana odpowiedź na zaproszenie dla %s"
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Gildia"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Gildia"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Poziom: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Maks. poziom"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Gildia"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Gildia została utworzona."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Gildia została utworzona."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s jest od teraz członkiem twojej grupy."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Nieznana odpowiedź na zaproszenie dla %s"
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Opuściłeś grupę."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s opuścił twoją grupę."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s jest od teraz członkiem twojej grupy."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Zaproszenie gracza do twojej grupy"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Opuszenie grupy, w której jesteś"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Wykopanie kogoś z grupy, w której jesteś"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Pokaż/zmień opcje podziału przedmiotu w grupie"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Pokaż/zmień opcje pozdziału doświadczenia w grupie"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Komenda powoduje opuszczenie grupy przez gracza"
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Komenda: /item <zasada>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Komenda zmienia zasadę pozdziału przedmiotu w grupie"
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<zasada> może być jedną z \"1\", \"yes\", \"true\" aby aktywować pozdział "
+"przedmiotu lub \"0\", \"no\", \"false\" by wyłączyć podział przedmiotu."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Komenda: /przedmiot"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "Komenda pokazuje zasadę pozdziału przedmiotu w grupie."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Komenda: /exp <zadada>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Komenda zmienia zasadę pozdziału doświadczenia w grupie."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<zasada> może być jedną z \"1\", \"yes\", \"true\" aby aktywować pozdział "
+"doświadczenia, lub \"0\", \"no\", \"false\" aby wyłączyć pozdział "
+"doświadczenia."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Komenda: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr "Komenda pokazuje obecną zasadę podziału doświadczenia w grupie."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Podział przedmiotu włączony."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Podział przedmiotu wyłączony."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Podział przedmiotu nie jest możliwy."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Podział przedmiotu włączony."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Podział doświadczenia włączony."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Podział doświadczenia wyłączony."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Podział doświadczenia nie jest możliwy."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Podział doświadczenia włączony."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Użycie przedmiotu nie powiodło się."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Nie można założyć."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Nie znaleziono Konta. Proszę zalogować się ponownie."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Nowe hasło jest za krótkie"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Niezarejestrowany ID"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Nieprawidłowe hasło"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Konto wygasło"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Odrzucony z serwera"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "Zostałeś tymczasowo zbanowany. Proszę skontaktować się z zespołem GM."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Zostałeś tymczasowo zbanowany z gry do dnia %s.\n"
+"Proszę skontaktować się z zespołem GM poprzez forum."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Ta nazwa użytkownika jest już zajęta"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Nie można sprzedać."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Łączenie z serwerem map..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Nie można utworzyć grupy."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Pomyślnie utworzono grupę."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s już jest członkiem grupy."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s odmówił zaproszenia."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s jest od teraz członkiem twojej grupy."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Nieznana odpowiedź na zaproszenie dla %s"
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Opuściłeś grupę."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s opuścił twoją grupę."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Nieznany członek próbował powiedzieć: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s nie jest w twojej grupie!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Wrzuć monetę aby kontynuować."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Jeszcze nie umarłeś. Po prostu odpoczywasz."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Więcej ciebie nie ma."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Przestałeś istnieć."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Odszedłeś na spotkanie ze swoim stwórcą."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Jesteś sztywniakiem."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Opuściło cię życie. Teraz spoczywasz w spokoju."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "Gdybyś nie był taki aktywny, nadal byś zrywał kwiatki."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Twoje procesy metaboliczne są teraz historią."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Kopnąłeś w kalendarz."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Jesteś ex-graczem."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Usychasz z tęsknoty za fiordami."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Wiadomość"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "Nosisz więcej, niż połowa twojej wagi. Nie możesz odzyskiwać zdrowia."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr "Nosisz więcej, niż połowa twojej wagi. Nie możesz odzyskiwać zdrowia."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Podniosłeś "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Otrzymujesz %s"
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Najpierw załóż strzały."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Handel zakończony niepowodzeniem!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Emotka nieudana!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Siad nieudany!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Utworzenie czatu nieudane!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Nie można dołączyć do grupy!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Nie można krzyknąć!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Masz za niski poziom!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Niewystarczające HP!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Niewystarczające SP!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Nie masz notatek!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Nie możesz teraz tego zrobić!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Wygląda na to, że potrzebujesz wiecej pieniędzy... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Nie można użyć tej umiejętności z taką bronią!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Potrzebujesz innego czerwonego kamienia!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Potrzebujesz innego niebieskiego kamienia!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Jesteś zbyt obciążony aby to zrobić!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "O! Co to?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Nie mogę nic ukraść..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Trucizna nie zadziałała..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Handlowanie nie jest możlwe. Kontrahent jest za daleko."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Handlowanie nie jest możliwe. Postać nie istnieje."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Handel anulowany z nieznanego powodu."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Handel: Ty i %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Handel z %s został anulowany."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Nieobsługiwany pakiet anulowania handlu."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Dodanie przedmiotu nie powiodło się. Kontrahent jest przeciążony."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+"Dodanie przedmiotu nie powiodło się. Kontrahent nie posiada wolnego miejsca."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Dodanie przedmiotu nie powiodło się z nieznanego powodu."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Kompletnie ignoruj %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Atak %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Obrona %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Nieznany przedmiot"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "nienazwany"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Detale cząsteczek"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Efekty otoczenia"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Skrót Emotki %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Gracz uderza Potwora"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Temat: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Imię: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "MiniMapa"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Rozpocznij zapisywanie czatu do zewnętrznego pliku"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Komenda: /record <nazwa_pliku>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Ta komenda rozpoczyna zapisywanie dziennika czatu to pliku <nazwa_pliku."
+
+#~ msgid "Command: /record"
+#~ msgstr "Komenda: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Ta komenda kończy zapisywanie sesji"
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Dozór wpisany do dziennika zapisu"
+
+#~ msgid "Finishing recording."
+#~ msgstr "Zakończono zapisywanie."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Obecnie nie zapisuje."
+
+#~ msgid "Already recording."
+#~ msgstr "Już zapisuje."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Rozpoczęcie zapisywania..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Rozpoczęcie zapisywania nie powiodło się."
+
+#~ msgid "Recording..."
+#~ msgstr "Zapisywanie..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Zatrzymaj zapisywanie"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Znajdź Ścieżkę do Myszy"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Pieniądze: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Praca:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Poziom: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Pomyślnie utworzono grupę."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Szept nie mógł zostać wysłany, jesteś ignorowany przez odbiorcę."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Plik konfiguracyjny do użycia"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Plik konfiguracyjny do użycia"
+
+#~ msgid "Sound"
+#~ msgstr "Dźwięk"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Dostęp zabroniony"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Nieznany błąd podczas wyboru postaci"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Zapraszanie w ten sposób nie jest obecnie wspierane."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s zaprosił ciebie, byś dołączył do grupy."
+
+#~ msgid "Willpower:"
+#~ msgstr "Siła woli:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Serwer jest pełny"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Handel z %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Szept"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Zaprzyjaźnij się z %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Nielubiany"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Kompletnie ignoruj %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Zaproś %s aby dołączył do twojej gildii@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Zaproś %s do grupy@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Wykopanie nie powiodło się!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Rozmawiaj z %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Wykop potwora@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Podnieś"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Nie można wysłać pustego czatu!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Nie można zdjąć."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Cień tekstu"
+
+#~ msgid "Text Outline"
+#~ msgstr "Kontur Tekstu"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Etykiety Pasków Postępu"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Przedmiot zbyt drogi"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Przedmiot jest założony"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Gracz"
+
+#~ msgid "Whisper"
+#~ msgstr "Szept"
+
+#~ msgid "Is"
+#~ msgstr "Jest"
+
+#~ msgid "Server"
+#~ msgstr "Serwer"
+
+#~ msgid "Logger"
+#~ msgstr "Logger"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Nieznany Typ Przedmiotu"
+
+#~ msgid "Generics"
+#~ msgstr "Ogólne"
+
+#~ msgid "Hats"
+#~ msgstr "Kapelusze"
+
+#~ msgid "Usables"
+#~ msgstr "Użytkowe"
+
+#~ msgid "Shirts"
+#~ msgstr "Koszulki"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Bronie jednoręczne"
+
+#~ msgid "Pants"
+#~ msgstr "Spodnie"
+
+#~ msgid "Shoes"
+#~ msgstr "Buty"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Bronie jednoręczne"
+
+#~ msgid "Shields"
+#~ msgstr "Tarcze"
+
+#~ msgid "Rings"
+#~ msgstr "Pierścienie"
+
+#~ msgid "Necklaces"
+#~ msgstr "Naszyjniki"
+
+#~ msgid "Arms"
+#~ msgstr "Naramienniki"
+
+#~ msgid "Ammo"
+#~ msgstr "Amunicja"
+
+#~ msgid "HP Bar"
+#~ msgstr "Pasek HP"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 Paska HP"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 Paska HP"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 Paska HP"
+
+#~ msgid "no"
+#~ msgstr "nie"
+
+#~ msgid "Buddy"
+#~ msgstr "Znajomy"
+
+#~ msgid "Buddy List"
+#~ msgstr "Lista znajomych"
+
+#~ msgid "Description: %s"
+#~ msgstr "Opis: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Efekt: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Poprzednia"
+
+#~ msgid "New"
+#~ msgstr "Nowa"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Poziom Pracy: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Obecny: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Opuść Gildię"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Recent:"
+#~ msgstr "Ostatni:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Test Rzucania Zaklęcia 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Test Rzucania Zaklęcia 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Test Rzucania Zaklęcia 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Bronie dwuręczne"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Zdejmij@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Załóż@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Upuść@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Rozdziel@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Zachowaj@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Wybierz serwer"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Nie udało się przełączyć na "
+
+#~ msgid "windowed"
+#~ msgstr "w oknie"
+
+#~ msgid "fullscreen"
+#~ msgstr "pełny ekran"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Tajemnicza umiejętność"
+
+#~ msgid "Weapons"
+#~ msgstr "Bronie"
+
+#~ msgid "Crafts"
+#~ msgstr "Rzemiosła"
+
+#~ msgid "Stats"
+#~ msgstr "Statystyki"
+
+#~ msgid "Total"
+#~ msgstr "Razem"
+
+#~ msgid "Cost"
+#~ msgstr "Koszt"
+
+#~ msgid "Attack:"
+#~ msgstr "Atak:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Refleks:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Pozostało Punktów Statusu: %d"
+
+#~ msgid "curl error "
+#~ msgstr "błąd curl "
+
+#~ msgid " host: "
+#~ msgstr " host: "
+
+#~ msgid "Buddys"
+#~ msgstr "Znajomi"
+
+#~ msgid "Party Window"
+#~ msgstr "Okno Grupy"
+
+#~ msgid "Unarmed"
+#~ msgstr "Nieuzbrojony"
+
+#~ msgid "Knife"
+#~ msgstr "Nóż"
+
+#~ msgid "Sword"
+#~ msgstr "Miecz"
+
+#~ msgid "Staff"
+#~ msgstr "Laska"
+
+#~ msgid "Whip"
+#~ msgstr "Bat"
+
+#~ msgid "Bow"
+#~ msgstr "Łuk"
+
+#~ msgid "Shooting"
+#~ msgstr "Strzelectwo"
+
+#~ msgid "Mace"
+#~ msgstr "Maczuga"
+
+#~ msgid "Axe"
+#~ msgstr "Topór"
+
+#~ msgid "Craft"
+#~ msgstr "Rrzemiosło"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Nieznana Umiejętność"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " nie może być utworzony, ale nie istnieje! Kończenie."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Nie można ustawić "
+
+#~ msgid " video mode: "
+#~ msgstr " tryb wideo: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Łączenie z serwerem postaci..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Łączenie z serwerem kont..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Alias create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Komenda: /new <nazwa-grupy>"
+
+#~ msgid "Unnamed"
+#~ msgstr "Nienazwany"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Podnieś %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Skok przy przewijaniu ekranu"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Opóźnienie przy przewijaniu ekranu"
+
+#~ msgid "Unable to load selection.png"
+#~ msgstr "Nie można załadować selection.png"
+
+#~ msgid "Emote"
+#~ msgstr "Emoty"
+
+#~ msgid "NPC Text Request"
+#~ msgstr "Tekst NPC - Prośba"
+
+#~ msgid "NPC Number Request"
+#~ msgstr "Prośba NPC Numer"
+
+#~ msgid ""
+#~ "\n"
+#~ "> Cancel\n"
+#~ msgstr ""
+#~ "\n"
+#~ "> Anuluj\n"
+
+#~ msgid "skills.xml"
+#~ msgstr "skills.xml"
+
+#~ msgid "inc"
+#~ msgstr "podw."
+
+#~ msgid "use"
+#~ msgstr "użyj"
+
+#~ msgid "%s: %s"
+#~ msgstr "%s: %s"
+
+#~ msgid " cancelled"
+#~ msgstr " anulował"
+
+#~ msgid "monsters.xml"
+#~ msgstr "monsters.xml"
+
+#~ msgid "items.xml"
+#~ msgstr "items.xml"
+
+#~ msgid " -D --default : Bypass the login process with default settings"
+#~ msgstr ""
+#~ " -D --default : Pomiń proces logowania z domyślnymi ustawieniami"
+
+#~ msgid "Slots: "
+#~ msgstr "Miejsc: "
diff --git a/po/pt.po b/po/pt.po
new file mode 100644
index 000000000..77a9cccb6
--- /dev/null
+++ b/po/pt.po
@@ -0,0 +1,5689 @@
+# Portuguese translation for mana
+# Copyright (c) 2007 Rosetta Contributors and Canonical Ltd 2007
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-03-05 13:28+0000\n"
+"Last-Translator: Tustiman <Unknown>\n"
+"Language-Team: Portuguese <pt@li.org>\n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Configuração"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Conectando ao servidor de mapas..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Autenticar"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Seleccione um Personagem"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Conectando ao servidor de mapas..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Servidor"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Erro"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Senha:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Modificar"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Membro foi promovido com sucesso."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Remover o Registo"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Host de atualização inválido: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Erro ao criar pasta de actualizações!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Comando desconhecido"
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Ajuda --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Mostra a ajuda"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Mostra o nome do mapa"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Mostra o numero de utilizadores online"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Diga alguma coisa sobre si"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Limpa a janela"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Envia uma mensagem privata a um utilizador"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > nome do jogador"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > nome do jogador"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Cria um separador para mensagens privadas com outro utlizador"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > nome da pesquisa"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Fecha a aba de sussurros"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Desconsiderar %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Mostra todos os canais públicos"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Junte-se ou crie um canal"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Cria um novo grupo"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Cria um novo grupo"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > convidar um jogadora para a equipa"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Determina se <enter> alterna para o log de chat"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Obter lista de jogadores presentes (Envia para o log do chat. Se "
+"logando)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Anuciamento Global (Somente GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Fecha a aba de sussurros"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Envia uma mensagem privata a um utilizador"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Para mais informações, escreva /help <command>."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Comando: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Este comando mostra a lista de todos os comandos disponiveis"
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Comando: /help <command>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Exibe o conteúdo de ajuda de <command>"
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Comando: /announce <msg>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** apenas para GM's ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Enviar mensagem <msg> para todos os jogadores conectados."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Comando /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Limpa os logs do chat anterior."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Comando> /item <opção>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Mostra o número de jogadores conectados."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Comando: /join <canal>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Este comando faz você entrar em <canal>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Se o <canal> não existe, ele será criado."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Comando /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Mostrar uma lista de todos os canais."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Comando /me <messagem>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Este comando diz aos outros o que eu estou (fazendo) <msg>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Comando: /msg <nick> <mensagem>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Comando: /whisper <nick> <mensagem>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Comando: /w <nick> <mensagem>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Enviar <mensagem> para <nick>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Se <nick> possuir espaços, coloque dentro de parênteses (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Comando: /query <nick>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Comando: /q <nick>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Este comando cria uma aba para mensagens confidenciais entre você e <nick>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Comando: /w <nick> <mensagem>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Define <mensagem> como o tópico."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Comando: /create <nome-do-grupo>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Estes comandos criam um novo grupo chamado <nome-do-grupo>."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Comando: /create <nome-do-grupo>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Estes comandos criam um novo grupo chamado <nome-do-grupo>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Comando: /party <nick>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Convida <nick> para uma festa com você."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Comando: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Este comando obtém uma lista dos Jogadores ao alcance e a envia para o log "
+"de registo do chat ou, caso haja uma gravação em andamento, para o log de "
+"gravação."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Comando: /toggle <estado>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Este comando define se a tecla enter deve alternar para o log do chat ou se "
+"o log do chat fica oculto automaticamente."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<estado> pode ser \"1\", \"yes\" e \"true\" para ativar ou \"0\", \"no\" e "
+"\"false\" para desactivar."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Comando: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Este comando mostra o status do botão alternar."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Comando> /item <opção>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Comando: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Mostra o nome do mapa atual."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Mostra o número de jogadores conectados."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Digite /help para ver uma lista de comandos."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Não é possível criar uma aba de sussurros para o nick \"%s\"! Ou ela já "
+"existe ou é você mesmo."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Solicitando entrada no canal %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Falta o nome do grupo."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Falta o nome do grupo."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Enter alterna para o chat."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "A mensagem fecha o chat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Agora enter alterna para o chat."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Agora a mensagem fecha o chat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Amigo"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Desconsiderado"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutro"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Impossível enviar sussurro, está ignorado pelo utilizador."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Grupo criado."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Impossível enviar sussurro, está ignorado pelo utilizador."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Impossível enviar sussurro, está ignorado pelo utilizador."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Impossível enviar sussurro, está ignorado pelo utilizador."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Grupo criado."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Impossível enviar sussurro, está ignorado pelo utilizador."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Opções para /%s são \"yes\" e \"no\", \"true\" e \"false\", \"1\" e \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Geral"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Screenshot salvo em ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Erro ao salvar screenshot!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Conexão com o servidor perdida, o jogo será fechado"
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Erro de conexão"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignorando propostas de negócios"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Aceitando propostas de negócios"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Impossível carregar mapa"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Erro ao carregar %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Grupo (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Guildas"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Janela de Diálogo"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Nome"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Ataque"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Falar"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Mover para Cima"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Reiniciar"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Comprar"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Preço: %s / Total: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Sair"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Máximo"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Loja"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Vender"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Alterar e-mail"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Conta: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Digite o novo endereço de email duas vezes:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "O nome de utilizador necessita de pelo menos %d caracteres."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "O nome de utilizador só pode ter %d caracteres."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "O novo endereço de email já existe."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Alterar Senha"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Senha:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Digite a nova senha duas vezes:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "A password necessita de pelo menos %d caracteres."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "A password só pode ter até %d caracteres."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Criar Personagem"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Nome:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Cor de Cabelo:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Estilo do Cabelo:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Criar"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Masculino"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Feminino"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Por favor distribua %d potos"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "O seu nome necessita de pelo menos 4 caracteres"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Estatisticas da personagem OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Por favor remova %d pontos"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Confime a remoção da personagem"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Tem a certeza que quer apagar este personagem"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Gestão da Conta e Personagem"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Remover o Registo"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Alterar e-mail"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Eliminar"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Fechar"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Padrão"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Amigo"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Verde: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Azul: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "baixo"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Hiperligação"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Arremesso"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Arco-Íris"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Arco-Íris"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Arco-Íris"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chat"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d jogadores estão presentes."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "A sussurrar para %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Sim"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Não"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignorado"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Tópico: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Nome: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "MiniMapa"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Efeitos de partícula"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Estatisticas da personagem OK"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Mover para Esquerda"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Seleccionar Jogador"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Seleccionar Jogador"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Seleccionar Jogador"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Seleccionar Jogador"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Cursor personalizado"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Equipamento"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Desequipar"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Ajuda"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Fechar"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventário"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Armazenamento"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Entradas:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Equipar"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Usar"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Largar"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Dividir"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Peso:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Guardar"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Recuperar"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Largar"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Tudo"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Seleccionar a quantidade de itens a negociar."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Seleccionar a quantidade de itens a largar."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Escolha a quantidade de itens para guardar."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Escolha a quantidade de itens para retirar."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Seleccionar a quantidade de itens a dividir."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Erro desconhecido"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Peso: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Status"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Reiniciar"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Reiniciar"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Nível: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Mover para Esquerda"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Fechar"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Autenticar"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Servidor:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Lembras nome de usuário"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registo"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Servidor"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Mapa"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Aguardando servidor"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Seguinte"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Enviar"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Lança"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Seguinte"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Para:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Enviar"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Falha ao enviar como remetente ou a carta é inválida."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Dinheiro: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Desequipar"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Negociar com %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Atacar %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Cancelar@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Retirar@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Desconsiderar %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignorar %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Deixar de ignorar %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Ignorar completamente %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > convidar um jogadora para a equipa"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > convidar um jogadora para a equipa"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Deixar de ignorar %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Atacar %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Adiciona nome ao chat@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Cancelar@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Pegar %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Adicionar ao chat@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Realçar aba"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Realçar aba"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Modificar"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Guardar"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Guardar"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Guardar"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Recuperar"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Recuperar"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Recuperar"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Adicionar ao chat@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Mudar de servidor"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Mudar de personagem"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Confirmar:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "O nome de utilizador necessita de pelo menos %d caracteres."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "O nome de utilizador só pode ter %d caracteres."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "A password necessita de pelo menos %d caracteres."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "A password só pode ter até %d caracteres."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "As senhas não coincidem."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Selecione seu servidor"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Porta:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Servidor:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Conectando..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Cursor personalizado"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Por favor escreva o endereço e a porta do servidor."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Aguardando servidor"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Habilitar Joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Habilitar Joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Áudio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Volume dos Efeitos"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Volume da Música"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Sem texto"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "A cor se parece com isso"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Cores"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Tipo: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Estática"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulsar"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Arco-Íris"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Espectro"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Atraso: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Vermelho: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Verde: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Azul: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Aplicar"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Reiniciar Janelas"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Pressione o botão para começar a calibragem"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Calibrar"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Habilitar Joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Parar"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Rode o manipulo"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "teclado"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Associar"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Associar"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Padrão"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Conflitos nas teclas detectado."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Realçar"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Habilitar Joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Realçar"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Habilitar/Desabilitar Negociações"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Habilitar Joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "como partícula"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relação"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutro"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Amigo"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Desconsiderado"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignorado"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Permitir trocas"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Permitir sussurros"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Deixar todos os sussurros em abas"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Jogadores"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Quando ignorado:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Seleccionar Jogador"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Efeitos de partícula"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Ajuda"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Modificar"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Reincie o jogo para que as mudanças surtam efeito."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Minúscula"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Pequeno"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Médio"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Grande"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Sem texto"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "texto"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Bolhas, sem nomes"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Bolhas com nomes"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "desligado"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "baixo"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "elevado"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "médio"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "máximo"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Ecrã completo"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relação"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Cursor personalizado"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Nomes visíveis"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Efeitos de partícula"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Mostrar aviso de achado"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "no chat"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "como partícula"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Habilitar Joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Plano de fundo"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Limite de FPS:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "Limite de FPS:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Vídeo"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Texto sobrescrito"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Opacidade do Interface"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Efeitos Ambientais"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Detalhe de partículas"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Tamanho da fonte"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Não"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "modo e restauração do antigo modo também falharam!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "modo e restauração do antigo modo também falharam!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Mudar para ecrã completo"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "É necessário reiniciar para as alterações terem efeito."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Mudando OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "É necessário reiniciar para as alterações ao OpenGl terem efeito."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Resolução de tela alterada"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Configurações de efeito de partícula modificadas."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "As mudanças terão efeito na mudança do mapa."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Adicionar"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Proposta de negociação"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s quer negociar com você, você aceita?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Competências"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Para cima"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Pontos de habilidade: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Pontos de habilidade: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Competências"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Nível: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Nível: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Guilda"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Guilda criada."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Criar Guilda"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Você tem certeza que deseja sair?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Festa"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > convidar um jogadora para a equipa"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > convidar um jogadora para a equipa"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Você tem certeza que deseja sair?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Criar Guilda"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Criar Personagem"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Convidar Usuário"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Grande"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Acaitar convite de %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Rejeitar convite de %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Acaitar convite de %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Rejeitar convite de %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Erro ao criar guilda."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Guilda"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Selecione seu servidor"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Requisição de grupo recebida, mas já existe um."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s te convidou para entrar no grupo %s."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Aceitar convite para o grupo"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Requisição de grupo recebida, mas já existe um."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s te convidou para entrar no seu grupo."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s te convidou para entrar no grupo %s."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s te convidou para entrar no seu grupo."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s te convidou para entrar no grupo %s."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Aceitar convite para o grupo"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Festa"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Selecione seu servidor"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Nível: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Dinheiro: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Trabalho: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Trabalho:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Estatisticas da personagem OK"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Nível: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Pontos de habilidade: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Mover para Esquerda"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Permitir trocas"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Mover para Esquerda"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Geral"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Mágica"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Mágica"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Comando: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Mágica"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Comando: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Seleccionar Jogador"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Nível máximo"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Mostrar nome"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Propor Negócio"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Confirmado. Aguardando..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Aceitar negociação"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Aceita. Aguarde..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Negócio: você"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Negócio"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Você obteve %s"
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Dá:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Modificar"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Falha ao adicionar item. Você não pode duplicar um tipo de item na janela."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Você não tem dinheiro suficiente."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nome: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Atualizando..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Conectando..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Iniciar"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 O processo de update está incompleto."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 É altamente recomendado que"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 você tente novamente mais tarde"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Concluído"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Ser"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Amigo"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Desconsiderado"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignorado"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "Nomes dos GMs"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Nomes de outros jogadores"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Nome Próprio"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Nomes dos GMs"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monstros"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monstro acerta jogador"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Festa"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Guilda"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Efeitos de partícula"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Aviso de achado"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Aviso de experiência"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Monstro acerta jogador"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Nomes de outros jogadores"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Golpe crítico"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr ""
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Falhas"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Realçar aba"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Realçar"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Realçar aba"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monstro acerta jogador"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Lista os utilizadores deste canal"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Definir o tópico deste canal"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Sair do canal"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Fazer um utilizador em operador do canal"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Expulsa um utilizador do canal"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Comando: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Mostrar usuários do canal."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Comando: /topic <mensagem>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Define <mensagem> como o tópico."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Comando: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Sair do canal."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Se você for a última pessoa no canal, ele será apagado."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Comando: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Tornar <nick> operador do canal."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Operadores de canal podem expulsar e dar op a outros utilizadores do canal."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Comando: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Retirar <nick> do canal."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "É preciso um utilizador para dar op!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "É preciso um utilizador para expulsar!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Anúncio geral:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Anúncio geral de %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s sussurou: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Fecha a aba de sussurros"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Comando: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Este comando fecha a atual aba de sussurros"
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Comando: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Mostra o número de jogadores conectados."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Este comando inicia a gravação do registo do chat para o ficheiro "
+"<nome_do_ficheiro>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Janela de Diálogo"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Emoticons"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Estado"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Atalho"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Seleccionar OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Modificar"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Selecione seu servidor"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Mover para Cima"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Mover para Baixo"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Mover para Esquerda"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Mover para Direita"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Selecionar & Atacar"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Mover para Esquerda"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Emoticons"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Parar ataque"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Seleccionar o mais próximo"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Seleccionar NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Seleccionar Jogador"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Pegar"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Esconder Janelas"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Sentar"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Captura de Ecrã"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Habilitar/Desabilitar Negociações"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Alterar e-mail"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Atalho para Item %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Atalho para Item %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Ajuda"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Status"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Janela de inventário"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Equipamento"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Janela de Habilidade"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Janela de Mini-mapa"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Janela de Diálogo"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Janela de atalhos para itens"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Configuração"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Janela de Depuração"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Janela de Habilidade"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Janela de atalho para Emoticons"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Status"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Configuração"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Esconder Janelas"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Status"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Comando: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Janela de Diálogo"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Aba de chat anterior"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Próxima aba de chat"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Atalho para Emoticon %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Alternar para chat"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Rolar janela de chat para cima"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Rolar janela de chat para baixo"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Aba de chat anterior"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Próxima aba de chat"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Aba de chat anterior"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Próxima aba de chat"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Seleccionar OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignorar input 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignorar input 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Mover para Baixo"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Mover para Esquerda"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Mover para Direita"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Mudar de personagem"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Servidor"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Selecionar & Atacar"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Alterar Senha"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Alterar e-mail"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Habilitar/Desabilitar Negociações"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Corrija-os, ou o jogo irá se comportar de forma estranha."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Impossível pegar item."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Você pegou %s [@@%d|%s@@]."
+msgstr[1] "Você pegou %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Você obteve %s"
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opções:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Ficheiro de configuração a ser usado"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Ficheiro de configuração a ser usado"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Exibe a versão"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Exibe esta ajuda"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Ficheiro de configuração a ser usado"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Efectua login com este utilizador"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Efectua login com esta senha"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Efectua login com este personagem"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Nome ou IP do servidor de login"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Porta do servidor de login"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Usa esta actualização do host"
+
+#: src/main.cpp:61
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Não faz downloads de actualização"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Pasta de onde os dados do jogo vão ser carregados"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Directório a ser usado como pasta inicial"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Directório a ser usado como pasta inicial"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Desabilita OpenGL nesta sessão"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Força"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Força %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Agilidade"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Agilidade %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Destreza"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Destreza %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Vitalidade"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Vitalidade %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Inteligência"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Inteligência %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Força de Vontade:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Força de vontade %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Você está morto."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "Lamentamos informar que seu personagem foi morto em combate."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Você não está mais vivo."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "As mãos frias da morte estão levando sua alma."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Fim de jogo!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Não, crianças. Seu personagem não morreu de verdade. Ele... err... foi para "
+"um lugar melhor."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Seu plano de quebrar as armas de seus inimigos com o seu pescoço não deu "
+"certo."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Eu acho que isso não correu lá muito bem."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Você quer uma identificação de suas posses?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Infelizmente, seus vestigios nunca foram encontrados..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Aniquilado."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Parece que te ofereceram sua própria cabeça."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "Você estragou tudo de novo, jogue fora seu corpo e arranje outro."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Clique em OK para re-popular."
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Você morreu"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Já está conectado"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Nome de utilizador já existe"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Estatisticas da personagem OK"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Estatisticas da personagem OK"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Erro desconhecido"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Info"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Personagem apagado."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Seleccionar a quantidade de itens a negociar."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Erro desconhecido"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Não há gameservers disponíveis."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Tópico: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Jogador acerta monstro"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Comando: /join <canal>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Solicitando entrada no canal %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s entrou para o grupo."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Comando desconhecido"
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Guilda criada."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Erro ao criar guilda."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Convite enviado."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Membro foi promovido com sucesso."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Erro ao promover membro."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Simbolo-mágico errado."
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Já está conectado"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "A conta expirou"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Nova senha incorreta"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Senha antiga incorreta"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Conta não conectada. Por favor, efectue o login primeiro."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Novo endereço de email incorrecto"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Antigo endereço de email incorrecto"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "O novo endereço de email já existe."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Versão do cliente é muito antiga"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Nome de utilizador ou senha inválida"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "A conta expirou"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Nome de utilizador, senha ou email inválido"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Nome de utilizador já existe"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Endereço de email já existe"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Entrou para o grupo."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s entrou para o grupo."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s recusou seu convite."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Aceitando propostas de negócios."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignorando propostas de negócios."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s quer negociar com você, você aceita?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Negociando com %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Negociação cancelada."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Negociação realizada."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Erro na expulsão!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Expulsão bem sucedida!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Nada para vender."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Obrigado pela compra."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Impossível comprar."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Obrigado pela venda."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Impossibilitado de vender."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Não é possível usar esta ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Erro desconhecido"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Erro ao criar personagem. Provavelmente o nome já está sendo usado."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Personagem apagado."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Falha ao apagar personagem."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Força:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agilidade:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitalidade:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Inteligência:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Destreza:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Sorte:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Impossível enviar sussurro, o utilizador está desconectado."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Impossível enviar sussurro, está ignorado pelo utilizador."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Jogador"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Jogador"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Não há suporte para canais!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Nome"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Proposta de negociação"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Força %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Agilidade %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Vitalidade %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Inteligência %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Destreza %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Sorte %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Autenticação falhou"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Não há servidores disponíveis"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Mais alguém está tentando utilizar esta conta"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Existe alguém logado a esta conta"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Hack de velocidade detectado"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Login duplicado"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Erro de conexão desconhecido"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Você foi desconectado do servidor!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Sorte"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Defesa:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "M. Ataque:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "M. Defesa:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Precisão:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Fuga:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Golpe crítico"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Ataque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Ataque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monstro acerta jogador"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Exibe esta ajuda."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Convida um jogador para o seu grupo"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Sai do grupo em que você está"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Expulsa alguém do grupo em que você está"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Comando: /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Convida <nick> para uma festa com você."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Comando: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Este comando faz com que o jogador saia do grupo."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Erro ao criar guilda."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Resposta de convite desconhecida para %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Guilda"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Guilda"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Nível: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Nível máximo"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Guilda"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Guilda criada."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Guilda criada."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s agora é um membro do seu grupo."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Resposta de convite desconhecida para %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Você saiu do grupo."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s saiu do seu grupo."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s agora é um membro do seu grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Convida um jogador para o seu grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Sai do grupo em que você está"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Expulsa alguém do grupo em que você está"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Mostra/Muda opções de partilha de itens do grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Mostra/Modifica opções de partilha de experiência do grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Este comando faz com que o jogador saia do grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Comando> /item <opção>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Este comando muda a opção de partilha de itens no grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<policy> pode ser \"1\", \"yes\" e \"true\" para habilitar partilhar de "
+"itens, ou \"0\", \"no\" e \"false\" para desabilitar."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Comando: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "Este comando exibe a actual opção de partilha de itens no grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Comando: /exp <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Este comando muda a opção de partilha de experiência no grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<policy> pode ser \"1\", \"yes\" e \"true\" para habilitar partilha de "
+"experiência, ou \"0\", \"no\" e \"false\" para desabilitar."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Comando: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr "Este comando exibe a actual opção de partilha de experiência no grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Partilha de itens habilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Partilha de itens desabilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Não é possível partilhar itens."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Partilha de itens habilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Partilha de experiência habilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Partilha de experiência desabilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Não é possível partilhar experiência."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Partilha de experiência habilitado."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Problemas ao usar item."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Impossível equipar."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Conta não encontrada. Por favor, log novamente."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Nova senha é muito curta"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "ID não registado"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Senha incorreta"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "A conta expirou"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Rejeitado pelo servidor"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Você foi permanentemente banido do jogo. Por favor entre em contacto com "
+"algum GM."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Você banido temporariamente do jogo até %s.\n"
+"Por favor entre em contacto com algum GM através dos fóruns."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Este nome de utilizador já está em uso"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Impossibilitado de vender."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Conectando ao servidor de mapas..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Não foi possível criar o grupo."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Grupo criado."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s já é membro de um grupo."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s recusou seu convite."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s agora é um membro do seu grupo."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Resposta de convite desconhecida para %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Você saiu do grupo."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s saiu do seu grupo."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Um membro desconhecido tentou dizer: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s não está em seu grupo!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Insira uma moeda para continuar."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Você não morreu ainda. Está apenas descansando."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Você não é mais."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Você deixou de ser."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Você expirou e foi encontrar o seu criador."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Você é um cadáver."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Sem vida, descanse em paz."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "Se não fosse tão animado, estaria comendo grama pela raiz."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Seus processos metabólicos são história agora."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Você bateu as botas."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Você chutou o balde."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+"Você dispensou seu corpo mortal, abaixou as cortinas e juntou-se ao maldito "
+"coro invisível."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Você é um ex-jogador"
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Você foi desta para melhor."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Mensagem"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Você está carregando mais que a metade de seu peso. Você não poderá mais "
+"recuperar HP."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Você está carregando mais que a metade de seu peso. Você não poderá mais "
+"recuperar HP."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Você pegou "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Você obteve %s"
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Equipe as flechas primeiro."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Falha na negociação!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Falha no Emote!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Falha ao sentar!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Falha ao criar Chat!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Impossível entrar no grupo!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Impossível gritar!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Você ainda não tem nível necessário!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "HP insuficiente!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "SP insuficiente!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Você não tem nenhuma nota armazenada!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Você não pode fazer isso agora!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Parece que você precisa de mais dinheiro... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Você não pode usar essa habilidade com esse tipo de arma!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Você precisa de outra gema vermelha!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Você precisa de outra gema azul!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Você está com muita carga para fazer isso!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Hã? O que é isso?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Falha ao transportar..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Não foi possível roubar nada..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Veneno não surtiu efeito..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Negociação impossível. O parceiro de negócios está muito longe."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Negociação impossível. O personagem não existe."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Negociação cancelada devido a uma razão desconhecida."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Negociação: Você e %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Negociação com %s cancelada."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Troca injusta pacote cancelado."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Erro ao adicionar item. Parceiro de negócios carregando muito peso."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "Erro ao adicionar item. Parceiro de negócios não tem slots livres."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Erro ao adicionar item devido a um motivo desconhecido."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Ignorar completamente %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Ataque %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Defesa %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Item desconhecido"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "sem nome"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Detalhe de partículas"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Efeitos Ambientais"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Atalho para Emoticon %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Jogador acerta monstro"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Tópico: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Nome: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "MiniMapa"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Inicie a gravação da conversa para um ficheiro externo"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Comando: /record <arquivo>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Este comando inicia a gravação do registo do chat para o ficheiro "
+#~ "<nome_do_ficheiro>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Comando: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Este comando finaliza a sessão de gravação."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Presença gravada no registo do log."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Finalizando gravação."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Não há gravação neste momento."
+
+#~ msgid "Already recording."
+#~ msgstr "Já está gravando."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Iniciando a gravação..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Falha ao iniciar gravação."
+
+#~ msgid "Recording..."
+#~ msgstr "Gravando..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Parar gravação"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Dinheiro: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Trabalho:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Nível: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Grupo criado."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Impossível enviar sussurro, está ignorado pelo utilizador."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Ficheiro de configuração a ser usado"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Ficheiro de configuração a ser usado"
+
+#~ msgid "Sound"
+#~ msgstr "Som"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Acesso negado"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Erro desconhecido ao seleccionar personagem"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "No momento ainda não é possível convidar deste modo."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s te convidou para entrar no seu grupo."
+
+#~ msgid "Willpower:"
+#~ msgstr "Força de Vontade:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Servidor cheio"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Negociando com %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Sussurrar"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Ser amigo de %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Desconsiderado"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Ignorar completamente %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Convidar %s para sua Guilda@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Convidar %s para entrar no seu grupo@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Erro na expulsão!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Falar com %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Expulsar monstro@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Pegar"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Não é possível enviar chat vazio!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Impossível desequipar."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Sombra do Texto"
+
+#~ msgid "Text Outline"
+#~ msgstr "Borda do texto"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Rótulos da barra de progresso"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Item muito caro"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Item está equipado"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Jogador"
+
+#~ msgid "Whisper"
+#~ msgstr "Sussurrar"
+
+#~ msgid "Is"
+#~ msgstr "É"
+
+#~ msgid "Server"
+#~ msgstr "Servidor"
+
+#~ msgid "Logger"
+#~ msgstr "Histórico"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Tipo de item desconhecido"
+
+#~ msgid "Generics"
+#~ msgstr "Genéricos"
+
+#~ msgid "Hats"
+#~ msgstr "Chapéus"
+
+#~ msgid "Usables"
+#~ msgstr "Usáveis"
+
+#~ msgid "Shirts"
+#~ msgstr "Camisas"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Armas para 1 mão"
+
+#~ msgid "Pants"
+#~ msgstr "Calças"
+
+#~ msgid "Shoes"
+#~ msgstr "Sapatos"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Armas para 1 mão"
+
+#~ msgid "Shields"
+#~ msgstr "Escudos"
+
+#~ msgid "Rings"
+#~ msgstr "Anéis"
+
+#~ msgid "Necklaces"
+#~ msgstr "Colares"
+
+#~ msgid "Arms"
+#~ msgstr "Braços"
+
+#~ msgid "Ammo"
+#~ msgstr "Munição"
+
+#~ msgid "HP Bar"
+#~ msgstr "Barra de HP"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 da barra de HP"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 da barra de HP"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 da barra de HP"
+
+#~ msgid "no"
+#~ msgstr "não"
+
+#~ msgid "Buddy"
+#~ msgstr "Contacto"
+
+#~ msgid "Buddy List"
+#~ msgstr "Lista de Contactos"
+
+#~ msgid "Description: %s"
+#~ msgstr "Descrição: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Efeito: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Anterior"
+
+#~ msgid "New"
+#~ msgstr "Novo"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Nível de Trabalho: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Presente: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Sair da Guilda"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Recent:"
+#~ msgstr "Recente:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Lançar feitiço de teste 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Lançar feitiço de teste 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Lançar feitiço de teste 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Armas para 2 mãos"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Desequipar@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Equipar@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Largar@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Dividir@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Guardar@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Escolher servidor"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Falha ao mudar para "
+
+#~ msgid "windowed"
+#~ msgstr "em janela"
+
+#~ msgid "fullscreen"
+#~ msgstr "tela cheia"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Habilidade Mistério"
+
+#~ msgid "Weapons"
+#~ msgstr "Armas"
+
+#~ msgid "Stats"
+#~ msgstr "Estatísticas"
+
+#~ msgid "Total"
+#~ msgstr "Total"
+
+#~ msgid "Cost"
+#~ msgstr "Custo"
+
+#~ msgid "Attack:"
+#~ msgstr "Ataque:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Reflexo:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Pontos de Estado Restantes: %d"
+
+#~ msgid "Buddys"
+#~ msgstr "Amigos"
+
+#~ msgid "Party Window"
+#~ msgstr "Janela de Grupo"
+
+#~ msgid "Unarmed"
+#~ msgstr "Desarmado"
+
+#~ msgid "Knife"
+#~ msgstr "Faca"
+
+#~ msgid "Sword"
+#~ msgstr "Espada"
+
+#~ msgid "Staff"
+#~ msgstr "Bastão"
+
+#~ msgid "Whip"
+#~ msgstr "Chicote"
+
+#~ msgid "Bow"
+#~ msgstr "Arco"
+
+#~ msgid "Shooting"
+#~ msgstr "Tiro"
+
+#~ msgid "Axe"
+#~ msgstr "Machado"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Habilidade desconhecida"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " não foi possível criar, mas ela não existe! Saindo."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Não foi possível configurar "
+
+#~ msgid " video mode: "
+#~ msgstr " modo de video: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Conectando ao servidor de personagens..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "A conectar ao servidor de contas..."
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Comando: /new <nome-do-grupo>"
+
+#~ msgid "a"
+#~ msgstr "um(a)"
+
+#~ msgid "Unnamed"
+#~ msgstr "Sem nome"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Apanhar %s@@"
diff --git a/po/pt_BR.po b/po/pt_BR.po
new file mode 100644
index 000000000..e1f68a29a
--- /dev/null
+++ b/po/pt_BR.po
@@ -0,0 +1,5722 @@
+# Brazilian Portuguese translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-02-17 04:42+0000\n"
+"Last-Translator: alms21 <alms21@gmail.com>\n"
+"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Configurar"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Conectando ao servidor de mapas..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Login"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Selecionar personagem"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Conectando ao servidor de mapas..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Servidor"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Erro"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Senha:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Mudar"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Membro foi promovido com sucesso."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Cancelar Registro"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Host de atualização inválido: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Erro ao criar pasta de atualizações!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Comando desconhecido."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "--Ajuda--"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Exibe ajuda"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Exibe o nome do mapa"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Exibe o número de usuários online"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Diz alguma coisa sobre você"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Limpa janela atual"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Envia uma messagem privada a um usuário"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Messagem Confidêncial"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Abreviação de messagem"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Fazer um chat com outros usuários"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Abreviação de query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Fecha a aba de mensagem privada"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Desconsiderar %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Exibir todos os canais públicos"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Criar ou entrar em um canal"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Cria um novo grupo"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Cria um novo grupo"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Convidar um usuário para o grupo"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Determina se <enter> alterna para o log de chat"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Pegar a lista de jogadores presentes (Enviou log de chat. Se "
+"logando)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Anuciamento Global (Somente GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Fecha a aba de mensagem privada"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Envia uma messagem privada a um usuário"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Para mais informações, digite /help <comando>."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Comando: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Exibe uma lista de todos os comandos disponíveis."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Comando: /help <comando>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Exibe o conteúdo de ajuda de <command>"
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Comando: /announce <msg>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** Disponivel apenas para GM's ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Este comando envia a mensagem <msg> para todos os jogadores online."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Comando: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Limpa os logs do chat anterior."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Comando> /item <opção>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Exibe o número total de jogadores online."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Comando: /join <canal>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Este comando faz você entrar em <canal>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Se o <canal> não existe, ele será criado."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Comando: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Este comando exibe uma lista com todos os canais."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Comando: /me <mensagem>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Este comando diz aos outros o que eu estou (fazendo) <msg>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Comando: /msg <nick> <mensagem>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Comando: /whisper <nick> <mensagem>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Comando: /w <nick> <mensagem>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Este comando envia o texto <mensagem> para <nick>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Se <nick> possuir espaços, coloque dentro de parenteses (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Comando: /query <nick>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Comando: /q <nick>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Este comando cria uma aba para mensagens confidenciais entre você e <nick>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Comando: /w <nick> <mensagem>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Seta <mensagem> como o tópico."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Comando: /create <nome-do-grupo>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Estes comandos criam um novo grupo chamado <nome-do-grupo>."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Comando: /create <nome-do-grupo>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Estes comandos criam um novo grupo chamado <nome-do-grupo>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Comando: /party <nick>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Convida <nick> para um grupo com você."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Comando: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Este comando obtém uma lista dos Jogadores ao alcance e a envia para o log "
+"de registro do chat ou, caso haja uma gravação em andamento, para o log de "
+"gravação."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Comando: /toggle <estado>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Este comando define se a tecla enter deve alternar para o log do chat ou se "
+"o log do chat fica oculto automaticamente."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<estado> pode ser \"1\", \"yes\" e \"true\" para ativar ou \"0\", \"no\" e "
+"\"false\" para desativar."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Comando: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Este comando mostra o status do botão alternar."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Comando> /item <opção>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Comando: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Mostra o nome do mapa atual."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Comando: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Exibe o número total de jogadores online."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Digite /help para uma lista de todos os comandos."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Não é possível enviar mensagens particulares vazias!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Não é possível criar uma aba de mensagem particular para o nick \"%s\"! Ou "
+"ela já existe ou é você mesmo."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Solicitando entrada no canal %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Falta o nome do grupo."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Falta o nome do grupo."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Enter alterna para o chat."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "A mensagem fecha o chat."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Agora enter alterna para o chat."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Agora a mensagem fecha o chat."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Amigo"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Desconsiderado"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutro"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Impossível enviar mensagem privada, você foi ignorado pelo usuário."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Grupo criado."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Impossível enviar mensagem privada, você foi ignorado pelo usuário."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Impossível enviar mensagem privada, você foi ignorado pelo usuário."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Impossível enviar mensagem privada, você foi ignorado pelo usuário."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Grupo criado."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Impossível enviar mensagem privada, você foi ignorado pelo usuário."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Opções para /%s são \"yes\" e \"no\", \"true\" e \"false\", \"1\" e \"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Geral"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Screenshot salvo em ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Falha ao salvar screenshot!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "A conexão com o servidor caiu, o jogo será fechado."
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Erro de conexão"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignorando propostas de negócios"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Aceitando propostas de negócios"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Impossível carregar mapa"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Erro ao carregar %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Grupo (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Corporações"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Janela de bate-papo"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Nome"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Atacar"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Falar"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Mover para Cima"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Resetar"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Comprar"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Preço: %s / Total: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Sair"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Máximo"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Loja"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Vender"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Alterar e-mail"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Conta: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Digite o novo endereço de email duas vezes:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "O nome do usuário precisa ter pelo menos %d caracteres."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "O nome do usuário tem que ser inferior a %d caracteres."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "O novo endereço de email já existe."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Alterar senha"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Senha:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Digite a nova senha duas vezes:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "A senha deve ter pelo menos %d caracteres."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "A senha deve ser menor que %d caracteres."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Criar Personagem"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Nome:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Cor do Cabelo:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Estilo do Cabelo:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Criar"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Homem"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Mulher"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Por favor distribua %d pontos"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Seu nome precisa ter no mínimo 4 caracteres."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Status do personagem OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Por favor remova %d pontos"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Confimar exclusão do personagem"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Tem certeza que deseja excluir este personagem?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Gerenciamento de Conta e Personagem"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Cancelar Registro"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Alterar e-mail"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Excluir"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Fechar"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Padrão"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Amigo"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Verde: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Azul: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "baixo"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Link"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Arremesso"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Arco-íris"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Arco-íris"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Arco-íris"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Bate-papo"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d jogadores estão presentes."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Sussurrando para %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Sim"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Não"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignorado"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Tópico: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Nome: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "MiniMapa"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Efeitos de partícula"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Status do personagem OK"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Esquerda"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Selecionar Jogador"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Selecionar Jogador"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Selecionar Jogador"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Selecionar Jogador"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Cursor customizado"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "OK"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Equipamento"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Desequipar"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Ajuda"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Fechar"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventório"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Armazenamento"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Entradas:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Equipar"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Usar"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Descartar"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Dividir"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Peso:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Guardar"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Retirar"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Descartar"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Tudo"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Selecionar quantidade de itens para negociar."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Selecionar quantidade de itens para descartar."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Escolha a quantidade de itens para guardar."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Escolha a quantidade de itens para retirar."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Selecionar quantidade de itens para dividir."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Erro desconhecido"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Peso: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Janela de Status"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Resetar"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Resetar"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Nível: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "Exp:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Esquerda"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Fechar"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Login"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Servidor:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Lembrar nome de usuário"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registrar"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Servidor"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Mapa"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Aguardando servidor"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Próximo"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Confirmar"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Lança"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Próximo"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Para:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Enviar"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Falha ao enviar como remetente ou a carta é inválida."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Dinheiro: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Desequipar"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Negociar com %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Atacar %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Cancelar@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Retirar@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Desconsiderar %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignorar %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Deixar de ignorar %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Ignorar completamente %s@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Convidar um usuário para o grupo"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Convidar um usuário para o grupo"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Deixar de ignorar %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Atacar %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Expulsar jogador@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Adiciona nome ao chat@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Cancelar@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Pegar %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Adicionar ao chat@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Usar@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Realçar aba"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Realçar aba"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Mudar"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Guardar"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Guardar"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Guardar"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Retirar"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Retirar"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Retirar"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Adicionar ao chat@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Trocar servidor"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Trocar de Personagem"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Confirmar:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "O nome do usuário precisa ter pelo menos %d caracteres."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "O nome do usuário tem que ser inferior a %d caracteres."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "A senha deve ter pelo menos %d caracteres."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "A senha deve ser menor que %d caracteres."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Senhas não conferem."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Selecione seu servidor"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Porta:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Servidor:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Conectando..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Cursor customizado"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Por favor especifique o endereço e a porta do servidor."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Aguardando servidor"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Habilitar joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Habilitar joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Áudio"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Volume Sfx"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Volume da Música"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Sem texto"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "A cor se parece com isso"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Cores"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Tipo: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Estático"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulso"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Arco-íris"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Espectro"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Atraso: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Vermelho: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Verde: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Azul: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Aplicar"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Restaurar janelas"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Aperte o botão para começar a calibração"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Calibrar"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Habilitar joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Parar"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Gire o bastão"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Teclado"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Atribuir"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Atribuir"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Padrão"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Conflitos nas teclas detectado."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Realçar"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Habilitar joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Realçar"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Habilitar/Desabilitar Negociações"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Impossível comprar."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Habilitar joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "como partícula"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relação"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutro"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Amigo"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Desconsiderado"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignorado"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Permitir trocas"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Permitir mensagens particular"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Deixar todas as mensagens particulares em abas"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Jogadores"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Quando ignorado:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Mostrar nome"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Selecionar Jogador"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Efeitos de partícula"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Ajuda"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Mudar"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Reincie o jogo para que as mudanças surtam efeito."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Minúsculo"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Pequena"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Média"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Grande"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Sem texto"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Texto"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Bolhas, sem nomes"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Bolhas com nomes"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "desligado"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "baixo"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "alto"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "médio"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "máximo"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Tela cheia"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relação"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Cursor customizado"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Nomes visíveis"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Efeitos de partícula"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Mostrar aviso de achado"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "em chat"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "como partícula"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Habilitar joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Fundo"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Limite FPS:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "Limite FPS:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Vídeo"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Texto sobrescrito"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Opacidade da GUI"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Ambiente FX"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Detalhe de partículas"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Tamanho da fonte"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Não"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "modo e restauração do antigo modo também falharam!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "modo e restauração do antigo modo também falharam!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Mudando para Tela cheia"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "É preciso reiniciar para as mudanças terem efeito."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Trocando OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Aplicando mudança a OpenGL requer reiniciar o jogo."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Resolução de tela alterada"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Configurações de efeito de partícula modificadas."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "As mudanças terão efeito na mudança do mapa."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Adicionar"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Proposta de negociação"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s quer negociar com você, você aceita?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Habilidades"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Acima"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Pontos de habilidade: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Pontos de habilidade: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Habilidades"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Nível: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Nível: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Corporação"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Corporação criada."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Criar corporação"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Tem certeza que deseja sair?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Grupo"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Convidar um usuário para o grupo"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Convidar um usuário para o grupo"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Tem certeza que deseja sair?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Criar corporação"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Criar Personagem"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Convidar Usuário"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Grande"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Convite de %s aceito."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Convite de %s rejeitado."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Convite de %s aceito."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Convite de %s rejeitado."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Erro ao criar corporação."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Corporação"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Selecione seu servidor"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Requisição de grupo recebida, mas já existe um."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s te convidou para entrar no grupo %s."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Aceitar convite para o grupo"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Requisição de grupo recebida, mas já existe um."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s te convidou para entrar em seu grupo."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s te convidou para entrar no grupo %s."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s te convidou para entrar em seu grupo."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s te convidou para entrar no grupo %s."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Aceitar convite para o grupo"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Grupo"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Selecione seu servidor"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Nível: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Dinheiro: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Trabalho: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Trabalho:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Status do personagem OK"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Nível: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Pontos de habilidade: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Esquerda"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Permitir trocas"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Esquerda"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Geral"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Mágica"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Mágica"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Comando: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Mágica"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Comando: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Selecionar Jogador"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Nível máximo"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Mostrar nome"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Propor negócio"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Confirmado. Aguardando..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Aceitar negociação"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Aceita. Aguarde..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Negócio: você"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Negócio"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Você obteve %s"
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Você dá:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Mudar"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Falha ao adicionar item. Você não pode duplicar um tipo de item na janela."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Você não tem dinheiro suficiente."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Nome: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Atualizando..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Conectando..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Jogar"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 O processo de update está incompleto."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 É altamente recomendado que"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 você tente novamente mais tarde"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Concluído"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Ser"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Amigo"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Desconsiderado"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignorado"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "Nomes dos GMs"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Nomes de outros jogadores"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Próprio nome"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Nomes dos GMs"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monstros"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monstro acerta jogador"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Grupo"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Corporação"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Efeitos de partícula"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Aviso de achado"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Aviso de experiência"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Monstro acerta jogador"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Nomes de outros jogadores"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Golpe crítico"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Jogador acerta monstro"
+
+#: src/gui/userpalette.cpp:137
+#, fuzzy
+msgid "Local Player Miss"
+msgstr "Salvar lista de jogadores"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Falhas"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Realçar aba"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Realçar"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Realçar aba"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monstro acerta jogador"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Listar os usuários deste canal"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Setar o tópico deste canal"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Sair do canal"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Transdorma um usuário em operador do canal"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Expulsa um usuário do canal"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Comando: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Mostra os usuários neste canal."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Comando: /topic <mensagem>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Seta <mensagem> como o tópico."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Comando: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Sair do canal."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Se você for a última pessoa no canal, ele será deletado."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Comando: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Tornar <nick> operador do canal."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Operadores de canal podem expulsar e dar op a outros usuários do canal."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Comando: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Retirar <nick> do canal."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "É preciso um usuário para dar op!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "É preciso um usuário para expulsar!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Anúncio geral:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Anúncio geral de %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s envia a mensagem privada: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Fecha a aba de mensagem privada"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Comando: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Este comando fecha a atual aba de mensagem privada"
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Comando: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Exibe o número total de jogadores online."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Este comando inicia a gravação do registro de bate-papo para o arquivo "
+"<nome_do_arquivo>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Janela de bate-papo"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Emoticon"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Atalho"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Selecionar OK"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Mudar"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Selecione seu servidor"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Mover para Cima"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Mover para Baixo"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Esquerda"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Direita"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Selecionar & Atacar"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Esquerda"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Emoticon"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Parar ataque"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Selecionar o mais próximo"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Selecionar NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Selecionar Jogador"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Pegar"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Esconder janelas"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Sentar"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Screenshot"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Habilitar/Desabilitar Negociações"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Alterar e-mail"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Atalho para Ítem %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Atalho para Ítem %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Janela de Ajuda"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Janela de Status"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Janela de inventário"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Janela de equipamento"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Janela de Habilidade"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Janela de Minimapa"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Janela de bate-papo"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Janela de atalhos para itens"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Janela de Configurações"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Janela de depuração"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Janela de Habilidade"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Janela de atalho para Emoticons"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Janela de Status"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Janela de Configurações"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Esconder janelas"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Janela de Status"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Comando: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Janela de bate-papo"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Aba de chat anterior"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Próxima aba de chat"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Atalho para Emoticon %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Alternar para chat"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Rolar janela de chat para cima"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Rolar janela de chat para baixo"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Aba de chat anterior"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Próxima aba de chat"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Aba de chat anterior"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Próxima aba de chat"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Selecionar OK"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignorar input 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignorar input 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Mover para Baixo"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Esquerda"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Direita"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Trocar de Personagem"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Servidor"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Selecionar & Atacar"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Alterar senha"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Alterar e-mail"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Habilitar/Desabilitar Negociações"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Corrija-os, ou o jogo irá se comportar de forma estranha."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Impossível pegar ítem."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Você pegou %s [@@%d|%s@@]."
+msgstr[1] "Você pegou %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Você obteve %s"
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Opções:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Arquivo de configuração a ser usado"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Arquivo de configuração a ser usado"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Exibe a versão"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Exibe esta ajuda"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Arquivo de configuração a ser usado"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Efetua login com este usuário"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Efetua login com esta senha"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Efetua login com este personagem"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Nome ou IP do servidor de login"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Porta do servidor de login"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Usa este host de update"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+" -D --default : Escolhe um personagem e um servidor de personagem padrão"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Não faz downloads de atualização"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Pasta de onde os dados do jogo vão ser carregados"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Diretório a ser usado como pasta inicial"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Diretório a ser usado como pasta inicial"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Desabilita OpenGL nesta sessão"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Força"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Força %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Agilidade"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Agilidade %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Destreza"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Destreza %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Vitalidade"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Vitalidade %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Inteligência"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Inteligência %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Força de Vontade:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Força de vontade %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Você está morto."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "Lamentamos informar que seu personagem foi morto em combate."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Você não está mais tão vivo."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "As mãos frias da morte estão levando sua alma."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Fim de jogo!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Não, crianças. Seu personagem não morreu de verdade. Ele... err... foi para "
+"um lugar melhor."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Seu plano de quebrar as armas de seus inimigos com o seu pescoço não deu "
+"certo."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Eu acho que isso não funcionou muito bem."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Você quer uma identificação de suas posses?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Infelizmente, seus traços nunca foram encontrados..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Aniquilado."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Parece que te ofereceram sua própria cabeça."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "Você estragou tudo de novo, jogue fora seu corpo e arranje outro."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Clique em OK para repopular."
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Você morreu"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Já está conectado"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Nome de usuário já existe"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Status do personagem OK"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Status do personagem OK"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Erro desconhecido"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Informações"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Personagem deletado."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Selecionar quantidade de itens para negociar."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Erro desconhecido"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Não há gameservers disponíveis."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Tópico: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Jogador acerta monstro"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Comando: /join <canal>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Solicitando entrada no canal %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s entrou para o grupo."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Comando desconhecido."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Corporação criada."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Erro ao criar corporação."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Convite enviado."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Membro foi promovido com sucesso."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Erro ao promover do membro."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Simbolo-mágico errado."
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Já está conectado"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "A conta expirou"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Nova senha incorreta"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Senha antiga incorreta"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Conta não conectada. Por favor, efetue o login primeiro."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Novo endereço de email incorreto"
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Antigo endereço de email incorreto"
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "O novo endereço de email já existe."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Versão do cliente é muito antiga"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Nome de usuário ou senha inválido"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "A conta expirou"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Nome de usuário, senha ou email inválido"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Nome de usuário já existe"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Endereço de email já existe"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Entrou para o grupo."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s entrou para o grupo."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s recusou seu convite."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Aceitando propostas de negócios."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignorando propostas de negócios."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s quer negociar com você, você aceita?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Negociando com %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Negociação cancelada."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Negociação realizada."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Erro na expulsão!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Expulsão bem sucedida!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Nada para vender."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Obrigado pela compra."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Impossível comprar."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Obrigado pela venda."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Impossibilitado de vender."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Não é possível usar este ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Erro desconhecido"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Erro ao criar personagem. Provavelmente o nome já está sendo usado."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Personagem deletado."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Falha ao deletar personagem."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Força:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Agilidade:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Vitalidade:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Inteligência:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Destreza:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Sorte"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Impossível enviar mensagem privada, o usuário está desconectado."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Impossível enviar mensagem privada, você foi ignorado pelo usuário."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Jogador"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Jogador"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Não há suporte para canais!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Nome"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Proposta de negociação"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Força %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Agilidade %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Vitalidade %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Inteligência %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Destreza %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Sorte %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Falha de autenticação"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Não há servidores disponíveis"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Mais alguém está tentando utilizar esta conta"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Existe alguém logado a esta conta"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Hack de velocidade detectado"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Login duplicado"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Erro de conexão desconhecido"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Você foi desconectado do servidor!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Sorte"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Defesa:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "M. Ataque:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "M. Defesa:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Acuracidade:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Evasão:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Golpe crítico"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Ataque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Ataque %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monstro acerta jogador"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Exibe esta ajuda."
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Convida um jogador para o seu grupo"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Sai do grupo em que você está"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Expulsa alguém do grupo em que você está"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Comando: /invite <nick>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Convida <nick> para um grupo com você."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Comando: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Este comando faz com que o jogador saia do grupo."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Erro ao criar corporação."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Resposta de convite desconhecida para %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Corporação"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Corporação"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Nível: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Nível máximo"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Corporação"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Corporação criada."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Corporação criada."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s agora é um membro do seu grupo."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Resposta de convite desconhecida para %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Você saiu do grupo."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s saiu do seu grupo."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s agora é um membro do seu grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Convida um jogador para o seu grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Sai do grupo em que você está"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Expulsa alguém do grupo em que você está"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Mostra/Muda opções de compartilhamento de itens do grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+"/exp > Mostra/Modifica opções de compartilhamento de experiência do grupo"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Este comando faz com que o jogador saia do grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Comando> /item <opção>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Este comando muda a opção de compartilhamento de itens do grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<policy> pode ser \"1\", \"yes\" e \"true\" para habilitar compartilhamento "
+"de itens, ou \"0\", \"no\" e \"false\" para desabilitar."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Comando: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+"Este comando exibe a atual opção de compartilhamento de itens do grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Comando: /exp <policy>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Este comando muda a opção de compartilhamento de experiência do grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<policy> pode ser \"1\", \"yes\" e \"true\" para habilitar compartilhamento "
+"de experiência, ou \"0\", \"no\" e \"false\" para desabilitar."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Comando: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+"Este comando exibe a atual opção de compartilhamento de experiência do grupo."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Compartilhamento de itens habilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Compartilhamento de itens desabilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Não é possível compartilhar itens."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Compartilhamento de itens habilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Compartilhamento de experiência habilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Compartilhamento de experiência desabilitado."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Não é possível compartilhar experiência."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Compartilhamento de experiência habilitado."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Problemas ao usar ítem."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Impossível equipar."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Conta não encontrada. Por favor, logue novamente."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Nova senha é muito curta"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "ID não registrado"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Senha incorreta"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "A conta expirou"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Rejeitado pelo servidor"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+"Você foi permanentemente banido do jogo. Por favor entre em contato com "
+"algum GM."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Você banido do jogo até %s.\n"
+"Por favor entre em contato com algum GM através dos fóruns."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Este nome de usuário já está em uso"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Impossibilitado de vender."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Conectando ao servidor de mapas..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Não foi possível criar o grupo."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Grupo criado."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s já é membro de um grupo."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s recusou seu convite."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s agora é um membro do seu grupo."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Resposta de convite desconhecida para %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Você saiu do grupo."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s saiu do seu grupo."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Um membro desconhecido tentou dizer: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s não está em seu grupo!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Insira uma moeda para continuar."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Você não morreu ainda. Está apenas descansando."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Você não é mais."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Você deixou de ser."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Você expirou e foi encontrar seu criador."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Você é um cadáver."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Sem vida, você descansa em paz."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "Se não fosse tão animado, estaria comendo grama pela raiz."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Seus processos metabólicos agora são história."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Você bateu as botas."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Você chutou o balde."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+"Você dispensou seu corpo mortal, abaixou as cortinas e juntou-se ao maldito "
+"coro invisível."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Você é um ex-jogador"
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Você foi desta para melhor."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Mensagem"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Você está carregando mais que a metade de seu peso. Você não poderá mais "
+"recuperar HP."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Você está carregando mais que a metade de seu peso. Você não poderá mais "
+"recuperar HP."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Você pegou "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Você obteve %s"
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Equipe as flechas primeiro."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Falha na negociação!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Falha no Emote!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Falha ao sentar!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Falha ao criar Chat!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Impossivel entrar no grupo!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Impossivel gritar!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Você ainda não tem nivel necessário!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "HP insuficiente!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "SP insuficiente!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Você não tem nenhuma nota armazenada!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Você não pode fazer isso agora!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Parece que você precisa de mais dinheiro... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Você não pode usar essa habilidade com esse tipo de arma!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Você precisa de outra gema vermelha!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Você precisa de outra jóia azul!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Você está com muita carga para fazer isso!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Hã? O que é isso?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Falha ao transportar..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Não foi possível roubar nada..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Veneno não surtiu efeito..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Negociação impossível. O parceiro de negócios está muito longe."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Negociação impossível. O personagem não existe."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Negociação cancelada devido a uma razão desconhecida."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Negociação: Você e %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Negociação com %s cancelada."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Troca injusta pacote cancelado."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Erro ao adicionar item. Parceiro de negócios carregando muito peso."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "Erro ao adicionar item. Parceiro de negócios não tem slots livres."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Erro ao adicionar item devido a um motivo desconhecido."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Ignorar completamente %s@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Ataque %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Defesa %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Item desconhecido"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "sem nome"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Detalhe de partículas"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Ambiente FX"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Atalho para Emoticon %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Jogador acerta monstro"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Tópico: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Nome: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "MiniMapa"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Começar a gravar o chat em um arquivo externo"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Comando: /record <nome_do_arquivo>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr ""
+#~ "Este comando inicia a gravação do registro de bate-papo para o arquivo "
+#~ "<nome_do_arquivo>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Comando: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Este comando finaliza a sessão de gravação."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Presença gravada no registro do log."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Finalizando gravação."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Não há gravação neste momento."
+
+#~ msgid "Already recording."
+#~ msgstr "Já está gravando."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Iniciando a gravação..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Falha ao iniciar gravação."
+
+#~ msgid "Recording..."
+#~ msgstr "Gravando..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Parar gravação"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Encontrar rota para o mouse"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "Exp:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Dinheiro: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Trabalho:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Nível: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Grupo criado."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Impossível enviar mensagem privada, você foi ignorado pelo usuário."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Arquivo de configuração a ser usado"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Arquivo de configuração a ser usado"
+
+#~ msgid "Sound"
+#~ msgstr "Som"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Acesso negado"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Erro desconhecido ao selecionar personagem"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "No momento ainda não é possível convidar deste modo."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s te convidou para entrar em seu grupo."
+
+#~ msgid "Willpower:"
+#~ msgstr "Força de Vontade:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Servidor cheio"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Negociando com %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Sussurrar"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Fazer amizade com %s@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Desconsiderado"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Ignorar completamente %s@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Convidar %s para sua corporação@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Convidar %s para entrar no seu grupo@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Erro na expulsão!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Falar com %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Expulsar monstro@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Pegar"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Não é possível enviar chat vazio!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Impossível desequipar."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Sombra do Texto"
+
+#~ msgid "Text Outline"
+#~ msgstr "Borda do texto"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Rótulos da barra de progresso"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Item muito caro"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Item está equipado"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Jogador"
+
+#~ msgid "Whisper"
+#~ msgstr "Sussurrar"
+
+#~ msgid "Is"
+#~ msgstr "É"
+
+#~ msgid "Server"
+#~ msgstr "Servidor"
+
+#~ msgid "Logger"
+#~ msgstr "Histórico"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Tipo de item desconhecido"
+
+#~ msgid "Generics"
+#~ msgstr "Genéricos"
+
+#~ msgid "Hats"
+#~ msgstr "Chapéus"
+
+#~ msgid "Usables"
+#~ msgstr "Usáveis"
+
+#~ msgid "Shirts"
+#~ msgstr "Camisas"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Armas para 1 mão"
+
+#~ msgid "Pants"
+#~ msgstr "Calças"
+
+#~ msgid "Shoes"
+#~ msgstr "Sapatos"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Armas para 1 mão"
+
+#~ msgid "Shields"
+#~ msgstr "Escudos"
+
+#~ msgid "Rings"
+#~ msgstr "Anéis"
+
+#~ msgid "Necklaces"
+#~ msgstr "Colares"
+
+#~ msgid "Arms"
+#~ msgstr "Armas"
+
+#~ msgid "Ammo"
+#~ msgstr "Munição"
+
+#~ msgid "HP Bar"
+#~ msgstr "Barra de HP"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 da barra de HP"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "1/2 da barra de HP"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 da barra de HP"
+
+#~ msgid "no"
+#~ msgstr "não"
+
+#~ msgid "Buddy"
+#~ msgstr "Amigo"
+
+#~ msgid "Buddy List"
+#~ msgstr "Lista de amigos"
+
+#~ msgid "Description: %s"
+#~ msgstr "Descrição: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Efeito: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Anterior"
+
+#~ msgid "New"
+#~ msgstr "Novo"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Nível de Trabalho: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Presente: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Sair da corporação"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Recent:"
+#~ msgstr "Recente:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Lançar feitiço de teste 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Lançar feitiço de teste 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Lançar feitiço de teste 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Armas para 2 mãos"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Desequipar@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Equipar@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Descartar@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Dividir@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Guardar@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Selecionar Servidor"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Falha ao mudar para "
+
+#~ msgid "windowed"
+#~ msgstr "em janela"
+
+#~ msgid "fullscreen"
+#~ msgstr "tela cheia"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Habilidade Mistério"
+
+#~ msgid "Weapons"
+#~ msgstr "Armas"
+
+#~ msgid "Crafts"
+#~ msgstr "Artesanatos"
+
+#~ msgid "Stats"
+#~ msgstr "Status"
+
+#~ msgid "Total"
+#~ msgstr "Total"
+
+#~ msgid "Cost"
+#~ msgstr "Custo"
+
+#~ msgid "Attack:"
+#~ msgstr "Ataque:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Reflexo:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Pontos de Status Restantes: %d"
+
+#~ msgid "curl error "
+#~ msgstr "Erro do curl "
+
+#~ msgid " host: "
+#~ msgstr " host: "
+
+#~ msgid "Buddys"
+#~ msgstr "Amigos"
+
+#~ msgid "Party Window"
+#~ msgstr "Janela de Grupo"
+
+#~ msgid "Unarmed"
+#~ msgstr "Desarmado"
+
+#~ msgid "Knife"
+#~ msgstr "Faca"
+
+#~ msgid "Sword"
+#~ msgstr "Espada"
+
+#~ msgid "Staff"
+#~ msgstr "Cajado"
+
+#~ msgid "Whip"
+#~ msgstr "Chicote"
+
+#~ msgid "Bow"
+#~ msgstr "Arco"
+
+#~ msgid "Shooting"
+#~ msgstr "Tiro"
+
+#~ msgid "Mace"
+#~ msgstr "Cetro"
+
+#~ msgid "Axe"
+#~ msgstr "Machado"
+
+#~ msgid "Craft"
+#~ msgstr "Artesanato"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Habilidade desconhecida"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " não foi possível criar, mas ela não existe! Saindo."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Não foi possível configurar "
+
+#~ msgid " video mode: "
+#~ msgstr " modo de video: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Conectando ao servidor de personagens..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Conectando ao servidor de contas..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Abreviação de create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Comando: /new <nome-do-grupo>"
+
+#~ msgid "a"
+#~ msgstr "um(a)"
+
+#~ msgid "Unnamed"
+#~ msgstr "Sem nome"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pegar|Pegar %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Rolar radius"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Rolar Laziness"
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 000000000..e77024e8f
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,5315 @@
+# Russian translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+# jmb_kz <jmb_kz@mail.ru>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2010-11-13 17:01+0300\n"
+"Last-Translator: Andrei Karas <akaras@inbox.ru>\n"
+"Language-Team: Russian <ru@li.org>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+"X-Language: ru_RU\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Настройка"
+
+#: src/client.cpp:798
+msgid "Connecting to server"
+msgstr "Идет подключение к серверу..."
+
+#: src/client.cpp:829
+msgid "Logging in"
+msgstr "Авторизация"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr "Вход в игровой мир"
+
+#: src/client.cpp:953
+msgid "Requesting characters"
+msgstr "Получение списка персонажей"
+
+#: src/client.cpp:984
+msgid "Connecting to the game server"
+msgstr "Подключение к игровому серверу"
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Сервер"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Ошибка"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr "Запрос регистрационных данных"
+
+#: src/client.cpp:1072
+msgid "Password Change"
+msgstr "Изменить Пароль"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr "Пароль изменен!"
+
+#: src/client.cpp:1092
+msgid "Email Change"
+msgstr "Сменить Email"
+
+#: src/client.cpp:1093
+msgid "Email changed successfully!"
+msgstr "Email изменен!"
+
+#: src/client.cpp:1113
+msgid "Unregister Successful"
+msgstr "Регистрация удалена"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr "Хорошо, возвращайтесь в любое время..."
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr "%s не существует, и не может быть создано! Выход."
+
+#: src/client.cpp:1494
+#, c-format
+msgid "Invalid update host: %s"
+msgstr "Некорректный сервер обновлений: %s"
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Ошибка создания директории для обновлений!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr "Ошибка: %s не существует, и не может быть создан! Выход."
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Неизвестная команда."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Помощь --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Отображает этот текст"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Отображает имя карты"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Отображает количество пользователей он-лайн"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Расскажите что-нибудь о себе"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Очищает это окно"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Послать личное сообщение пользователю"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Аналог команды msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Аналог команды msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query> Создает вкладку для чата с пользователем."
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q> Аналог query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr "/away > Сообщить тем, с кем вы перешептываетесь, что вы отошли."
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr "/ignore > Игнорировать игрока"
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr "/unignore > Убрать пользователя из игнора"
+
+#: src/commandhandler.cpp:315
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/ignoreall > Игнорировать все вкладки с перешептыванием"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr "/erase > Удалить игрока"
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr "/befriend > Подружиться"
+
+#: src/commandhandler.cpp:318
+msgid "/desregard > Disregard a player"
+msgstr "/desregard > не придавать значения"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr "/neutral > Относится нейтрально"
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Показать список каналов"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Создать или присоединиться к каналу"
+
+#: src/commandhandler.cpp:324
+msgid "/createparty > Create a new party"
+msgstr "/createparty > Создать группу"
+
+#: src/commandhandler.cpp:325
+msgid "/createguild > Create a new guild"
+msgstr "/createguild > Создать гильдию"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Пригласить пользователя в группу"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+"/toggle -> Определяет появление строки ввода текста в чат по нажатию <return>"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Показывает список игроков он-лайн (также извещает в окне чата, "
+"если включен лог)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Глобальное извещение (доступно только ГМ)"
+
+#: src/commandhandler.cpp:335
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/closeall > Закрыть все вкладки перешептывания"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr "/all > Показать всех видимых существ на вкладке отладки"
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr "/move > Идти к заданной позиции"
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr "/navigate > Нарисовать путь к заданной позиции"
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr "/target > Прицелиться в существо"
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr "/outfit > Одеть наряд под указанным номером"
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr "/emote > Показать смайлик под указанным номером"
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr "/follow > Следовать за игроком"
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr "/imitation > Имитировать игрока"
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr "/heal > Лечить игрока"
+
+#: src/commandhandler.cpp:347
+msgid "/mail > Send offline message to player"
+msgstr "/mail > Послать оффлайн сообщение пользователю"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Для более детальной информации введите: /help <команда>"
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Команда: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Эта команда показывает список доступных команд"
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Команда: /help <команда>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Эта команда показывает помощь по <команде>."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Команда: /announce <сообщение>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** доступно только для GM ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Эта команда посылает <сообщение> всем игрокам в сети."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Команда: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Эта команда очищает лог чата."
+
+#: src/commandhandler.cpp:379
+msgid "Command: /ignore <player>"
+msgstr "Команда: /ignore <игрок>"
+
+#: src/commandhandler.cpp:380
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+"Эта команда игнорирует указанного игрока независимо от текущего статуса "
+"взаимоотношений"
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Команда: /join <канал>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Команда для входа на <канал>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Если <канал> не существует, он будет создан."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Команда: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Эта команда показывает список всех каналов."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Команда: /me <сообщение>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Эта команда покажет другим игрокам, что вы (делаете) <сообщение>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Команда: /msg <имя персонажа> <сообщение>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Команда: /whisper <имя персонажа> <сообщение>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Команда: /w <ник> <сообщение>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Эта команда посылает текст <сообщение> пользователю <nick>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Если ник содержит пробелы, заключите его в кавычки (\")."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Команда: /query <имя персонажа>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Команда: /q <имя персонажа>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Эта команда создаст закладку для личного общения между вами и <имя игрока>."
+
+#: src/commandhandler.cpp:417
+msgid "Command: /away <afk reason>"
+msgstr "Команда: /away <причина отсутствия у компьютера>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr "Команда сообщает, что вы отошли по указанной причине."
+
+#: src/commandhandler.cpp:420
+msgid "Command: /away"
+msgstr "Команда: /away"
+
+#: src/commandhandler.cpp:421
+msgid "This command clears the away status and message."
+msgstr "Эта команда очищает статус и сообщение отсутствия."
+
+#: src/commandhandler.cpp:425
+msgid "Command: /createparty <name>"
+msgstr "Command: /createparty <имя_группы>"
+
+#: src/commandhandler.cpp:426
+msgid "This command creates a new party called <name>."
+msgstr "Эта Команда создает группу под названием <имя_группы>."
+
+#: src/commandhandler.cpp:430
+msgid "Command: /createguild <name>"
+msgstr "Команда: /createparty <имя_гильдии>"
+
+#: src/commandhandler.cpp:431
+msgid "This command creates a new guild called <name>."
+msgstr "Эта Команда создает гильдию под названием <имя_гильдии>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Команда: /party <имя>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Эта команда приглашает <имя персонажа> к вам в группу."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Команда: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Команда получпет список всех игроков, которых вы слышите и посылает его либо "
+"в лог-файл (если включена такая опция), либо в окно чата."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Команда: /toggle <режим>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Эта Команда устанавливает, будет ли нажатие клавиши Enter переключать лог "
+"чата или же он (лог) будет выключен автоматически."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<режим> может быть \"1\", \"yes\", \"true\" дабы включить опцию или \"0\", "
+"\"no\", \"false\" чтобы выключить."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Команда: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Эта команда показывает статус переключения строки ввода в чат"
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+msgid "Command: /unignore <player>"
+msgstr "Команда: /unignore <игрок>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr "Эта команда улаляет игрока из списка игнорирования"
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Команда: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Эта команда показывает имя текущей карты."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Команда: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Эта команда показывает число пользователей в сети на данный момент."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Введите /help для получения списка команд."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Нельзя отправлять пустые сообщения!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Невозможно создать вкладку для личного общения с игроком \"%s\"! Или вкладка "
+"уже создана, или этот игрок вы сами."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Запрос на присоединение к каналу %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Не указано название группы"
+
+#: src/commandhandler.cpp:601
+msgid "Guild name is missing."
+msgstr "Не задано имя гильдии."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr "Пожалуйста укажите имя"
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Enter переключает вас на окно чата."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Сообщение закрывает чат."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Теперь Return переключает чат."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Теперь сообщение закрывает чат."
+
+#: src/commandhandler.cpp:700
+msgid "friend"
+msgstr "друг"
+
+#: src/commandhandler.cpp:705
+msgid "disregarded"
+msgstr "пренебрегаемый"
+
+#: src/commandhandler.cpp:710
+msgid "neutral"
+msgstr "нейтральный"
+
+#: src/commandhandler.cpp:729
+#, c-format
+msgid "Player already %s!"
+msgstr "Игрок уже %s!"
+
+#: src/commandhandler.cpp:743
+#, c-format
+msgid "Player successfully %s!"
+msgstr "Игрок удачно %s!"
+
+#: src/commandhandler.cpp:751
+#, c-format
+msgid "Player could not be %s!"
+msgstr "Игрок не может быть %s!"
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr "Игрок не был игнорируемым!"
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr "Игрок больше не игнорируется!"
+
+#: src/commandhandler.cpp:782
+msgid "Player could not be unignored!"
+msgstr "Игрок не может быть удален из списка игнорирования!"
+
+#: src/commandhandler.cpp:799
+msgid "Player already erased!"
+msgstr "Игрок и так уже удален!"
+
+#: src/commandhandler.cpp:810
+msgid "Player successfully erased!"
+msgstr "Игрок удален!"
+
+#: src/commandhandler.cpp:812
+msgid "Player could not be erased!"
+msgstr "Игрок не может быть удален!"
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"/%s может принимать значение \"yes\", \"no\", \"true\", \"false\", \"1\" или "
+"\"0\"."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Общие"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr "Отладка"
+
+#: src/game.cpp:435
+msgid "Screenshot saved as "
+msgstr "Снимок экрана сохранен как "
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Ошибка при сохранении снимка экрана!"
+
+#: src/game.cpp:482
+msgid "The connection to the server was lost."
+msgstr "Соединение с сервером потеряно."
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Ошибка сети"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Игнорировать предложения о торговле"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Принимать предложения о торговле"
+
+#: src/game.cpp:1373
+msgid "Could Not Load Map"
+msgstr "Не удалось загрузить карту"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Ошибка во время загрузки %s"
+
+#: src/gui/beingpopup.cpp:89
+#, c-format
+msgid "Party: %s"
+msgstr "Группа: %s"
+
+#: src/gui/beingpopup.cpp:102
+#, c-format
+msgid "Guild: %s"
+msgstr "Гильдия: %s"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+msgid "Bot Checker"
+msgstr "Окно детектора ботов"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Имя"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Атаковать"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Говорить"
+
+#: src/gui/botcheckerwindow.cpp:297
+msgid "Move"
+msgstr "Движение"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr "Результат"
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Сбросить"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Купить"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Цена: %s / Всего: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr "+"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr "-"
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Выход"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Макс"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Магазин"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Продать"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Отмена"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Сменить адрес E-mail"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Учётная запись: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr "Введите новый адрес E-mail дважды:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Новый адрес email должен содержать не менее %d символов."
+
+#: src/gui/changeemaildialog.cpp:136
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Новый адрес email должен содержать менее %d символов."
+
+#: src/gui/changeemaildialog.cpp:143
+msgid "The email address entries mismatch."
+msgstr "Адрес E-mail не совпадает"
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Изменить пароль"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Пароль:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr "Введите новый пароль дважды:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr "Введите старый пароль."
+
+#: src/gui/changepassworddialog.cpp:117
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Пароль должен содержать не менее %d символов."
+
+#: src/gui/changepassworddialog.cpp:124
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Пароль должен содержать менее %d символов."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr "Новый пароль не совпадает."
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Создать персонажа"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Имя:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ">"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr "<"
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr "Цвет волос:"
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr "Стрижка:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Создать"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Мужчина"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Женщина"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Распределите очки (%d)"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Имя должно содержать не менее четырех символов."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Данные персонажа в порядке"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Снимите очки (%d)"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Подтвердите удаление героя"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Вы уверены, что хотите удалить этого персонажа?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Управление учётной записью"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr "Сменить героя"
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Удалить регистрацию"
+
+#: src/gui/charselectdialog.cpp:155
+msgid "Change Email"
+msgstr "Сменить адрес E-mail"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Удалить"
+
+#: src/gui/charselectdialog.cpp:425
+msgid "Choose"
+msgstr "Выбрать"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr "(пусто)"
+
+#: src/gui/chat.cpp:91
+msgid "default"
+msgstr "По умолчанию"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr "черный"
+
+#: src/gui/chat.cpp:93
+msgid "red"
+msgstr "красный"
+
+#: src/gui/chat.cpp:94
+msgid "green"
+msgstr "зеленый"
+
+#: src/gui/chat.cpp:95
+msgid "blue"
+msgstr "синий"
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr "золотой"
+
+#: src/gui/chat.cpp:97
+msgid "yellow"
+msgstr "желтый"
+
+#: src/gui/chat.cpp:98
+msgid "pink"
+msgstr "розовый"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr "фиолетовый"
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr "серый"
+
+#: src/gui/chat.cpp:101
+msgid "brown"
+msgstr "коричневый"
+
+#: src/gui/chat.cpp:102
+msgid "rainbow 1"
+msgstr "радуга 1"
+
+#: src/gui/chat.cpp:103
+msgid "rainbow 2"
+msgstr "радуга 2"
+
+#: src/gui/chat.cpp:104
+msgid "rainbow 3"
+msgstr "радуга 3"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Чат"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d игроков он-лайн."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Вы прошептали %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Да"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Нет"
+
+#: src/gui/confirmdialog.cpp:49
+msgid "Ignore"
+msgstr "Игнорировать"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr "%d FPS (Программно)"
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr "%d FPS (быстрая OpenGL)"
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr "%d FPS (старая OpenGL)"
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr "%d FPS"
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+msgid "Music:"
+msgstr "Музыка:"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+msgid "Map:"
+msgstr "Карта:"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+msgid "Minimap:"
+msgstr "МиниКарта:"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr "Курсор: (%d, %d)"
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, c-format
+msgid "Particle count: %d"
+msgstr "Количество частиц: %d"
+
+#: src/gui/debugwindow.cpp:84
+#, c-format
+msgid "Map actors count: %d"
+msgstr "Кол-во объектов: %d"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+msgid "Player Position:"
+msgstr "Позиция игрока:"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+msgid "Target:"
+msgstr "Цель:"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+msgid "Target Id:"
+msgstr "Id цели:"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+msgid "Target Level:"
+msgstr "Уровень цели:"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+msgid "Target Party:"
+msgstr "Группа цели:"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+msgid "Target Guild:"
+msgstr "Гильдия цели:"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+msgid "Cursor:"
+msgstr "Курсор:"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr "Кол-во. объектов:"
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr "Пинг: %d мсек."
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr "Пинг: ? мсек."
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr "Вх.: %d байт/сек."
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr "Исх.: %d байт/сек."
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "ОК"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Снаряжение"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Снять"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Помощь"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Закрыть"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Инвентарь"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Хранение"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Вместимость:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Надеть"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Использовать"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+msgid "Drop..."
+msgstr "Бросить"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Разделить"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr "Наряды"
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Вес:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Сохранить"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Получить"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Бросить"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Всё"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Сколько предметов продать."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Сколько предметов сбросить."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Укажите количество вещей для хранения."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Укажите количество вещей для изъятия."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Сколько предметов разделить."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr "Добавить в список покупки."
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr "Добавить в список продажи."
+
+#: src/gui/itemamount.cpp:279
+msgid "Unknown."
+msgstr "Неизвестно."
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ","
+
+#: src/gui/itempopup.cpp:152
+#, c-format
+msgid "Weight: %s"
+msgstr "Вес: %s"
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+msgid "Kill stats"
+msgstr "Окно статистики атак"
+
+#: src/gui/killstats.cpp:61
+msgid "Reset stats"
+msgstr "Сбросить стат."
+
+#: src/gui/killstats.cpp:62
+msgid "Reset timer"
+msgstr "Сбросить таймер"
+
+#: src/gui/killstats.cpp:66
+msgid "Level: "
+msgstr "Уровень: "
+
+#: src/gui/killstats.cpp:70
+msgid "Exp: "
+msgstr "Опыт:"
+
+#: src/gui/killstats.cpp:71
+msgid " Left: "
+msgstr " Осталось: "
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr " опыта в сред. для 1%: ?"
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr "Фрагов: ?, Всего опыта: ?"
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr "Средний опыт: ?, кол-во монстров до след. уровня: ?"
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr "Убийств/Мин.: ?, Опыт/Мин.: ?"
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr "Опыт в минуту: ?"
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr "Время до след. уровня за одну минуту: ?"
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr "Опыт за 5 минут: ?"
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr "Время до след. уровня за 5 минут: ?"
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr "Опыт за 15 минут: ?"
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr "Время до след. уровня за 15 минут: ?"
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr "Опыт от последнего монстра: ?"
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr "Время до появляения Jacko: ?"
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr "Опыт за минуту: %d"
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr "Время до следующего уровня: %f"
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr "Время до следующего уровня: ?"
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr "Опыт за 5 минут: %d"
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr "Опыт за 15 минут: %d"
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr "Время до появляения Jacko: живой"
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr "Время до появляения Jacko: "
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr "?"
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr "Время до появляения Jacko: должен появится"
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr "Нормально"
+
+#: src/gui/login.cpp:57
+msgid "Auto Close"
+msgstr "Авт. закрыть"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr "Пропустить"
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Вход"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Сервер:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr "Польз. сайт обновлений"
+
+#: src/gui/login.cpp:106
+msgid "Remember username"
+msgstr "Запомнить логин"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr "Обновления:"
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Регистрация"
+
+#: src/gui/login.cpp:117
+msgid "Change Server"
+msgstr "Сменить сервер"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Карта"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr "Нужно"
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Ожидание ответа от сервера"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Следующий"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Применить"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+msgid "Clear"
+msgstr "Очистить"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+"\n"
+"> Следующий\n"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Для:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Отправить"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Невозможно послать ибо отправитель либо сообщение неверны."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr "Наряд: %d"
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, c-format
+msgid "Key: %s"
+msgstr "Клавиша: %s"
+
+#: src/gui/outfitwindow.cpp:83
+msgid "Unequip first"
+msgstr "Сначала снять"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Торговать@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Атаковать@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+msgid "@@whisper|Whisper@@"
+msgstr "@@whisper|Шептать@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+msgid "@@heal|Heal@@"
+msgstr "@@heal|Лечить@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+msgid "@@friend|Befriend@@"
+msgstr "@@friend|Подружиться@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Пренебреч@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+msgid "@@ignore|Ignore@@"
+msgstr "@@unignore|Игнорировать@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+msgid "@@erase|Erase@@"
+msgstr "@@erase|Стереть@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Не игнорировать@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Полностью игнорировать@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr "@@follow|Следовать@@"
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr "@@imitation|Имитация@@"
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+msgid "@@party|Invite to party@@"
+msgstr "@@party|Пригласить в группу@@"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+msgid "@@kick party|Kick from party@@"
+msgstr "@@kick party|Вышвырнуть из группы@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@guild-kick|Выкинуть из гильдии@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr "@@guild-pos|Сменить статус в гильдии >@@"
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+msgid "@@guild|Invite to guild@@"
+msgstr "@@guild|Пригласить в гильдию@@"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Вышвырнуть игрока@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr "@@nuke|Уничтожить@@"
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr "@@move|Двигаться@@"
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+msgid "@@undress|Undress@@"
+msgstr "@@undress|Раздеть@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr "@@buy|Купить@@"
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+msgid "@@sell|Sell@@"
+msgstr "@@sell|Продать@@"
+
+#: src/gui/popupmenu.cpp:226
+msgid "@@talk|Talk@@"
+msgstr "@@talk|Говорить@@"
+
+#: src/gui/popupmenu.cpp:240
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Вышвырнуть игрока@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Добавить имя в чат@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Отмена@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr "@@player_%u|%s >@@"
+
+#: src/gui/popupmenu.cpp:375
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Поднять@@"
+
+#: src/gui/popupmenu.cpp:376
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Добавить в чат@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr "Элмент карты"
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr "@@rename map|Переименовать@@"
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr "@@remove map|Удалить@@"
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr "@@load old outfits|Загрузить старые наряды@@"
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr "Заклинания"
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr "@@load old spells|Загрузить старые заклинания@@"
+
+#: src/gui/popupmenu.cpp:427
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@edit spell|Изменить заклинание@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr "@@chat close|Закрыть@@"
+
+#: src/gui/popupmenu.cpp:453
+msgid "Disable highlight"
+msgstr "Отключить уведомление"
+
+#: src/gui/popupmenu.cpp:459
+msgid "Enable highlight"
+msgstr "Включить уведомление"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr "@@leave party|Покинуть@@"
+
+#: src/gui/popupmenu.cpp:585
+msgid "Change guild position"
+msgstr "Сменить позицию в гильдии"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr "@@guild-pos-%d|%s@@"
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr "Переименовать знак на карте"
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr "Имя: "
+
+#: src/gui/popupmenu.cpp:1091
+msgid "Store 10"
+msgstr "Сохранить 10"
+
+#: src/gui/popupmenu.cpp:1094
+msgid "Store half"
+msgstr "Сохранить половину"
+
+#: src/gui/popupmenu.cpp:1096
+msgid "Store all"
+msgstr "Сохранить все"
+
+#: src/gui/popupmenu.cpp:1110
+msgid "Retrieve 10"
+msgstr "Получить 10"
+
+#: src/gui/popupmenu.cpp:1113
+msgid "Retrieve half"
+msgstr "Получить половину"
+
+#: src/gui/popupmenu.cpp:1115
+msgid "Retrieve all"
+msgstr "Получить все"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+msgid "Add to chat"
+msgstr "Добавить в чат"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr "Загрузить старые горячие клавиши предметов"
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr "Загрузить старые данные"
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr "Сохранить состояние"
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Сменить сервер"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Сменить персонажа"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Подтвердите:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Имя пользователя должно содержать не менее %d символов."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Имя пользователя не должно содержать более %d символов."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Пароль должен содержать не менее %d символов."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Пароль не должен содержать более %d символов."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Пароли не совпадают."
+
+#: src/gui/serverdialog.cpp:207
+msgid "Choose Your Server"
+msgstr "Выберите сервер"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Порт:"
+
+#: src/gui/serverdialog.cpp:223
+msgid "Server type:"
+msgstr "Тип:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr "Загрузить"
+
+#: src/gui/serverdialog.cpp:246
+msgid "Connect"
+msgstr "Соединится"
+
+#: src/gui/serverdialog.cpp:247
+msgid "Custom Server"
+msgstr "Добавить"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Следует указать адрес и порт сервера."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr "Получение списка серверов...%2.2f%%"
+
+#: src/gui/serverdialog.cpp:488
+msgid "Waiting for server..."
+msgstr "Ожидание ответа от сервера"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr "Подготовка к загрузке"
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr "Не удалось получить список серверов!"
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr "требуется более новая версия"
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr "требуется v%s"
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr "Включить Аудио"
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr "Включить игровые эффекты"
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr "Включить эффекты интерфейса"
+
+#: src/gui/setup_audio.cpp:49
+msgid "Enable music"
+msgstr "Включить музыку"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Enable mumble voice chat"
+msgstr "Включить голосовой чат mumble"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr "Скачать музыку"
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Аудио"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Громкость эффектов"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Громкость музыки"
+
+#: src/gui/setup_audio.cpp:117
+msgid "Notice"
+msgstr "Внимание"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+"Возможно потребуется перезагрузка игры, если вы хотите скачать новую музыку"
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr "Звуковой движок"
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr "Удалить цвета из полученных сообщений в чате"
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr "Оставлять сообщения магии на вкладке отладки"
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr "Разрешить магические и администраторские команды на всех вкладках"
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr "Показывать сообщения сервера на вкладке отладки"
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr "Включить лог чата"
+
+#: src/gui/setup_chat.cpp:88
+msgid "Enable trade tab"
+msgstr "Включить вкладки торговли"
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr "Скрыть сообщения магазина"
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr "Показать историю чата"
+
+#: src/gui/setup_chat.cpp:100
+msgid "Enable battle tab"
+msgstr "Включить вкладку боя"
+
+#: src/gui/setup_chat.cpp:104
+msgid "Show battle events"
+msgstr "Показать сообщения боя"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr "Показать список цветов чата"
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr "Изменить"
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr "Ограничить число символов в строке чата"
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr "Ограничить число строк в чате"
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Вот, как выглядит сей цвет"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Цвета"
+
+#: src/gui/setup_colors.cpp:72
+msgid "Type:"
+msgstr "Введите: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Статичный"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Пульсирующий"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Радуга"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Спектр"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+msgid "Delay:"
+msgstr "Задержка:"
+
+#: src/gui/setup_colors.cpp:109
+msgid "Red:"
+msgstr "Красный:"
+
+#: src/gui/setup_colors.cpp:124
+msgid "Green:"
+msgstr "Зеленый:"
+
+#: src/gui/setup_colors.cpp:139
+msgid "Blue:"
+msgstr "Синий:"
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr "Прозрачность:"
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Применить"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Сбросить расположение окон"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Нажмите кнопку, чтобы начать калибровку"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Калибровать"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Использовать джойстик"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Джойстик"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Стоп"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Вращайте рукоять"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Клавиатура"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Назначить"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Unassign"
+msgstr "Снять назначение"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "По умолчанию"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Обнаружен(ы) конфликт(ы) клавиш!"
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr "Разное"
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr "Показ. повр. нанесенные монстрам"
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr "Автоприцел по доступным монстрам"
+
+#: src/gui/setup_other.cpp:104
+msgid "Highlight map portals"
+msgstr "Подсветка точек перехода на карте"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr "Подсветка радиуса атаки игрока"
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr "Подсветка радиуса атаки монстров"
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr "Прокручивать прицел по игрокам"
+
+#: src/gui/setup_other.cpp:121
+msgid "Cycle monster targets"
+msgstr "Прокручивать прицел по монстрам"
+
+#: src/gui/setup_other.cpp:124
+msgid "Enable bot checker"
+msgstr "Включить детектор ботов"
+
+#: src/gui/setup_other.cpp:127
+msgid "Highlight floor items"
+msgstr "Подсветка предметов на полу"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+msgid "Enable shop mode"
+msgstr "Включить режим магазина"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr "Включить защиту от сбойных серверов"
+
+#: src/gui/setup_other.cpp:149
+msgid "Enable debug log"
+msgstr "Включить отлад. лог"
+
+#: src/gui/setup_other.cpp:153
+msgid "Enable server side attack"
+msgstr "Включить серверную атаку"
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr "Авто. исправ. позиции"
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr "Атаковать в движении"
+
+#: src/gui/setup_other.cpp:165
+msgid "Enable quick stats"
+msgstr "Включить быструю смену статов"
+
+#: src/gui/setup_other.cpp:169
+msgid "Show warps particles"
+msgstr "Показывать анимацию порталов"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr "Принимать запросы купить/продать"
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr "Показывать жизнь мобов"
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Отношение"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Нейтральное"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Друг"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Пренебрегаемый"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Игнорировано"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr "Стерт"
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Разрешить торговлю"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Разрешить шептание"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr "Старые"
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Личные сообщения во вкладках"
+
+#: src/gui/setup_players.cpp:248
+msgid "Show gender"
+msgstr "Показать пол"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Игроки"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Когда игнорируется:"
+
+#: src/gui/setup_players.cpp:301
+msgid "Show level"
+msgstr "Показать уровень"
+
+#: src/gui/setup_players.cpp:305
+msgid "Show own name"
+msgstr "Показать свое имя"
+
+#: src/gui/setup_players.cpp:309
+msgid "Target dead players"
+msgstr "Наводить фокус на мертвых игроков"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr "Тема"
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr "Тема интерфейса"
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr "Основной шрифт"
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr "Жирный шрифт"
+
+#: src/gui/setup_theme.cpp:112
+msgid "Particle font"
+msgstr "Шрифт частиц"
+
+#: src/gui/setup_theme.cpp:113
+msgid "Help font"
+msgstr "Шрифт помощи"
+
+#: src/gui/setup_theme.cpp:223
+msgid "Theme Changed"
+msgstr "Тема изменена"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Перезегрузите игру дабы изменения вступили в силу."
+
+#: src/gui/setup_video.cpp:143
+msgid "Tiny (10)"
+msgstr "Маленький (10)"
+
+#: src/gui/setup_video.cpp:144
+msgid "Small (11)"
+msgstr "Маленький (11)"
+
+#: src/gui/setup_video.cpp:145
+msgid "Medium (12)"
+msgstr "Средний (12)"
+
+#: src/gui/setup_video.cpp:146
+msgid "Large (13)"
+msgstr "Большой (13)"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr "Боьшой (14)"
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr "Огромный (15)"
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr "Программно"
+
+#: src/gui/setup_video.cpp:172
+msgid "Fast OpenGL"
+msgstr "Быстрая OpenGL"
+
+#: src/gui/setup_video.cpp:173
+msgid "Safe OpenGL"
+msgstr "Бозпасная OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Нет текста"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Текст"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Пузырьки, без названий"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Пузырьки с названиями"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "выкл"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "низ."
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "выс."
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "средне"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "макс."
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "На полный экран"
+
+#: src/gui/setup_video.cpp:277
+msgid "Hw acceleration"
+msgstr "Аппаратное ускорение"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Игровой курсор"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Видимые имена"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Эффекты частиц"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr "Сохранять текст NPC"
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Показать уведомление о подборе предмета"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "в чате"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "как частицу"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr "Спрятать картинку счита"
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr "Режим экономии"
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr "Синх. движение"
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr "Рисовать клавищи на карте"
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr "Рисовать путь"
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr "Показывать уровень работы"
+
+#: src/gui/setup_video.cpp:301
+msgid "Enable opacity cache"
+msgstr "Включить кеш прозрачности"
+
+#: src/gui/setup_video.cpp:302
+msgid "Show background"
+msgstr "Показать фон"
+
+#: src/gui/setup_video.cpp:307
+msgid "FPS limit:"
+msgstr "Ограничить кадр/с:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+msgid "Alt FPS limit: "
+msgstr "Альтер. ограничить кадр/с: "
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Видео"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Текст над головами"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Непрозрачность интерфейса"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Эффекты окружающей среды"
+
+#: src/gui/setup_video.cpp:329
+msgid "Particle detail"
+msgstr "Детализация частиц"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Размер шрифта"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+msgid "None"
+msgstr "Нет"
+
+#: src/gui/setup_video.cpp:528
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+"Не удалось переключиться в оконный режим. Восстановить старый режим также не "
+"удалось!"
+
+#: src/gui/setup_video.cpp:534
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+"Не удалось переключиться в полноэкранный режим. Восстановить старый режим "
+"также не удалось!"
+
+#: src/gui/setup_video.cpp:545
+msgid "Switching to Full Screen"
+msgstr "Переключение в полноэкранный режим"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Для вступления в силу выбранных настроек требуется перезагрузка игры."
+
+#: src/gui/setup_video.cpp:558
+msgid "Changing to OpenGL"
+msgstr "Переключение на OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Переход к OpenGL требует перезагрузки игры."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr "Свое разрешение (например: 1024х768)"
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr "Новое разрешение: "
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+msgid "Screen Resolution Changed"
+msgstr "Разрешение экрана изменено"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+"Некоторые окна могут быть сдвинуты, чтобы уместиться на экране при меньшем "
+"разрешении"
+
+#: src/gui/setup_video.cpp:750
+msgid "Particle Effect Settings Changed."
+msgstr "Настройки эффектов частиц изменены."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Изменения вступят в силу после загрузки новой карты."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr "Свой магазин"
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr "Купить"
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr "Продать"
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Добавить"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr "Анонс"
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr "Показывать ссылки"
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Запрос на Торговлю"
+
+#: src/gui/shopwindow.cpp:707
+#, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s хочет %s %s, вы принимаете предложение?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Умения"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Верх"
+
+#: src/gui/skilldialog.cpp:290
+#, c-format
+msgid "Skill points available: %d"
+msgstr "Очков навыков осталось: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Очков навыков: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, c-format
+msgid "Skill %d"
+msgstr "Умение %d"
+
+#: src/gui/skilldialog.cpp:469
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Уровень: %d (%+d)"
+
+#: src/gui/skilldialog.cpp:477
+#, c-format
+msgid "Lvl: %d"
+msgstr "Уровень: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Гильдия"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr "Пользователь %s приглашен в гильдию %s."
+
+#: src/gui/socialwindow.cpp:157
+#, c-format
+msgid "Guild %s quit requested."
+msgstr "Выход из гильдии %s запрошен."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr "Приглашение игрока в Гильдию"
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr "Кого вы хотите пригласить в гильдию %s?"
+
+#: src/gui/socialwindow.cpp:194
+msgid "Leave Guild?"
+msgstr "Покинуть Гильдию?"
+
+#: src/gui/socialwindow.cpp:195
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Вы действительно хотите выйти из гильдии %s?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Группа"
+
+#: src/gui/socialwindow.cpp:240
+#, c-format
+msgid "Invited user %s to party."
+msgstr "Пригласить пользователя %s в группу."
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr "Запрошен выход из группы %s."
+
+#: src/gui/socialwindow.cpp:281
+msgid "Member Invite to Party"
+msgstr "Пригласить пользователя в группу"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr "Кого вы хотите пригласить в группу %s?"
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr "Покинуть группу?"
+
+#: src/gui/socialwindow.cpp:292
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Вы действительно хотите покинуть группу %s?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr "Нав"
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Создать Гильдию"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+msgid "Create Party"
+msgstr "Создать группу"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr "Общество"
+
+#: src/gui/socialwindow.cpp:847
+msgid "Invite"
+msgstr "Пригласить"
+
+#: src/gui/socialwindow.cpp:848
+msgid "Leave"
+msgstr "Покинуть"
+
+#: src/gui/socialwindow.cpp:975
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr "Принято приглашение в группу от %s."
+
+#: src/gui/socialwindow.cpp:985
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr "Отклонено приглашение в группу от %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Принято приглашение в гильдию от %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Отклонено приглашение в гильдию от %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, c-format
+msgid "Creating guild called %s."
+msgstr "Создание гильдии с именем %s."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr "Создание группы с именем %s."
+
+#: src/gui/socialwindow.cpp:1093
+msgid "Guild Name"
+msgstr "Имя гильдии"
+
+#: src/gui/socialwindow.cpp:1094
+msgid "Choose your guild's name."
+msgstr "Выберите имя для гильдии."
+
+#: src/gui/socialwindow.cpp:1108
+msgid "Received guild request, but one already exists."
+msgstr "Получено приглашение в гильдию, но оно не первое."
+
+#: src/gui/socialwindow.cpp:1114
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s приглашает присоединиться к гильдии %s."
+
+#: src/gui/socialwindow.cpp:1120
+msgid "Accept Guild Invite"
+msgstr "Принять приглашение в гильдию"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Получено приглашение в группу, но оно не порвое."
+
+#: src/gui/socialwindow.cpp:1146
+msgid "You have been invited you to join a party."
+msgstr "Вас приглашают в группу."
+
+#: src/gui/socialwindow.cpp:1150
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr "Вас приглашают присоединиться к группе %s."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s приглашает вас к себе в группу."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s приглашает присоединиться к %s группе."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Принять приглашение в группу"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr "Не удалось создать группу. Вы уже состоите в другой."
+
+#: src/gui/socialwindow.cpp:1192
+msgid "Party Name"
+msgstr "Имя группы"
+
+#: src/gui/socialwindow.cpp:1193
+msgid "Choose your party's name."
+msgstr "Выберите имя будущей группы."
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Уровень: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Деньги: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "ОЖ:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "Мана:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Профессия: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Профессия:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, c-format
+msgid "Character points: %d"
+msgstr "Очки персонажа: %d"
+
+#: src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Уровень: %d (GM %d)"
+
+#: src/gui/statuswindow.cpp:299
+#, c-format
+msgid "Correction points: %d"
+msgstr "Очков навыков: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+msgid "No Target"
+msgstr "Без цели"
+
+#: src/gui/textcommandeditor.cpp:110
+msgid "Allow Target"
+msgstr "Разрешить цель"
+
+#: src/gui/textcommandeditor.cpp:111
+msgid "Need Target"
+msgstr "Необходима цель"
+
+#: src/gui/textcommandeditor.cpp:116
+msgid "General Magic"
+msgstr "Общая Магия"
+
+#: src/gui/textcommandeditor.cpp:117
+msgid "Life Magic"
+msgstr "Магия Жизни"
+
+#: src/gui/textcommandeditor.cpp:118
+msgid "War Magic"
+msgstr "Боевая Магия"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr "Магия Трансформации"
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr "Магия Природы"
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr "Астральная магия"
+
+#: src/gui/textcommandeditor.cpp:164
+msgid "Command Editor"
+msgstr "Редактор комманд"
+
+#: src/gui/textcommandeditor.cpp:181
+msgid "magic"
+msgstr "Магия"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr "Другое"
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr "Символ:"
+
+#: src/gui/textcommandeditor.cpp:193
+msgid "Command:"
+msgstr "Команда:"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr "Мана:"
+
+#: src/gui/textcommandeditor.cpp:201
+msgid "Target Type:"
+msgstr "Тип цели:"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr "Картинка:"
+
+#: src/gui/textcommandeditor.cpp:212
+msgid "Magic level:"
+msgstr "Уровень Магии:"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr "Школа Магии:"
+
+#: src/gui/textcommandeditor.cpp:223
+msgid "School level:"
+msgstr "Уровень школы:"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr "Сохранить"
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Предложить торговлю"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Подтверждено. Ждем-с..."
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Подтвердить торговлю"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Подтверждено. Ждем-с..."
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Торговля: Вы"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Торговать"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, c-format
+msgid "You get %s"
+msgstr "Вы получаете %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Вы отдаете:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Сменить"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "У вас недостаточно денег"
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Имя: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Обновление..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Соединение..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Играть"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Процесс обновления не завершен!"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Настоятельно рекомендуется"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+msgid "##1 you try again later."
+msgstr "##1 попытаться еще раз немного погодя."
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Завершено"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Существо"
+
+#: src/gui/userpalette.cpp:110
+msgid "Friend Names"
+msgstr "Имена Друзей"
+
+#: src/gui/userpalette.cpp:111
+msgid "Disregarded Names"
+msgstr ""
+
+#: src/gui/userpalette.cpp:112
+msgid "Ignored Names"
+msgstr "Игнорируемые имена"
+
+#: src/gui/userpalette.cpp:113
+msgid "Erased Names"
+msgstr "Стертые имена"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Имена других игроков"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Собственное имя"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "Имена ГМ"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "Боты"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Монстры"
+
+#: src/gui/userpalette.cpp:119
+msgid "Monster HP bar"
+msgstr "Полоса жизни монстров"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr "Полоса жизни монстров (второй цвет)"
+
+#: src/gui/userpalette.cpp:122
+msgid "Party Members"
+msgstr "Члены группы"
+
+#: src/gui/userpalette.cpp:123
+msgid "Guild Members"
+msgstr "Члены гильдии"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Эффекты частиц"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Сообщение о подборе предмета"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "Сообщение об изменении опыта"
+
+#: src/gui/userpalette.cpp:127
+msgid "Player Hits Monster"
+msgstr "Удары игрока по монстру"
+
+#: src/gui/userpalette.cpp:128
+msgid "Monster Hits Player"
+msgstr "Удары монстра по игроку"
+
+#: src/gui/userpalette.cpp:130
+msgid "Other Player Hits Local Player"
+msgstr "Другой игрок бъет локального игрока"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Критический удар"
+
+#: src/gui/userpalette.cpp:133
+msgid "Local Player Hits Monster"
+msgstr "Удары игроков вокруг по монстру"
+
+#: src/gui/userpalette.cpp:135
+msgid "Local Player Critical Hit"
+msgstr "Критический удар игрока"
+
+#: src/gui/userpalette.cpp:137
+msgid "Local Player Miss"
+msgstr "Промах соседнего игрока"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Промахи"
+
+#: src/gui/userpalette.cpp:139
+msgid "Portal Highlight"
+msgstr "Подсветка переходов"
+
+#: src/gui/userpalette.cpp:141
+msgid "Collision Highlight"
+msgstr "Подсветка столкновений"
+
+#: src/gui/userpalette.cpp:143
+msgid "Walkable Highlight"
+msgstr "Подсветка доступных участков карты"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr "Зона атаки соседнего игрока"
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr "Граница зоны атаки соседнего игрока"
+
+#: src/gui/userpalette.cpp:149
+msgid "Monster Attack Range"
+msgstr "Зона атаки монстра"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr "Домашняя позиция"
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr "Бордюр домашней позиции"
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr "Точка дороги"
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr "Кто онлайн - обновление"
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr "Обновить"
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr "Кто онлайн - "
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr "Кто онлайн - ошибка"
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr "Кто онлайн - обновление"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Список пользователей текущего канала"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Задать тему текущего канала"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Покинуть канал"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Сделать пользователя оператором канала"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Вышвырнуть пользователя с канала"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Комманды: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Эта Команда показывает пользователей канала"
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Команда: /topic <сообщение>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Задает тему для <сообщение>."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Команда: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Команда покидает текущий канал"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Если вы - последний пользователь канала, канал будет удален"
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Команда: /op <имя>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Эта Команда делает <пользователь> оператором канала."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Операторы канала могут вышвыривать пользователей и делать их операторами."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Команда: /kick <ник>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Эта команда заставляет <ник> покинуть канал."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Нужно выбрать пользователя!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Глобальное объявление:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Глобальное объявление от %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, c-format
+msgid "%s whispers: %s"
+msgstr "%s шепчет: %s"
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr "/ignore > Игнорировать другого игрока"
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr "/unignore > Перестать игнорировать другого игрока"
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Закрыть вкладку перешептывания"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Команда: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Закрывает вкладку перешептывания"
+
+#: src/gui/widgets/whispertab.cpp:121
+msgid "Command: /ignore"
+msgstr "Команда: /ignore"
+
+#: src/gui/widgets/whispertab.cpp:122
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+"Эта команда позволяет игнорировать другого игрока вне зависимости от текущих "
+"отношений с ним."
+
+#: src/gui/widgets/whispertab.cpp:128
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "Эта команда прекращает игнорирование другого игрока."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr "ДБ"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Bot checker"
+msgstr "Окно детектора ботов"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr "Кто онлайн"
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+msgid "Smiles"
+msgstr "Смайлы"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Состояние"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "Shortcuts"
+msgstr "Горячие клавиши"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+msgid "Select World"
+msgstr "Выбрать Сервер"
+
+#: src/gui/worldselectdialog.cpp:79
+msgid "Change Login"
+msgstr "Сменить логин"
+
+#: src/gui/worldselectdialog.cpp:80
+msgid "Choose World"
+msgstr "Выберите сервер"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Двигаться вверх"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Двигаться вниз"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Двигаться влево"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Двигаться вправо"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Прицелиться и атаковать"
+
+#: src/keyboardconfig.cpp:48
+msgid "Move to Target"
+msgstr "Двигаться к цели"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr "Изменить тип движения и атаки"
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr "Идти к Домашней локации"
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr "Установить домашнюю локацию"
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr "Двигаться к позиции"
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Улыбнуться"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Прекратить атаку"
+
+#: src/keyboardconfig.cpp:61
+msgid "Target Closest"
+msgstr "Прицелиться в ближайшего"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Прицелиться на NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Прицелиться на игрока"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Поднять"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr "Изменить тип подбора предметов"
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Скрыть окна"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Сесть"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Сделать скриншот"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Разрешить/Запретить торговлю"
+
+#: src/keyboardconfig.cpp:74
+msgid "Change Map View Mode"
+msgstr "Изменяет режим отображения карты"
+
+#: src/keyboardconfig.cpp:76
+msgid "Item Shortcuts Key"
+msgstr "Горячие клавиши предмета"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Комбинация клавиш предмета %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Окно помощи"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Окно статуса"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Окно инвентаря"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Окно екипировки"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Окно навыков"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Окно мини-карты"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Окно чата"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Окно комбинаций клавиш предметов"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Окно настроек"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Окно отладки"
+
+#: src/keyboardconfig.cpp:136
+msgid "Social Window"
+msgstr "Окно общества"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Окно емоций"
+
+#: src/keyboardconfig.cpp:140
+msgid "Outfits Window"
+msgstr "Окно костюмов"
+
+#: src/keyboardconfig.cpp:142
+msgid "Shop Window"
+msgstr "Окно магазина"
+
+#: src/keyboardconfig.cpp:143
+msgid "Quick drop Window"
+msgstr "Окно быстрого бросания предметов"
+
+#: src/keyboardconfig.cpp:145
+msgid "Kills Stats Window"
+msgstr "Окно статистики атак"
+
+#: src/keyboardconfig.cpp:147
+msgid "Commands Window"
+msgstr "Окно комманд"
+
+#: src/keyboardconfig.cpp:149
+msgid "Bot Checker Window"
+msgstr "Окно детектора ботов"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr "Окно кто онлайн"
+
+#: src/keyboardconfig.cpp:154
+msgid "Previous Social Tab"
+msgstr "Предыдущая закладка общества"
+
+#: src/keyboardconfig.cpp:155
+msgid "Next Social Tab"
+msgstr "Следующая закладка общества"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Комбинация клавиш для емоции %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr "Одеть наряд"
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr "Скопировать наряд"
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr "Копировать одетый наряд"
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Переключится на чат"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Прокрутить чат вверх"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Прокрутить чат вниз"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Предыдущая закладка чата"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Следующая закладка чата"
+
+#: src/keyboardconfig.cpp:262
+msgid "Previous chat tab line"
+msgstr "Предыдущая строка вкладки"
+
+#: src/keyboardconfig.cpp:264
+msgid "Next chat tab line"
+msgstr "Следующая строка вкладки"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr "Автозавершение в чате"
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr "Отключить фокус ввода"
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Выбрать Ok"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Игнорировать ввод 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Игнорировать ввод 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr "Вверх"
+
+#: src/keyboardconfig.cpp:277
+msgid "Direct Down"
+msgstr "Вниз"
+
+#: src/keyboardconfig.cpp:279
+msgid "Direct Left"
+msgstr "Влево"
+
+#: src/keyboardconfig.cpp:280
+msgid "Direct Right"
+msgstr "Вправо"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr "Быстрое лечения себя или цели"
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr "Использовать заклинание #itenplz"
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr "Использовать магическую атаку"
+
+#: src/keyboardconfig.cpp:298
+msgid "Switch magic attack"
+msgstr "Переключить маг. атаку"
+
+#: src/keyboardconfig.cpp:300
+msgid "Change move type"
+msgstr "Изменить тип движения"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr "Изменить тип атаки оружием"
+
+#: src/keyboardconfig.cpp:304
+msgid "Change Attack Type"
+msgstr "Изменить тип атаки"
+
+#: src/keyboardconfig.cpp:306
+msgid "Change Follow mode"
+msgstr "Изменить режим следования"
+
+#: src/keyboardconfig.cpp:308
+msgid "Change Imitation mode"
+msgstr "Сменить режим имитации"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr "Запретить / Разрешить специальные модификаторы"
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr "Вкл. / Выкл. звук"
+
+#: src/keyboardconfig.cpp:314
+msgid "Enable / Disable away mode"
+msgstr "Включить / Выключить режим отошел"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr "Эмуляция правого клика с клавиатуры"
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr "Изменить режим камеры"
+
+#: src/keyboardconfig.cpp:380
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+"Конфликт клавиш \"%s\" и \"%s\".Исправьте их, или игра может себя странно "
+"вести."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr "Вы были убиты "
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Невозможно подобрать предмет"
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr "Отошел"
+
+#: src/localplayer.cpp:3617
+msgid "You see "
+msgstr "Вы видите "
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr "manaplus [опции] [файлы]"
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr "[mana-file] : Мана-файл - это XML-файл (.mana)"
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr "используется для назначения своих параметров"
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr " клиента"
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Опции:"
+
+#: src/main.cpp:50
+msgid " -l --log-file : Log file to use"
+msgstr " -l --log-file : Использовать указанный файл как лог"
+
+#: src/main.cpp:51
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -L --chat-log-dir : Использовать указанный каталог для лога"
+
+#: src/main.cpp:52
+msgid " -v --version : Display the version"
+msgstr " -v --version : Показать версию"
+
+#: src/main.cpp:53
+msgid " -h --help : Display this help"
+msgstr " -h --help : Показать эту справку"
+
+#: src/main.cpp:54
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-dir : Использовать указанный каталог конфигурации"
+
+#: src/main.cpp:55
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Войти с указанным логином"
+
+#: src/main.cpp:56
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Войти с указанным паролем"
+
+#: src/main.cpp:57
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Использовать указанный персонаж"
+
+#: src/main.cpp:58
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Имя или IP сервера авторизации"
+
+#: src/main.cpp:59
+msgid " -p --port : Login server port"
+msgstr " -p --port : Порт сервера авторизации"
+
+#: src/main.cpp:60
+msgid " --update-host : Use this update host"
+msgstr " --update-host : Использовать этот узел обновлений"
+
+#: src/main.cpp:61
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+" -D --default : Выбрать персонаж и сервер персонажей по умолчанию"
+
+#: src/main.cpp:63
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Пропустить обновление"
+
+#: src/main.cpp:64
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Загрузить игровые данные из этого каталога"
+
+#: src/main.cpp:66
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -L --localdata-dir : Каталог для локальных данных"
+
+#: src/main.cpp:68
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " --screenshot-dir : Сохранять скриншоты в указанном каталоге"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr " --safemode : Запуск игры в безопасном режиме"
+
+#: src/main.cpp:71
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " --no-opengl : Не использовать OpenGL для этой сессии"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Сила (str)"
+
+#: src/net/manaserv/attributes.cpp:166
+#, c-format
+msgid "Strength %+.1f"
+msgstr "Сила (str) %+.1f"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Выносливость (agi)"
+
+#: src/net/manaserv/attributes.cpp:179
+#, c-format
+msgid "Agility %+.1f"
+msgstr "Выносливость (agi) %+.1f"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Ловкость (dex)"
+
+#: src/net/manaserv/attributes.cpp:192
+#, c-format
+msgid "Dexterity %+.1f"
+msgstr "Ловкость (dex) %+.1f"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Живучесть (vit)"
+
+#: src/net/manaserv/attributes.cpp:205
+#, c-format
+msgid "Vitality %+.1f"
+msgstr "Живучесть (vit) %+.1f"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Интеллект (int)"
+
+#: src/net/manaserv/attributes.cpp:218
+#, c-format
+msgid "Intelligence %+.1f"
+msgstr "Интеллект (int) %+.1f"
+
+#: src/net/manaserv/attributes.cpp:224
+msgid "Willpower"
+msgstr "Воля"
+
+#: src/net/manaserv/attributes.cpp:231
+#, c-format
+msgid "Willpower %+.1f"
+msgstr "Воля (wil) %+.1f"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Вы мертвы."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "С грустью сообщаем вам, что ваш персонаж пал в бою."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Вас боьше нет среди живых."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Холодные руки Смерти извлекают вашу душу."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Игра Окончена!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Нет, детки. Ваш персонаж на самом деле не умер. Он...эммм...ушел в лучший "
+"мир."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr "Ваш план сломать оружие врагов об свое горло провалился."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Похоже, это было не слишком хорошо."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Хочешь предскажу твою судьбу?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Грустно, вас врятли когда-нибудь найдут..."
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Уничтожен."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:336
+msgid "Press OK to respawn."
+msgstr "Нажмите ОК, чтобы возродиться."
+
+#: src/net/manaserv/beinghandler.cpp:337
+msgid "You Died"
+msgstr "Вы умерли"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+msgid "Not logged in."
+msgstr "Не авторизован."
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr "Нет свободного места."
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr "Имя задано неверно"
+
+#: src/net/manaserv/charhandler.cpp:153
+msgid "Character's name already exists."
+msgstr "Персонаж с таким именем уже существует"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr "Прическа выбрана неверно."
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr "Цвет волос выбран неверно."
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr "Пол выбран неверно."
+
+#: src/net/manaserv/charhandler.cpp:165
+msgid "Character's stats are too high."
+msgstr "Характеристики персонажа слишком велики."
+
+#: src/net/manaserv/charhandler.cpp:168
+msgid "Character's stats are too low."
+msgstr "Характеристики персонажа слишком малы."
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+msgid "Unknown error."
+msgstr "Неизвестная ошибка."
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Сведения"
+
+#: src/net/manaserv/charhandler.cpp:206
+msgid "Player deleted."
+msgstr "Игрок удален."
+
+#: src/net/manaserv/charhandler.cpp:218
+msgid "Selection out of range."
+msgstr "Выбор вне допустимого предела."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, c-format
+msgid "Unknown error (%d)."
+msgstr "Неизвестная ошибка (%d)."
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Доступные игровые серверы не найдены"
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Тема: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+msgid "Players in this channel:"
+msgstr "Игроки на канале:"
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Error joining channel."
+msgstr "Ошибка подключения к каналу."
+
+#: src/net/manaserv/chathandler.cpp:213
+msgid "Listing channels."
+msgstr "Список каналов."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr "Конец списка каналов."
+
+#: src/net/manaserv/chathandler.cpp:298
+#, c-format
+msgid "%s entered the channel."
+msgstr "%s зашел на канал."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr "%s покинул канал."
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr "%s установил режим %s для пользователя %s"
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr "%s был вышвырнут %s"
+
+#: src/net/manaserv/chathandler.cpp:336
+msgid "Unknown channel event."
+msgstr "Неизвестное событие на канале."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Гильдия создана."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Ошибка создания гильдии"
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Приглашение отправлено"
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Член гильдии успешно повышен."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Не удалось повысить члена гильдии."
+
+#: src/net/manaserv/loginhandler.cpp:89
+msgid "Wrong magic_token."
+msgstr "Ошибочный magic_token."
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+msgid "Already logged in."
+msgstr "Уже в сети."
+
+#: src/net/manaserv/loginhandler.cpp:95
+msgid "Account banned."
+msgstr "Учетная запись заблокирована (бан)."
+
+#: src/net/manaserv/loginhandler.cpp:120
+msgid "New password incorrect."
+msgstr "Новый пароль указан неверно"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+msgid "Old password incorrect."
+msgstr "Старый пароль указан неверно."
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Вы не вошли под своим именем. Пожалуйста, авторизуйтесь"
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "New email address incorrect."
+msgstr "Новый адрес E-mail указан неверно."
+
+#: src/net/manaserv/loginhandler.cpp:155
+msgid "Old email address incorrect."
+msgstr "Старый адрес E-mail указан неверно."
+
+#: src/net/manaserv/loginhandler.cpp:163
+msgid "The new email address already exists."
+msgstr "Введенный адрес E-mail уже зарегистрирован."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+"Регистрация из клиента запрещена. Пожалуйста, свяжитесь с администрацией "
+"сервера."
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+msgid "Client version is too old."
+msgstr "Версия клиент-программы устарела."
+
+#: src/net/manaserv/loginhandler.cpp:273
+msgid "Wrong username or password."
+msgstr "Неверное имя пользователя или пароль."
+
+#: src/net/manaserv/loginhandler.cpp:279
+msgid "Account banned"
+msgstr "Учетная запись заблокирована (бан)."
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+"С вашей предыдущей попытки авторизации прошло слишком мало времени, "
+"попробуйте позже."
+
+#: src/net/manaserv/loginhandler.cpp:310
+msgid "Wrong username, password or email address."
+msgstr "Неверное имя пользователя, пароль или адрес E-mail."
+
+#: src/net/manaserv/loginhandler.cpp:313
+msgid "Username already exists."
+msgstr "Пользователь с таким именем уже существует."
+
+#: src/net/manaserv/loginhandler.cpp:316
+msgid "Email address already exists."
+msgstr "Введенный адрес E-mail уже зарегистрирован."
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr "Вы слишко долго проходили проверку или ваш ответ неверный."
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Присоединился к группе."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s теперь в группе."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, c-format
+msgid "%s rejected your invite."
+msgstr "%s Отклонил(а) ваше приглашение."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Принимать входящие предложения торговли."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Игнорировать входящие предложения торговли."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s хочет торговать с вами, вы принимаете предложение?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Торговля с %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Торговля отменена."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Торговля завершена."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Не удалось вышвырнуть!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Игрок вышвырнут!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Нечего продавать..."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Спасибо за покупку!"
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Низзя купить!"
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Спасибо за продажу!"
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Нельзя продать."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+"В доступе отказано. Скорее всего на этом сервере слишком много игроков."
+
+#: src/net/tmwa/charserverhandler.cpp:110
+msgid "Cannot use this ID."
+msgstr "Нельзя использовать данный ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+msgid "Unknown char-server failure."
+msgstr "Неизвестная ошибка сервера чата."
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Невозможно создать персонажа. Скорее всего, таке имя уже используется."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Персонаж удален"
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Невозможно удалить персонажа."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Сила (str):"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Выносливость (agi):"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Живучесть (vit):"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Интеллект (int):"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Ловкость (dex):"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Удача (luk):"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Сообщение не может быть отправлено, %s оффлайн"
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Низзя прошептать: пользователь игнорирует шептание..."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Игрок."
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Игрок."
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Каналы не поддерживаются!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr "Пользователи Онлайн: %d"
+
+#: src/net/tmwa/gamehandler.cpp:102
+msgid "Game"
+msgstr "Игра"
+
+#: src/net/tmwa/gamehandler.cpp:102
+msgid "Request to quit denied!"
+msgstr "Запрос на выход отклонен!"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Сила (str) %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Выносливость (agi) %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Живучесть (vit) %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Интеллект (int) %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Ловкость (dex) %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Удача (luk) %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+msgid "Authentication failed."
+msgstr "Ошибка авторизации"
+
+#: src/net/tmwa/generalhandler.cpp:138
+msgid "No servers available."
+msgstr "Нет доступных серверов."
+
+#: src/net/tmwa/generalhandler.cpp:142
+msgid "Someone else is trying to use this account."
+msgstr "Кто-то еще пытается воспользоваться данным аккаунтом"
+
+#: src/net/tmwa/generalhandler.cpp:145
+msgid "This account is already logged in."
+msgstr "Этот аккаунт уже в сети."
+
+#: src/net/tmwa/generalhandler.cpp:148
+msgid "Speed hack detected."
+msgstr "Обнаружен взлом скорости."
+
+#: src/net/tmwa/generalhandler.cpp:151
+msgid "Duplicated login."
+msgstr "Двойная попытка подключения"
+
+#: src/net/tmwa/generalhandler.cpp:154
+msgid "Unknown connection error."
+msgstr "Неизвестная ошибка подключения."
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Отключено от сервера!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Удача (luk)"
+
+#: src/net/tmwa/generalhandler.cpp:255
+msgid "Defense"
+msgstr "Защита"
+
+#: src/net/tmwa/generalhandler.cpp:256
+msgid "M.Attack"
+msgstr "Маг. Атака"
+
+#: src/net/tmwa/generalhandler.cpp:257
+msgid "M.Defense"
+msgstr "Маг.Защита"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Точности"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Уклонения"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "% Критический удар"
+
+#: src/net/tmwa/generalhandler.cpp:261
+msgid "Attack Delay"
+msgstr "Задержка атаки"
+
+#: src/net/tmwa/generalhandler.cpp:263
+msgid "Walk Delay"
+msgstr "Задержка движения"
+
+#: src/net/tmwa/generalhandler.cpp:265
+msgid "Attack Range"
+msgstr "Зона атаки"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Показать эту справку"
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Пригласить игрока в вашу гиьдию"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Покинуть текущую гильдию"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Вышвырнуть кого-либо из вашей текущей группы"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Команда: /invite <игрок>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Эта команда приглашает <имя персонажа> к вам в группу."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Команда: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+msgid "This command causes the player to leave the guild."
+msgstr "Эта Команда заставляет игрока покинуть гильдию."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+msgid "You already in guild."
+msgstr "Вы и так в гильдии"
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+msgid "Unknown server response."
+msgstr "Неизвестный ответ сервера."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, c-format
+msgid "Guild name: %s"
+msgstr "Имя гильдии: %s"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, c-format
+msgid "Guild master: %s"
+msgstr "Мастер гильдии: %s"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, c-format
+msgid "Guild level: %d"
+msgstr "Уровень гильдии: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr "Пользователи онлайн: %d"
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr "Макс. членов: %d"
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, c-format
+msgid "Average level: %d"
+msgstr "Средний уровень: %d"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, c-format
+msgid "Guild exp: %d"
+msgstr "Опыт гильдии: %d"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, c-format
+msgid "Guild next exp: %d"
+msgstr "Нужно опыта до следующего уровня: %d"
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, c-format
+msgid "Guild castle: %s"
+msgstr "Замки: %s"
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr "Не удаось пригласить пользователя в гиьдию."
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr "Пользователь отклонил приглашение."
+
+#: src/net/tmwa/guildhandler.cpp:443
+msgid "User is now part of your guild."
+msgstr "Пользователь теперь в вашей гильдии."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr "Ваша гильдия полна."
+
+#: src/net/tmwa/guildhandler.cpp:453
+msgid "Unknown guild invite response."
+msgstr "Неизвестный ответ на приглашение в гильдию."
+
+#: src/net/tmwa/guildhandler.cpp:475
+msgid "You have left the guild."
+msgstr "Вы покинули гильдию."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, c-format
+msgid "%s has left your guild."
+msgstr "%s покинул вашу гильдию."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr "Вы были кикнуты из гильдии."
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s был вышвырнут и вашем гильдии."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Пригласить игрока в вашу группу"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Покинуть текущую группу"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Вышвырнуть кого-либо из вашей текущей группы"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+"/item > Показать/Скрыть текущее состояние распределения предметов в группе"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Показать/Скрыть текущее состояние распределения опыта в группе"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Эта Команда заставляет игрока покинуть группу"
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Команда: /item <политика разделения предметов>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr "Команда изменяет политику разделения предетов между ченами группы."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<политикой> может быть \"1\", \"yes\", \"true\" для включения разделения "
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Команда: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "Отображает текущую политику раздеения предметов между членами группы."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Команда: /exp <политика распределения опыта>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Эта команда изменяет политику распределения опыта в группе."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Команда: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr "Эта команда отображает текущую политику обмена опытом."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Обмен предметами включен"
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Обмен предметами выключен"
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Обмен предметами невозможен."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+msgid "Item sharing unknown."
+msgstr "Статус обмена предметами неизвестен."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Обмен опытом вклыючен."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Обмен опытом выкючен."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Обмен опытом невозможен."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+msgid "Experience sharing unknown."
+msgstr "Политика распределения опыта неизвестна."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Не удалось использовать предмет."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Нельза экипировать!"
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Учетная запись не найдена. Попробуйте снова."
+
+#: src/net/tmwa/loginhandler.cpp:96
+msgid "New password too short."
+msgstr "Новый пароль слишком короткий."
+
+#: src/net/tmwa/loginhandler.cpp:161
+msgid "Unregistered ID."
+msgstr "Незарегистрированный ID"
+
+#: src/net/tmwa/loginhandler.cpp:164
+msgid "Wrong password."
+msgstr "Неверный пароль"
+
+#: src/net/tmwa/loginhandler.cpp:167
+msgid "Account expired."
+msgstr "Учетная запись просрочена."
+
+#: src/net/tmwa/loginhandler.cpp:170
+msgid "Rejected from server."
+msgstr "Получен отказ от сервера.."
+
+#: src/net/tmwa/loginhandler.cpp:173
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "Вас навсегда забанили. Пожалуйста, свяжитесь с командой ГМ-ов."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Вас забанили до %s. Пожалуйста, свяжитесь с командой ГМ-ов через форум."
+
+#: src/net/tmwa/loginhandler.cpp:184
+msgid "This user name is already taken."
+msgstr "Это имя пользователя уже занято."
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr "Пустой адрес был передан методу Network::connect()!"
+
+#: src/net/tmwa/network.cpp:351
+msgid "Unable to resolve host \""
+msgstr "Не удолось найти хост \""
+
+#: src/net/tmwa/network.cpp:421
+msgid "Connection to server terminated. "
+msgstr "Подключение к серверу прервано."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Не удалось создать группу."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Группа успешно создана."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s уже в вашей группе."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s отверг ваше приглашение."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s теперь в вашей группе."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "QQQ Неизвестный ответ на приглашение для %s"
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Вы покинули группу."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s покинул вашу группу."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "Неизвестный участник попытался сказать: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s не в группе!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Опустите монетку для продолжения."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Вы не мертвы. Вы просто отдыхаете."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Вас больше нет."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Вы перестали быть."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Ваше время истекло, пора встретиться с Создателем."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Вы сдулись."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Лишенный жизни, покойся с миром."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Ваш обмен веществ стал историей."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Вы упали с ветки."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Вы не жилец"
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Сообщение"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+"Вы несете груз больший, чем половина вашей грузоподъемности. Не удалось "
+"восстановить здоровье."
+
+#: src/net/tmwa/playerhandler.cpp:337
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr ""
+"Вы несете груз меньше, чем половина вашей грузоподъемности. Вы можете "
+"восстановить здоровье."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, c-format
+msgid "You picked up %s."
+msgstr "Вы получили %s."
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, c-format
+msgid "You spent %s."
+msgstr "Вы потратили %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr "Не удалось увеличить навык!"
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Для начала экипируйтесь стрелами!"
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Не удалось начать торговлю!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Не удалось испоьзовать смайлик!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Не удалось присесть!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Не удалось создать чат!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Нельзы присоединиться к группе!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Нельзя кричать!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "У Вас недостаточный уровень!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Недостаточно ОЖ!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Недостаточно Маны"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "У вас нет записей!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Вы не можете сделать это сейчас!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Похоже вам нужно боьше денег... ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Вы не можете использовать это умение с этим видом оружия!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Вам нужен другой красный камень!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Вам нужен другой синий камень!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Вы несёте слишком много, чтобы сделать это!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "А? Что это?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Изменение не удалось..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Не удалось ничего украсть..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Яд не подействовал..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Торговля невозможна. Партнер по торговле слишком далеко."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Торговля невозможна. Такой персонаж не существует."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Торговля отменена по неизвестной причине."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Торговля: Вы и %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Торговля с %s отменена."
+
+#: src/net/tmwa/tradehandler.cpp:184
+msgid "Unhandled trade cancel packet."
+msgstr "Неизвестный сигнал завершения торговли"
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Не удалось добавить предмет. Партнер по торговле перегружен."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "Не удалось добавить предмет. У партнера по торговле кончилось место."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Не удалось добавить предмет по неизвестной причине."
+
+#: src/playerrelations.cpp:404
+msgid "Completely ignore"
+msgstr "@@ignore|Полностью игнорировать@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr "Печатать '...'"
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr "Мигать именем"
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr "Плавающий '...' пузырек"
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr "Плавающий пузырек"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Атака %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Защита %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "Мана %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Неизвестный предмет"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "безымянный"
+
+#~ msgid "One stat is zero."
+#~ msgstr "Одна из характеристик равна нулю."
+
+#~ msgid "Particle detail: %s"
+#~ msgstr "Детализация частиц: %s"
+
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Эффекты окружающей среды: %s"
+
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Горячая клавиша емоции %d"
+
+#~ msgid "Guild creation isn't supported yet."
+#~ msgstr "Создание гильдий пока не поддерживается."
+
+#, fuzzy
+#~ msgid "%s (?, ?)"
+#~ msgstr "Курсор: (?, ?)"
+
+#~ msgid "Player position:"
+#~ msgstr "Позиция игрока:"
+
+#~ msgid "Music: %s"
+#~ msgstr "Музыка: %s"
+
+#~ msgid "Map: %s"
+#~ msgstr "Карта: %s"
+
+#~ msgid "Minimap: %s"
+#~ msgstr "МиниКарта: %s"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Записывать чат во внешний файл"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Команда: /record <имя файла>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr "Эта команда начнет протоколирование окна чата в файл <имя файла>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Команда: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Эта команда завершает запись."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Запись завершена."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Запись не ведётся."
+
+#~ msgid "Already recording."
+#~ msgstr "Запись уже ведётся."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Начало записи..."
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Не удалось начать запись."
+
+#~ msgid "Recording..."
+#~ msgstr "Запись..."
+
+#~ msgid "Stop recording"
+#~ msgstr "Остановить записи..."
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Идти за курсором мыши"
+
+#~ msgid "HP"
+#~ msgstr "ОЖ"
+
+#~ msgid "MP"
+#~ msgstr "Мана:"
+
+#~ msgid "Exp"
+#~ msgstr "Опыт:"
+
+#~ msgid "Money"
+#~ msgstr "Деньги"
+
+#~ msgid "Job"
+#~ msgstr "Профессия"
+
+#~ msgid "Level"
+#~ msgstr "Уровень"
+
+#~ msgid "Player already ignored!"
+#~ msgstr "Игрок уже в спике игнорирования"
+
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Игрок добавлен в список игнорирования!"
+
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Игрок не может быть добавлен в список игнорирования"
+
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr ""
+#~ " -С --config-file : Использовать указанный конфигурационный файл "
+
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -l --chat-log-dir : Каталог для журнала чата"
+
+#~ msgid "Sound"
+#~ msgstr "Звук"
+
+#~ msgid "You now away from keyboard"
+#~ msgstr "Сейчас вы в режиме отошел"
+
+#~ msgid "Access denied."
+#~ msgstr "Доступ запрещен"
+
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Неизвестный Глюк при выборе персонажа"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr "Такое приглашение в данный момент не поддерживается."
+
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s приглашает вас к себе в группу."
+
+#~ msgid "Willpower:"
+#~ msgstr "Воля:"
+
+#~ msgid "Server is full."
+#~ msgstr "Сервер переполнен"
+
+#~ msgid "Trade with %s..."
+#~ msgstr "@@trade|Торговать с %s@@"
+
+#~ msgid "Whisper %s"
+#~ msgstr "Шептать"
+
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Полностью игнорировать %s@@"
+
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Пригласить %s в вашу гильдию@@"
+
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Пригласить %s в вашу группу@@"
+
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Говорить с %s@@"
+
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Вышвырнуть монстра@@"
+
+#~ msgid "Pick up %s"
+#~ msgstr "Поднять"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Низзя послать пустое сообщение!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Нельзя разекипировать"
+
+#~ msgid "Text Shadow"
+#~ msgstr "Тень от текста"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Подписи Progress Bar'ов"
+
+#~ msgid "Item Too Expensive"
+#~ msgstr "Предмет слишком дорогой для вас"
+
+#~ msgid "Item Is Equipped"
+#~ msgstr "Предмет экипирован"
+
+#~ msgid "GM"
+#~ msgstr "ГМ"
+
+#~ msgid "Player"
+#~ msgstr "Игрок"
+
+#~ msgid "Whisper"
+#~ msgstr "Шептать"
+
+#~ msgid "Is"
+#~ msgstr "Есть"
+
+#~ msgid "Server"
+#~ msgstr "Сервер"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Вещь неизвестного типа"
+
+#~ msgid "Generics"
+#~ msgstr "Общие"
+
+#~ msgid "Hats"
+#~ msgstr "Шляпы"
+
+#~ msgid "Usables"
+#~ msgstr "используемый"
+
+#~ msgid "Shirts"
+#~ msgstr "Рубашки"
+
+#~ msgid "One Handed Weapons"
+#~ msgstr "Одноручное оружие"
+
+#~ msgid "Pants"
+#~ msgstr "Штаны"
+
+#~ msgid "Shoes"
+#~ msgstr "Обувь"
+
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Двуручное оружие"
+
+#~ msgid "Shields"
+#~ msgstr "Щиты"
+
+#~ msgid "Rings"
+#~ msgstr "Кольца"
+
+#~ msgid "Necklaces"
+#~ msgstr "Ожерелья"
+
+#~ msgid "Ammo"
+#~ msgstr "Боеприпасы"
+
+#~ msgid "HP Bar"
+#~ msgstr "Строка очков жизни (ОЖ)"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "3/4 строки ОЖ"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "Половина строки ОЖ"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "1/4 строки ОЖ"
+
+#~ msgid "no"
+#~ msgstr "Нет"
+
+#~ msgid "Buddy"
+#~ msgstr "Друг"
+
+#~ msgid "Buddy List"
+#~ msgstr "Список друзей"
+
+#~ msgid "Description: %s"
+#~ msgstr "Описание: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Эффект: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Предыдущий"
+
+#~ msgid "New"
+#~ msgstr "Новый"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Уровень профессии: %d"
+
+#~ msgid "Quit Guild"
+#~ msgstr "Распустить гильдию"
+
+#~ msgid "Ok"
+#~ msgstr "Ok"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Прочитать Тестовое Заклинание №1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Прочитать Тестовое Заклинание №2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Прочитать Тестовое Заклинание №3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Двуручное оружие"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Разекипировать@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Надеть@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Сбросить@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Разделить@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Выберите сервер"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Мистичный Навык"
+
+#~ msgid "Weapons"
+#~ msgstr "Оружие"
+
+#~ msgid "Stats"
+#~ msgstr "Статистика"
+
+#~ msgid "Total"
+#~ msgstr "Всего"
+
+#~ msgid "Cost"
+#~ msgstr "Стоимость"
+
+#~ msgid "Attack:"
+#~ msgstr "Атака:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Рефлекс"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Осталось очков статуса: %d"
+
+#~ msgid " host: "
+#~ msgstr " хост: "
+
+#~ msgid "Buddys"
+#~ msgstr "Приятели"
+
+#~ msgid "Party Window"
+#~ msgstr "Окно группы"
+
+#~ msgid "Unarmed"
+#~ msgstr "Обезоруженный"
+
+#~ msgid "Knife"
+#~ msgstr "Нож"
+
+#~ msgid "Sword"
+#~ msgstr "Меч"
+
+#~ msgid "Bow"
+#~ msgstr "Лук"
+
+#~ msgid "Shooting"
+#~ msgstr "Стрельба"
+
+#~ msgid "Mace"
+#~ msgstr "Булава"
+
+#~ msgid "Axe"
+#~ msgstr "Топор"
+
+#~ msgid "Craft"
+#~ msgstr "Сотворить"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Неизвестный Навык"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Подключение к серверу персонажей..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Соединение с сервером авторизации..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Имя для создания"
+
+#~ msgid "Unnamed"
+#~ msgstr "Без имени"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Подобрать %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Радиус прокрутки"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Заторможенность прокрутки"
diff --git a/po/sk.po b/po/sk.po
new file mode 100644
index 000000000..df2e25c69
--- /dev/null
+++ b/po/sk.po
@@ -0,0 +1,3632 @@
+# Slovak translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-06-08 22:09+0000\n"
+"Last-Translator: Thorbjørn Lindeijer <bjorn@lindeijer.nl>\n"
+"Language-Team: Slovak <sk@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural= (n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "Nastavenie"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Pripájam sa..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "Prihlásenie"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Vyberte postavu"
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Chyba"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Heslo:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Zrušiť registráciu"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Neznámy príkaz."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- Pomoc --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "Príkaz: /hel"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "Tento príkaz zobrazí zoznam veštkých prístupných príkazov."
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "Príkaz: /help <príkaz>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "Tento príkaz zobrazí nápovedu pre <príkaz>."
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "Príkaz: /announce <správa>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** prístupné iba pre GM ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Tento príkaz pošle správu <správa> všetkým pripojeným používateľom."
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "Príkaz: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "Tento príkaz vymaže obsah logu predchádzajúceho rozhovoru."
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Príkaz: /announce <správa>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Tento príkaz zobrazí počet aktuálne pripojených hráčov."
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "Ak <nick> medzery v mene, použi dvojité úvodzovky (\")."
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Príkaz: /clear"
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Príkaz: /announce <správa>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "Príkaz: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "Tento príkaz zobrazí meno aktuálne mapy."
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "Príkaz: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "Tento príkaz zobrazí počet aktuálne pripojených hráčov."
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "Napíš /help pre zoznam príkazov."
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Nie je možné vstúpiť do párty!"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "Kúpiť"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Ukončiť"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "Obchod"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Predaj"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "Zrušiť"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Zmeniť Emailovú adresu"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Účet: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Používateľské meno musí byť najmenej %d písmen dlhé."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Používateľské meno musí byt menšie než %d."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "Zmeniť heslo"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Heslo:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Heslo musí byť aspoň %d písmen dlhé."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Heslo musí byť menšie %d ako písmen."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Vytvoriť postavu"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "Meno"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Farba vlasov:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Štýl vlasov:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "Vytvoriť"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "Muž"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "Žena"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Prosím rozdeľ %d bodov"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Tvoje meno musí mať aspoň 4 písmená."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Charakterové staty OK"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Prosím odstráň %d bodov"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "Potvrďte zmazanie postavy"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Naozaj chcete odstrániť túto postavu?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "Účet a správa postáv"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Zrušiť registráciu"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Zmeniť Emailovú adresu"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Vymazať"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "Zatvoriť"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Nápoveda pre %s: %s"
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Áno"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Nie"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "Meno: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Účet: %s"
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Vybavenie"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "Odstrojiť"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "Nápoveda"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "Zatvoriť"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "Inventár"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "Vystrojiť"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Použiť"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "Zahodiť"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "Zahodiť"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "Potvrdiť"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "Zvoľte množstvo vecí k predaju."
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "Zvoľte množstvo vecí k zahodeniu."
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "Zvoľte množstvo vecí k rozdeleniu."
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Effekt: %s"
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "Prihlásenie"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "Zapamätať si používateľské meno"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Registrovať"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Vyberte Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Nasledujúci"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Nasledujúci"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "Odstrojiť"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "@@obchod|Obchodovať s %s@@"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "@@útok|Útok %s@@"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "Nápoveda pre %s: %s"
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, fuzzy, c-format
+msgid "Invite %s to join your guild"
+msgstr "@@párti|Pozvať %s pridať sa do tvoje párti@@"
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "@@párti|Pozvať %s pridať sa do tvoje párti@@"
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "Zmeniť server"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "Vymeniť postavu"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Používateľské meno musí byť najmenej %d písmen dlhé."
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Používateľské meno musí byt menšie než %d."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Heslo musí byť aspoň %d písmen dlhé."
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Heslo musí byť menšie %d ako písmen."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Heslá sa nezhodujú."
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "Pripájam sa..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Vyberte Server"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "Zvuk"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Sfx zvuk"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Hudobný zvuk"
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Použiť"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Nie"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Schopnosti"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Schopnosti"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Level: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Level: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Naozaj chcete odstrániť túto postavu?"
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Naozaj chcete odstrániť túto postavu?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Vytvoriť postavu"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "Klany, aliancie, guildy"
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Level: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Peniaze: %d"
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Charakterové staty OK"
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Level: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Meno: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "Pripájam sa..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "Globálne oznámenie:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Globálne oznámenie od %s:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "Nápoveda pre %s: %s"
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Príkaz: /where"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Tento príkaz zobrazí počet aktuálne pripojených hráčov."
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "Stav"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "Skratka"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "Vyberte Server"
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "Sila:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "Čulosť:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "Vitalita:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "Inteligencia:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "Obratnosť:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "Meno"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Vytvorenie postavy sa nepodarilo"
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Vymazať"
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Tento príkaz zobrazí meno aktuálne mapy."
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Neznámy príkaz."
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Zrušiť registráciu"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "Zmeniť heslo"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr "Obchod sa nepodaril!"
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr "Zobrazenie smajlíka sa nepodarilo!"
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr "Sadnutie sa nepodarilo!"
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr "Vytvorenie postavy sa nepodarilo"
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr "Nie je možné vstúpiť do párty!"
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr "Nemôžem kričať!"
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Ešte si nedosiahol dostatočne vysokú úroveť!"
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr "Nedostatok HP!"
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr "Nedostatok SP!"
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr "Nemáš žiadne poznámky!"
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr "Práve teraz to nemôžeš robiť."
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Nemôžeš použiť túto zručnosť s touto zbraňou!"
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr "Potrebuješ ďaľší červený gem!"
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr "Potrebuješ ďaľší modrý gem!"
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr "Nosíš veľa, aby si mohol spraviť toto!"
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr "Heh? Čo to je?"
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr "Warp sa nepodaril ..."
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr "Nedá sa kradnúť ..."
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr "Jed nemá žiaden účinnok ..."
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Charakterové staty OK"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Charakterové staty OK"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Zvoľte množstvo vecí k predaju."
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Neznámy príkaz."
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "Sila vôle:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Neznámy príkaz."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "Sila vôle:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Description: %s"
+#~ msgstr "Popis: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Predchádzajúci"
+
+#~ msgid "New"
+#~ msgstr "Nový"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Pracovná úroveň: %d"
+
+#~ msgid "Ok"
+#~ msgstr "Ano"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@zrušiť|Zrušiť@@"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@použiť|Odstrojiť@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@použiť|Obliecť@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@použiť|Použiť@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@vyhodiť|Vyhodiť@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@rozdeliť|Rozdeliť@@"
diff --git a/po/sq.po b/po/sq.po
new file mode 100644
index 000000000..71c3fa049
--- /dev/null
+++ b/po/sq.po
@@ -0,0 +1,3560 @@
+# Albanian translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2010-01-02 10:47+0000\n"
+"Last-Translator: Jat Lee <Unknown>\n"
+"Language-Team: Albanian <sq@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:650
+msgid "Logging in"
+msgstr ""
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr ""
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+msgid "Password Change"
+msgstr ""
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Unknown command > Komand e panjohur"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- Ndihmë--"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/ndihmë > Ndihmë përeth disa komandave"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/ku > Emri i mapit ku gjendesh"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/kush > Numri i lojtarëve online"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/unë >Trego diqka për veten"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/pastro > Pastro këtë dritare"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/mesazh > Dërgo mesazh privat te playeri që dëshiron"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/pëshpëritje > pseudonim i mesazhit"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > pseudonim i mesazhit"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr ""
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:134
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:123
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+msgid "Hair color:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:77
+msgid "Hair style:"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+msgid "Change Email"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, c-format
+msgid "Map: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, c-format
+msgid "Particle count: %d"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr ""
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+msgid ""
+"\n"
+"> Next\n"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr ""
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+msgid "None"
+msgstr ""
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, c-format
+msgid "Lvl: %d (%+d)"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:416
+#, c-format
+msgid "Lvl: %d"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+msgid "Create Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+msgid "Level"
+msgstr ""
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "/ndihmë > Ndihmë përeth disa komandave"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Game"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+msgid "Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Unknown command > Komand e panjohur"
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Unknown command > Komand e panjohur"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Unknown command > Komand e panjohur"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
diff --git a/po/sv.po b/po/sv.po
new file mode 100644
index 000000000..6e9005101
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,5761 @@
+# Swedish translation for mana
+# Copyright (c) 2007 Rosetta Contributors and Canonical Ltd 2007
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-12-24 19:29+0200\n"
+"PO-Revision-Date: 2009-07-17 05:36+0000\n"
+"Last-Translator: Kess Vargavind <Unknown>\n"
+"Language-Team: Swedish <sv@li.org>\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:724 src/gui/setup.cpp:47 src/gui/windowmenu.cpp:92
+msgid "Setup"
+msgstr "Inställningar"
+
+#: src/client.cpp:798
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Ansluter till kartservern..."
+
+#: src/client.cpp:829
+#, fuzzy
+msgid "Logging in"
+msgstr "Användarnamn"
+
+#: src/client.cpp:862
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:953
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Välj karaktär"
+
+#: src/client.cpp:984
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "Ansluter till kartservern..."
+
+#: src/client.cpp:994
+#, fuzzy
+msgid "Changing game servers"
+msgstr "Server"
+
+#: src/client.cpp:1029 src/client.cpp:1036 src/client.cpp:1171
+#: src/gui/changeemaildialog.cpp:154 src/gui/changepassworddialog.cpp:144
+#: src/gui/charcreatedialog.cpp:179 src/gui/register.cpp:225
+#: src/gui/serverdialog.cpp:350 src/gui/unregisterdialog.cpp:134
+#: src/net/manaserv/charhandler.cpp:180 src/net/manaserv/charhandler.cpp:223
+#: src/net/tmwa/charserverhandler.cpp:137
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Error"
+msgstr "Fel"
+
+#: src/client.cpp:1045
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:1072
+#, fuzzy
+msgid "Password Change"
+msgstr "Lösenord:"
+
+#: src/client.cpp:1073
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:1092
+#, fuzzy
+msgid "Email Change"
+msgstr "Ändra"
+
+#: src/client.cpp:1093
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "Medlem befordrad."
+
+#: src/client.cpp:1113
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Avregistrera"
+
+#: src/client.cpp:1114
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1297 src/client.cpp:1323 src/client.cpp:1367
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1494
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Ogiltig uppdateringsvärd: "
+
+#: src/client.cpp:1528 src/client.cpp:1534
+msgid "Error creating updates directory!"
+msgstr "Kunde inte skapa katalog för uppdateringar!"
+
+#: src/client.cpp:1555
+#, c-format
+msgid "Error: %s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/commandhandler.cpp:264 src/commandhandler.cpp:477
+msgid "Unknown command."
+msgstr "Okänt kommando."
+
+#: src/commandhandler.cpp:294
+msgid "-- Help --"
+msgstr "-- Hjälp --"
+
+#: src/commandhandler.cpp:295
+msgid "/help > Display this help"
+msgstr "/help > Visa den här hjälpen"
+
+#: src/commandhandler.cpp:297
+msgid "/where > Display map name"
+msgstr "/where > Visa kartans namn"
+
+#: src/commandhandler.cpp:298
+msgid "/who > Display number of online users"
+msgstr "/who > Visa antalet inloggade spelare"
+
+#: src/commandhandler.cpp:299
+msgid "/me > Tell something about yourself"
+msgstr "/me > Säg något om dig själv"
+
+#: src/commandhandler.cpp:301
+msgid "/clear > Clears this window"
+msgstr "/clear > Tömmer det här fönstret"
+
+#: src/commandhandler.cpp:303
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Skickar ett privat meddelande till en spelare"
+
+#: src/commandhandler.cpp:304
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alias för msg"
+
+#: src/commandhandler.cpp:305
+msgid "/w > Alias of msg"
+msgstr "/w > Alias för msg"
+
+#: src/commandhandler.cpp:306
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Skapar en flik för privata meddelanden med en annan spelare"
+
+#: src/commandhandler.cpp:308
+msgid "/q > Alias of query"
+msgstr "/q > Alias för query"
+
+#: src/commandhandler.cpp:310
+msgid "/away > Tell the other whispering players you're away from keyboard."
+msgstr ""
+
+#: src/commandhandler.cpp:313
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:314
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:315
+#, fuzzy
+msgid "/ignoreall > Ignore all opened whisper tabs"
+msgstr "/close > Stänger viskningsfliken"
+
+#: src/commandhandler.cpp:316
+msgid "/erase > Erase a player"
+msgstr ""
+
+#: src/commandhandler.cpp:317
+msgid "/befriend > Be friend a player"
+msgstr ""
+
+#: src/commandhandler.cpp:318
+#, fuzzy
+msgid "/desregard > Disregard a player"
+msgstr "@@disregard|Strunta i %s@@"
+
+#: src/commandhandler.cpp:319
+msgid "/neutral > Neutral a player"
+msgstr ""
+
+#: src/commandhandler.cpp:321
+msgid "/list > Display all public channels"
+msgstr "/list > Visa alla offentliga chattkanaler"
+
+#: src/commandhandler.cpp:322
+msgid "/join > Join or create a channel"
+msgstr "/join > Gå med i eller skapa en chattkanal"
+
+#: src/commandhandler.cpp:324
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > Skapa ny grupp"
+
+#: src/commandhandler.cpp:325
+#, fuzzy
+msgid "/createguild > Create a new guild"
+msgstr "/create > Skapa ny grupp"
+
+#: src/commandhandler.cpp:326
+msgid "/party > Invite a user to party"
+msgstr "/party > Bjud in en spelare till din grupp"
+
+#: src/commandhandler.cpp:328
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Avgör huruvida <retur> aktiverar chattfönstret eller ej"
+
+#: src/commandhandler.cpp:330
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Lista närvarande spelare (sänds till chattloggen om loggning är "
+"aktiverad)"
+
+#: src/commandhandler.cpp:333
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Globalt meddelande (endast för GM)"
+
+#: src/commandhandler.cpp:335
+#, fuzzy
+msgid "/closeall > Close all opened whisper tabs"
+msgstr "/close > Stänger viskningsfliken"
+
+#: src/commandhandler.cpp:337
+msgid "/all > Show all visible beings in debug tab"
+msgstr ""
+
+#: src/commandhandler.cpp:339
+msgid "/move > Move to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:340
+msgid "/navigate > Draw path to given position"
+msgstr ""
+
+#: src/commandhandler.cpp:341
+msgid "/target > Set target to being"
+msgstr ""
+
+#: src/commandhandler.cpp:342
+msgid "/outfit > Wear outfit by index"
+msgstr ""
+
+#: src/commandhandler.cpp:343
+msgid "/emote > Show emote by index"
+msgstr ""
+
+#: src/commandhandler.cpp:344
+msgid "/follow > Follow player"
+msgstr ""
+
+#: src/commandhandler.cpp:345
+msgid "/imitation > Imitate player"
+msgstr ""
+
+#: src/commandhandler.cpp:346
+msgid "/heal > Heal player"
+msgstr ""
+
+#: src/commandhandler.cpp:347
+#, fuzzy
+msgid "/mail > Send offline message to player"
+msgstr "/msg > Skickar ett privat meddelande till en spelare"
+
+#: src/commandhandler.cpp:351
+msgid "For more information, type /help <command>."
+msgstr "Skriv /help <kommando> för mer information."
+
+#: src/commandhandler.cpp:355
+msgid "Command: /help"
+msgstr "Kommando: /help"
+
+#: src/commandhandler.cpp:356
+msgid "This command displays a list of all commands available."
+msgstr "Det här kommandot visar en lista över alla tillgängliga kommandon."
+
+#: src/commandhandler.cpp:358
+msgid "Command: /help <command>"
+msgstr "Kommando: /help <kommando>"
+
+#: src/commandhandler.cpp:359
+msgid "This command displays help on <command>."
+msgstr "Det här kommandot ger mer information om <kommando>."
+
+#: src/commandhandler.cpp:367
+msgid "Command: /announce <msg>"
+msgstr "Kommando: /announce <text>"
+
+#: src/commandhandler.cpp:368
+msgid "*** only available to a GM ***"
+msgstr "*** endast en GM kan använda det här kommandot ***"
+
+#: src/commandhandler.cpp:369
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"Det här kommandot skickar meddelandet <text> till alla inloggade spelare."
+
+#: src/commandhandler.cpp:374
+msgid "Command: /clear"
+msgstr "Kommando: /clear"
+
+#: src/commandhandler.cpp:375
+msgid "This command clears the chat log of previous chat."
+msgstr "Det här kommandot tömmer chattloggen."
+
+#: src/commandhandler.cpp:379
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Kommando: /item <alternativ>"
+
+#: src/commandhandler.cpp:380
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Det här kommandot visar antalet spelare som är inloggade just nu."
+
+#: src/commandhandler.cpp:385
+msgid "Command: /join <channel>"
+msgstr "Kommando: /join <chattkanal>"
+
+#: src/commandhandler.cpp:386
+msgid "This command makes you enter <channel>."
+msgstr "Det här kommandot låter dig gå in i <chattkanal>."
+
+#: src/commandhandler.cpp:387
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Om <chattkanal> inte existerar, skapas den."
+
+#: src/commandhandler.cpp:391
+msgid "Command: /list"
+msgstr "Kommando: /list"
+
+#: src/commandhandler.cpp:392
+msgid "This command shows a list of all channels."
+msgstr "Det här kommandot visar en lista över alla chattkanaler."
+
+#: src/commandhandler.cpp:396
+msgid "Command: /me <message>"
+msgstr "Kommando: /me <meddelande>"
+
+#: src/commandhandler.cpp:397
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Det här kommandet berättar för andra att du är/gör <meddelande>."
+
+#: src/commandhandler.cpp:401
+msgid "Command: /msg <nick> <message>"
+msgstr "Kommando: /msg <spelare> <meddelande>"
+
+#: src/commandhandler.cpp:402
+msgid "Command: /whisper <nick> <message>"
+msgstr "Kommando: /whisper <spelare> <meddelande>"
+
+#: src/commandhandler.cpp:403
+msgid "Command: /w <nick> <message>"
+msgstr "Kommando: /w <spelare> <meddelande>"
+
+#: src/commandhandler.cpp:404
+msgid "This command sends the text <message> to <nick>."
+msgstr "Det här kommandot skickar <meddelande> till <spelare>."
+
+#: src/commandhandler.cpp:405 src/commandhandler.cpp:437
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/tmwa/gui/guildtab.cpp:88 src/net/tmwa/gui/partytab.cpp:82
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Om <spelare> innehåller mellanslag, måste du sätta citattecken (\") runt det."
+
+#: src/commandhandler.cpp:410
+msgid "Command: /query <nick>"
+msgstr "Kommando: /query <spelare>"
+
+#: src/commandhandler.cpp:411
+msgid "Command: /q <nick>"
+msgstr "Kommando: /q <spelare>"
+
+#: src/commandhandler.cpp:412
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Det här kommandot försöker att skapa en flik för viskningar mellan dig och "
+"<spelare>."
+
+#: src/commandhandler.cpp:417
+#, fuzzy
+msgid "Command: /away <afk reason>"
+msgstr "Kommando: /w <spelare> <meddelande>"
+
+#: src/commandhandler.cpp:418
+msgid "This command tells you're away from keyboard with the given reason."
+msgstr ""
+
+#: src/commandhandler.cpp:420
+#, fuzzy
+msgid "Command: /away"
+msgstr "Kommando: /who"
+
+#: src/commandhandler.cpp:421
+#, fuzzy
+msgid "This command clears the away status and message."
+msgstr "Det här kommandot sätter ämnet till <meddelande>."
+
+#: src/commandhandler.cpp:425
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Kommando: /create <grupp>"
+
+#: src/commandhandler.cpp:426
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Dessa kommandon skapar <grupp>."
+
+#: src/commandhandler.cpp:430
+#, fuzzy
+msgid "Command: /createguild <name>"
+msgstr "Kommando: /create <grupp>"
+
+#: src/commandhandler.cpp:431
+#, fuzzy
+msgid "This command creates a new guild called <name>."
+msgstr "Dessa kommandon skapar <grupp>."
+
+#: src/commandhandler.cpp:435
+msgid "Command: /party <nick>"
+msgstr "Kommando: /party <spelare>"
+
+#: src/commandhandler.cpp:436 src/net/tmwa/gui/partytab.cpp:81
+msgid "This command invites <nick> to party with you."
+msgstr "Det här kommandot bjuder in <spelare> till din grupp."
+
+#: src/commandhandler.cpp:442
+msgid "Command: /present"
+msgstr "Kommando: /present"
+
+#: src/commandhandler.cpp:443
+#, fuzzy
+msgid ""
+"This command gets a list of players within hearing and sends it to chat log."
+msgstr ""
+"Det här kommandot ger en lista över spelare som finns inom höravstånd, om "
+"loggning av chatten är aktiverad skickas listan till loggfilen."
+
+#: src/commandhandler.cpp:448
+msgid "Command: /toggle <state>"
+msgstr "Kommando: /toggle <tillstånd>"
+
+#: src/commandhandler.cpp:449
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Det här kommandot anger huruvida retur visar/döljerer chattfönstret eller om "
+"chattfönstret stänger sig själv."
+
+#: src/commandhandler.cpp:452
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or "
+"\"0\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<tillstånd> kan vara ”1”, ”yes” eller ”true” för att använda returtangenten "
+"eller ”0”, ”no” eller ”false” för att använda automatisk stängning."
+
+#: src/commandhandler.cpp:455
+msgid "Command: /toggle"
+msgstr "Kommando: /toggle"
+
+#: src/commandhandler.cpp:456
+msgid "This command displays the return toggle status."
+msgstr "Det här kommandot visar tillståndet för huruvida retur används."
+
+#: src/commandhandler.cpp:460 src/gui/widgets/whispertab.cpp:127
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Kommando: /item <alternativ>"
+
+#: src/commandhandler.cpp:461
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:466
+msgid "Command: /where"
+msgstr "Kommando: /where"
+
+#: src/commandhandler.cpp:467
+msgid "This command displays the name of the current map."
+msgstr "Det här kommandot visar namnet på den karta där du befinner dig."
+
+#: src/commandhandler.cpp:471
+msgid "Command: /who"
+msgstr "Kommando: /who"
+
+#: src/commandhandler.cpp:472
+msgid "This command displays the number of players currently online."
+msgstr "Det här kommandot visar antalet spelare som är inloggade just nu."
+
+#: src/commandhandler.cpp:478
+msgid "Type /help for a list of commands."
+msgstr "Skriv /help för en lista med kommandon."
+
+#: src/commandhandler.cpp:546
+msgid "Cannot send empty whispers!"
+msgstr "Behöver en text att viska!"
+
+#: src/commandhandler.cpp:554
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Kan inte skapa viskningsflik för smeknamnet \"%s\"! Antingen existerar "
+"fliken redan eller så försöker du viska till dig själv."
+
+#: src/commandhandler.cpp:574
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Skickar förfrågan att gå in i chattkanalen %s."
+
+#: src/commandhandler.cpp:590 src/net/tmwa/gui/partytab.cpp:122
+msgid "Party name is missing."
+msgstr "Du måste ange gruppens namn."
+
+#: src/commandhandler.cpp:601
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "Du måste ange gruppens namn."
+
+#: src/commandhandler.cpp:614 src/commandhandler.cpp:721
+#: src/commandhandler.cpp:762 src/commandhandler.cpp:792
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:655
+msgid "Return toggles chat."
+msgstr "Retur visar/döljer chattfönstret."
+
+#: src/commandhandler.cpp:655
+msgid "Message closes chat."
+msgstr "Meddelande stänger chattfönstret."
+
+#: src/commandhandler.cpp:666
+msgid "Return now toggles chat."
+msgstr "Retur växlar nu chattfönstrets synlighet."
+
+#: src/commandhandler.cpp:672
+msgid "Message now closes chat."
+msgstr "Meddelanden stänger nu chattfönstret."
+
+#: src/commandhandler.cpp:700
+#, fuzzy
+msgid "friend"
+msgstr "Vän"
+
+#: src/commandhandler.cpp:705
+#, fuzzy
+msgid "disregarded"
+msgstr "Förbisedd"
+
+#: src/commandhandler.cpp:710
+#, fuzzy
+msgid "neutral"
+msgstr "Neutral"
+
+#: src/commandhandler.cpp:729
+#, fuzzy, c-format
+msgid "Player already %s!"
+msgstr "Kunde inte viska eftersom ignorerad av spelaren."
+
+#: src/commandhandler.cpp:743
+#, fuzzy, c-format
+msgid "Player successfully %s!"
+msgstr "Grupp skapad."
+
+#: src/commandhandler.cpp:751
+#, fuzzy, c-format
+msgid "Player could not be %s!"
+msgstr "Kunde inte viska eftersom ignorerad av spelaren."
+
+#: src/commandhandler.cpp:773
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:780
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:782
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "Kunde inte viska eftersom ignorerad av spelaren."
+
+#: src/commandhandler.cpp:799
+#, fuzzy
+msgid "Player already erased!"
+msgstr "Kunde inte viska eftersom ignorerad av spelaren."
+
+#: src/commandhandler.cpp:810
+#, fuzzy
+msgid "Player successfully erased!"
+msgstr "Grupp skapad."
+
+#: src/commandhandler.cpp:812
+#, fuzzy
+msgid "Player could not be erased!"
+msgstr "Kunde inte viska eftersom ignorerad av spelaren."
+
+#: src/commandhandler.h:39
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr "Alternativ till /%s är ”yes”, ”no”, ”true”, ”false”, ”1”, ”0”."
+
+#: src/game.cpp:219 src/gui/widgets/chattab.cpp:390
+msgid "General"
+msgstr "Allmänt"
+
+#: src/game.cpp:223 src/gui/debugwindow.cpp:47 src/gui/widgets/chattab.cpp:392
+msgid "Debug"
+msgstr ""
+
+#: src/game.cpp:435
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Skärmbild sparades till ~/"
+
+#: src/game.cpp:443
+msgid "Saving screenshot failed!"
+msgstr "Kunde inte spara skärmbild!"
+
+#: src/game.cpp:482
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr ""
+"Förbindelsen till servern förlorades, programmet kommer nu att avslutas."
+
+#: src/game.cpp:487
+msgid "Network Error"
+msgstr "Nätverksfel"
+
+#: src/game.cpp:997
+msgid "Ignoring incoming trade requests"
+msgstr "Ignorerar handelserbjudanden"
+
+#: src/game.cpp:1004
+msgid "Accepting incoming trade requests"
+msgstr "Accepterar handelserbjudanden"
+
+#: src/game.cpp:1373
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Kunde inte ladda karta"
+
+#: src/game.cpp:1374
+#, c-format
+msgid "Error while loading %s"
+msgstr "Kunde inte ladda %s"
+
+#: src/gui/beingpopup.cpp:89
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Grupp (%s)"
+
+#: src/gui/beingpopup.cpp:102
+#, fuzzy, c-format
+msgid "Guild: %s"
+msgstr "Gillen"
+
+#: src/gui/beingpopup.cpp:114
+#, c-format
+msgid "Pvp rank: %d"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:264
+#, fuzzy
+msgid "Bot Checker"
+msgstr "Chattfönster"
+
+#: src/gui/botcheckerwindow.cpp:294 src/gui/setup_players.cpp:59
+msgid "Name"
+msgstr "Namn"
+
+#: src/gui/botcheckerwindow.cpp:295 src/keyboardconfig.cpp:45
+#: src/net/tmwa/generalhandler.cpp:254
+msgid "Attack"
+msgstr "Attackera"
+
+#: src/gui/botcheckerwindow.cpp:296 src/keyboardconfig.cpp:59
+msgid "Talk"
+msgstr "Prata"
+
+#: src/gui/botcheckerwindow.cpp:297
+#, fuzzy
+msgid "Move"
+msgstr "Gå uppåt"
+
+#: src/gui/botcheckerwindow.cpp:298
+msgid "Result"
+msgstr ""
+
+#: src/gui/botcheckerwindow.cpp:308 src/gui/npcdialog.cpp:116
+msgid "Reset"
+msgstr "Återställ"
+
+#: src/gui/buy.cpp:53 src/gui/buy.cpp:60 src/gui/buy.cpp:94
+#: src/gui/buysell.cpp:62
+msgid "Buy"
+msgstr "Köp"
+
+#: src/gui/buy.cpp:85 src/gui/buy.cpp:298 src/gui/sell.cpp:84
+#: src/gui/sell.cpp:306
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Pris: %s / Totalt: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:90 src/gui/itemamount.cpp:204 src/gui/itemamount.cpp:232
+#: src/gui/npcdialog.cpp:106 src/gui/sell.cpp:87 src/gui/statuswindow.cpp:793
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:93 src/gui/itemamount.cpp:203 src/gui/itemamount.cpp:231
+#: src/gui/npcdialog.cpp:107 src/gui/sell.cpp:88 src/gui/statuswindow.cpp:805
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:95 src/gui/quitdialog.cpp:43 src/gui/quitdialog.cpp:48
+#: src/gui/quitdialog.cpp:49 src/gui/sell.cpp:90 src/gui/serverdialog.cpp:244
+#: src/keyboardconfig.cpp:271
+msgid "Quit"
+msgstr "Avsluta"
+
+#: src/gui/buy.cpp:96 src/gui/sell.cpp:91 src/gui/statuswindow.cpp:446
+#: src/gui/statuswindow.cpp:792 src/gui/statuswindow.cpp:823
+msgid "Max"
+msgstr "Max"
+
+#: src/gui/buysell.cpp:37 src/gui/buysell.cpp:46
+#: src/gui/inventorywindow.cpp:112
+msgid "Shop"
+msgstr "Affär"
+
+#: src/gui/buysell.cpp:62 src/gui/sell.cpp:50 src/gui/sell.cpp:57
+#: src/gui/sell.cpp:89
+msgid "Sell"
+msgstr "Sälj"
+
+#: src/gui/buysell.cpp:62 src/gui/changeemaildialog.cpp:56
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:206
+#: src/gui/npcpostdialog.cpp:55 src/gui/popupmenu.cpp:1120
+#: src/gui/popupmenu.cpp:1147 src/gui/popupmenu.cpp:1192
+#: src/gui/popupmenu.cpp:1230 src/gui/quitdialog.cpp:54
+#: src/gui/register.cpp:79 src/gui/setup.cpp:64 src/gui/socialwindow.cpp:786
+#: src/gui/textcommandeditor.cpp:231 src/gui/textdialog.cpp:44
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:153
+msgid "Cancel"
+msgstr "Avbryt"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Ändra epostadress"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Konto: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Ange den nya epostadressen två gånger:"
+
+#: src/gui/changeemaildialog.cpp:129
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Användarnamnet måste vara minst %d tecken långt."
+
+#: src/gui/changeemaildialog.cpp:136
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Användarnamnet måste vara kortare än %d tecken."
+
+#: src/gui/changeemaildialog.cpp:143
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "Den nya epostadressen används redan."
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:133
+msgid "Change Password"
+msgstr "Ändra lösenord"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:91
+#: src/gui/register.cpp:73 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Lösenord:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Ange det nya lösenordet två gånger:"
+
+#: src/gui/changepassworddialog.cpp:111
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:117
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Lösenordet måste vara minst %d tecken långt."
+
+#: src/gui/changepassworddialog.cpp:124
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Lösenordet måste vara kortare än %d tecken."
+
+#: src/gui/changepassworddialog.cpp:131
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Skapa karaktär"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:90
+#: src/gui/register.cpp:72
+msgid "Name:"
+msgstr "Namn:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:77
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:76
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Hårfärg:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Frisyr:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:437
+#: src/gui/socialwindow.cpp:846
+msgid "Create"
+msgstr "Skapa"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:95
+msgid "Male"
+msgstr "Man"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:96
+msgid "Female"
+msgstr "Kvinna"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Var vänlig fördela %d poäng"
+
+#: src/gui/charcreatedialog.cpp:180
+msgid "Your name needs to be at least 4 characters."
+msgstr "Ditt namn måste vara minst 4 tecken långt."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Karaktärens värden okej"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Var vänlig ta bort %d poäng"
+
+#: src/gui/charselectdialog.cpp:72
+msgid "Confirm Character Delete"
+msgstr "Bekräfta borttagning av karaktär"
+
+#: src/gui/charselectdialog.cpp:73
+msgid "Are you sure you want to delete this character?"
+msgstr "Är du säker på att du vill ta bort den här karaktären?"
+
+#: src/gui/charselectdialog.cpp:121
+msgid "Account and Character Management"
+msgstr "Hantering av konto och karaktärer"
+
+#: src/gui/charselectdialog.cpp:132
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:146 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Avregistrera"
+
+#: src/gui/charselectdialog.cpp:155
+#, fuzzy
+msgid "Change Email"
+msgstr "Ändra epostadress"
+
+#: src/gui/charselectdialog.cpp:367 src/gui/serverdialog.cpp:248
+#: src/gui/setup_players.cpp:242 src/gui/shopwindow.cpp:117
+#: src/gui/shopwindow.cpp:120 src/gui/textcommandeditor.cpp:234
+msgid "Delete"
+msgstr "Ta bort"
+
+#: src/gui/charselectdialog.cpp:425
+#, fuzzy
+msgid "Choose"
+msgstr "Stäng"
+
+#: src/gui/charselectdialog.cpp:439 src/gui/charselectdialog.cpp:440
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:91
+#, fuzzy
+msgid "default"
+msgstr "Förval"
+
+#: src/gui/chat.cpp:92
+msgid "black"
+msgstr ""
+
+#: src/gui/chat.cpp:93
+#, fuzzy
+msgid "red"
+msgstr "Vän"
+
+#: src/gui/chat.cpp:94
+#, fuzzy
+msgid "green"
+msgstr "Grön: "
+
+#: src/gui/chat.cpp:95
+#, fuzzy
+msgid "blue"
+msgstr "Blå: "
+
+#: src/gui/chat.cpp:96
+msgid "gold"
+msgstr ""
+
+#: src/gui/chat.cpp:97
+#, fuzzy
+msgid "yellow"
+msgstr "låg"
+
+#: src/gui/chat.cpp:98
+#, fuzzy
+msgid "pink"
+msgstr "Länk"
+
+#: src/gui/chat.cpp:99
+msgid "purple"
+msgstr ""
+
+#: src/gui/chat.cpp:100
+msgid "grey"
+msgstr ""
+
+#: src/gui/chat.cpp:101
+#, fuzzy
+msgid "brown"
+msgstr "Kastvapen"
+
+#: src/gui/chat.cpp:102
+#, fuzzy
+msgid "rainbow 1"
+msgstr "Regnbåge"
+
+#: src/gui/chat.cpp:103
+#, fuzzy
+msgid "rainbow 2"
+msgstr "Regnbåge"
+
+#: src/gui/chat.cpp:104
+#, fuzzy
+msgid "rainbow 3"
+msgstr "Regnbåge"
+
+#: src/gui/chat.cpp:121 src/gui/itemamount.cpp:90 src/gui/login.cpp:75
+#: src/gui/setup_players.cpp:215 src/gui/setup_theme.cpp:68
+#: src/gui/setup_video.cpp:163 src/gui/setup_video.cpp:188
+#: src/gui/textcommandeditor.cpp:98 src/gui/textcommandeditor.cpp:137
+#: src/gui/textcommandeditor.cpp:156
+msgid "???"
+msgstr "???"
+
+#: src/gui/chat.cpp:131 src/gui/setup_chat.cpp:60
+msgid "Chat"
+msgstr "Chatt"
+
+#: src/gui/chat.cpp:554
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d spelare är närvarande."
+
+#: src/gui/chat.cpp:890
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Viskar till %s: %s"
+
+#: src/gui/confirmdialog.cpp:44
+msgid "Yes"
+msgstr "Ja"
+
+#: src/gui/confirmdialog.cpp:45
+msgid "No"
+msgstr "Nej"
+
+#: src/gui/confirmdialog.cpp:49
+#, fuzzy
+msgid "Ignore"
+msgstr "Ignorerad"
+
+#: src/gui/debugwindow.cpp:63 src/gui/debugwindow.cpp:74
+#, c-format
+msgid "%d FPS (Software)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:67
+#, c-format
+msgid "%d FPS (fast OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:70
+#, c-format
+msgid "%d FPS (old OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:77
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:78 src/gui/debugwindow.cpp:181
+#: src/gui/debugwindow.cpp:204
+#, fuzzy
+msgid "Music:"
+msgstr "Ämne: %s"
+
+#: src/gui/debugwindow.cpp:79 src/gui/debugwindow.cpp:185
+#: src/gui/debugwindow.cpp:206
+#, fuzzy
+msgid "Map:"
+msgstr "Namn: %s"
+
+#: src/gui/debugwindow.cpp:80 src/gui/debugwindow.cpp:183
+#: src/gui/debugwindow.cpp:205
+#, fuzzy
+msgid "Minimap:"
+msgstr "Minikarta"
+
+#: src/gui/debugwindow.cpp:81
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:82 src/gui/debugwindow.cpp:192
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Partikeleffekter"
+
+#: src/gui/debugwindow.cpp:84
+#, fuzzy, c-format
+msgid "Map actors count: %d"
+msgstr "Karaktärens värden okej"
+
+#: src/gui/debugwindow.cpp:90 src/gui/debugwindow.cpp:126
+#: src/gui/debugwindow.cpp:131
+#, fuzzy
+msgid "Player Position:"
+msgstr "Spelare slår monster"
+
+#: src/gui/debugwindow.cpp:91 src/gui/debugwindow.cpp:138
+#: src/gui/debugwindow.cpp:163
+#, fuzzy
+msgid "Target:"
+msgstr "Gå åt vänster"
+
+#: src/gui/debugwindow.cpp:92 src/gui/debugwindow.cpp:143
+#: src/gui/debugwindow.cpp:164
+#, fuzzy
+msgid "Target Id:"
+msgstr "Välj spelare"
+
+#: src/gui/debugwindow.cpp:93 src/gui/debugwindow.cpp:147
+#: src/gui/debugwindow.cpp:152 src/gui/debugwindow.cpp:165
+#, fuzzy
+msgid "Target Level:"
+msgstr "Välj spelare"
+
+#: src/gui/debugwindow.cpp:94 src/gui/debugwindow.cpp:155
+#: src/gui/debugwindow.cpp:166
+#, fuzzy
+msgid "Target Party:"
+msgstr "Välj spelare"
+
+#: src/gui/debugwindow.cpp:95 src/gui/debugwindow.cpp:158
+#: src/gui/debugwindow.cpp:167
+#, fuzzy
+msgid "Target Guild:"
+msgstr "Välj spelare"
+
+#: src/gui/debugwindow.cpp:179 src/gui/debugwindow.cpp:202
+#, fuzzy
+msgid "Cursor:"
+msgstr "Särskild muspekare"
+
+#: src/gui/debugwindow.cpp:196 src/gui/debugwindow.cpp:209
+msgid "Map actors count:"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:217
+#, c-format
+msgid "Ping: %d ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:222
+msgid "Ping: ? ms"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:225
+#, c-format
+msgid "In: %d bytes/s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:227
+#, c-format
+msgid "Out: %d bytes/s"
+msgstr ""
+
+#: src/gui/editdialog.cpp:44 src/gui/itemamount.cpp:205
+#: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:53 src/gui/textdialog.cpp:43
+#: src/gui/trade.cpp:81 src/gui/trade.cpp:83
+msgid "OK"
+msgstr "Okej"
+
+#: src/gui/equipmentwindow.cpp:70 src/gui/windowmenu.cpp:70
+msgid "Equipment"
+msgstr "Utrustning"
+
+#: src/gui/equipmentwindow.cpp:89 src/gui/inventorywindow.cpp:96
+#: src/gui/inventorywindow.cpp:393 src/gui/inventorywindow.cpp:402
+#: src/gui/popupmenu.cpp:1068 src/gui/popupmenu.cpp:1167
+#: src/gui/popupmenu.cpp:1207
+msgid "Unequip"
+msgstr "Avrusta"
+
+#: src/gui/help.cpp:38
+msgid "Help"
+msgstr "Hjälp"
+
+#: src/gui/help.cpp:52 src/gui/inventorywindow.cpp:135
+#: src/gui/npcdialog.cpp:48 src/gui/shopwindow.cpp:108
+msgid "Close"
+msgstr "Stäng"
+
+#: src/gui/inventorywindow.cpp:62 src/gui/windowmenu.cpp:72
+msgid "Inventory"
+msgstr "Inventarium"
+
+#: src/gui/inventorywindow.cpp:62
+msgid "Storage"
+msgstr "Lagring"
+
+#: src/gui/inventorywindow.cpp:89
+msgid "Slots:"
+msgstr "Utrymme:"
+
+#: src/gui/inventorywindow.cpp:94 src/gui/inventorywindow.cpp:395
+#: src/gui/inventorywindow.cpp:404 src/gui/popupmenu.cpp:1070
+#: src/gui/popupmenu.cpp:1169 src/gui/popupmenu.cpp:1209
+msgid "Equip"
+msgstr "Utrusta"
+
+#: src/gui/inventorywindow.cpp:95 src/gui/inventorywindow.cpp:396
+#: src/gui/inventorywindow.cpp:400 src/gui/popupmenu.cpp:1073
+#: src/gui/popupmenu.cpp:1142 src/gui/popupmenu.cpp:1173
+#: src/gui/popupmenu.cpp:1212
+msgid "Use"
+msgstr "Använd"
+
+#: src/gui/inventorywindow.cpp:109 src/gui/inventorywindow.cpp:499
+#: src/gui/popupmenu.cpp:1076 src/gui/popupmenu.cpp:1177
+#: src/gui/popupmenu.cpp:1215
+#, fuzzy
+msgid "Drop..."
+msgstr "Släpp"
+
+#: src/gui/inventorywindow.cpp:110 src/gui/popupmenu.cpp:1081
+#: src/gui/popupmenu.cpp:1182 src/gui/popupmenu.cpp:1220
+msgid "Split"
+msgstr "Dela"
+
+#: src/gui/inventorywindow.cpp:111 src/gui/outfitwindow.cpp:56
+#: src/gui/popupmenu.cpp:408
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:114
+msgid "Weight:"
+msgstr "Vikt:"
+
+#: src/gui/inventorywindow.cpp:133 src/gui/inventorywindow.cpp:490
+#: src/gui/popupmenu.cpp:1085 src/gui/popupmenu.cpp:1185
+#: src/gui/popupmenu.cpp:1223 src/gui/setup.cpp:65
+msgid "Store"
+msgstr "Lagra"
+
+#: src/gui/inventorywindow.cpp:134 src/gui/popupmenu.cpp:1104
+msgid "Retrieve"
+msgstr "Hämta"
+
+#: src/gui/inventorywindow.cpp:501 src/gui/popupmenu.cpp:1078
+#: src/gui/popupmenu.cpp:1179 src/gui/popupmenu.cpp:1217
+#: src/gui/windowmenu.cpp:91
+msgid "Drop"
+msgstr "Släpp"
+
+#: src/gui/itemamount.cpp:207
+msgid "All"
+msgstr "Alla"
+
+#: src/gui/itemamount.cpp:258
+msgid "Select amount of items to trade."
+msgstr "Välj antal föremål att handla med."
+
+#: src/gui/itemamount.cpp:261
+msgid "Select amount of items to drop."
+msgstr "Välj antal föremål att släppa."
+
+#: src/gui/itemamount.cpp:264
+msgid "Select amount of items to store."
+msgstr "Välj antal att lagra."
+
+#: src/gui/itemamount.cpp:267
+msgid "Select amount of items to retrieve."
+msgstr "Välj antal att hämta."
+
+#: src/gui/itemamount.cpp:270
+msgid "Select amount of items to split."
+msgstr "Välj antal föremål att dela."
+
+#: src/gui/itemamount.cpp:273
+msgid "Add to buy shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:276
+msgid "Add to sell shop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:279
+#, fuzzy
+msgid "Unknown."
+msgstr "Okänt fel"
+
+#: src/gui/itempopup.cpp:145
+msgid ", "
+msgstr ""
+
+#: src/gui/itempopup.cpp:152
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Vikt: "
+
+#: src/gui/killstats.cpp:43 src/gui/windowmenu.cpp:65
+#, fuzzy
+msgid "Kill stats"
+msgstr "Statusfönster"
+
+#: src/gui/killstats.cpp:61
+#, fuzzy
+msgid "Reset stats"
+msgstr "Återställ"
+
+#: src/gui/killstats.cpp:62
+#, fuzzy
+msgid "Reset timer"
+msgstr "Återställ"
+
+#: src/gui/killstats.cpp:66
+#, fuzzy
+msgid "Level: "
+msgstr "Nivå: %d"
+
+#: src/gui/killstats.cpp:70
+#, fuzzy
+msgid "Exp: "
+msgstr "EP:"
+
+#: src/gui/killstats.cpp:71
+#, fuzzy
+msgid " Left: "
+msgstr "Gå åt vänster"
+
+#: src/gui/killstats.cpp:74
+msgid " exp, Avg Mob for 1%: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:75 src/gui/killstats.cpp:128
+msgid "Kills: ?, Total Exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:76 src/gui/killstats.cpp:129
+msgid "Avg Exp: ?, No. of Avg mob to next level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:77 src/gui/killstats.cpp:146
+msgid "Kills/Min: ?, Exp/Min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:79
+msgid "Exp speed per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:80
+msgid "Time for next level per 1 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:81
+msgid "Exp speed per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:82
+msgid "Time for next level per 5 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:83
+msgid "Exp speed per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:84
+msgid "Time for Next level per 15 min: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:86
+msgid "Last kill exp: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:87
+msgid "Time before jacko spawn: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:270
+#, c-format
+msgid "Exp Speed per 1 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:275 src/gui/killstats.cpp:291
+#: src/gui/killstats.cpp:307
+#, c-format
+msgid " Time For Next Level: %f"
+msgstr ""
+
+#: src/gui/killstats.cpp:281 src/gui/killstats.cpp:297
+#: src/gui/killstats.cpp:313
+msgid " Time For Next Level: ?"
+msgstr ""
+
+#: src/gui/killstats.cpp:286
+#, c-format
+msgid "Exp Speed per 5 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:302
+#, c-format
+msgid "Exp Speed per 15 min: %d"
+msgstr ""
+
+#: src/gui/killstats.cpp:331
+msgid "Time before jacko spawn: jacko alive"
+msgstr ""
+
+#: src/gui/killstats.cpp:335 src/gui/killstats.cpp:345
+msgid "Time before jacko spawn: "
+msgstr ""
+
+#: src/gui/killstats.cpp:336
+msgid "?"
+msgstr ""
+
+#: src/gui/killstats.cpp:341
+msgid "Time before jacko spawn: jacko spawning"
+msgstr ""
+
+#: src/gui/login.cpp:56
+msgid "Normal"
+msgstr ""
+
+#: src/gui/login.cpp:57
+#, fuzzy
+msgid "Auto Close"
+msgstr "Stäng"
+
+#: src/gui/login.cpp:58
+msgid "Skip"
+msgstr ""
+
+#: src/gui/login.cpp:83 src/gui/login.cpp:118
+msgid "Login"
+msgstr "Användarnamn"
+
+#: src/gui/login.cpp:87 src/gui/serverdialog.cpp:221
+#: src/gui/widgets/chattab.cpp:166
+msgid "Server:"
+msgstr "Server:"
+
+#: src/gui/login.cpp:92
+msgid "Custom update host"
+msgstr ""
+
+#: src/gui/login.cpp:106
+#, fuzzy
+msgid "Remember username"
+msgstr "Kom ihåg användarnamnet"
+
+#: src/gui/login.cpp:107
+msgid "Update:"
+msgstr ""
+
+#: src/gui/login.cpp:116 src/gui/register.cpp:63 src/gui/register.cpp:78
+msgid "Register"
+msgstr "Registrera"
+
+#: src/gui/login.cpp:117
+#, fuzzy
+msgid "Change Server"
+msgstr "Server"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:86
+msgid "Map"
+msgstr "Karta"
+
+#: src/gui/ministatus.cpp:196
+msgid "Need"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:46
+msgid "Waiting for server"
+msgstr "Väntar på server"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Next"
+msgstr "Nästa"
+
+#: src/gui/npcdialog.cpp:49
+msgid "Submit"
+msgstr "Vidare"
+
+#: src/gui/npcdialog.cpp:54 src/gui/npcpostdialog.cpp:39
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:100 src/gui/popupmenu.cpp:447
+#, fuzzy
+msgid "Clear"
+msgstr "Spjut"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:200
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Nästa"
+
+#: src/gui/npcpostdialog.cpp:45
+msgid "To:"
+msgstr "Till:"
+
+#: src/gui/npcpostdialog.cpp:52
+msgid "Send"
+msgstr "Skicka"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+"Kunde inte skicka brevet eftersom antingen avsändaren eller brevet självt är "
+"ogiltigt."
+
+#: src/gui/outfitwindow.cpp:78 src/gui/outfitwindow.cpp:832
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:80 src/gui/outfitwindow.cpp:834
+#, fuzzy, c-format
+msgid "Key: %s"
+msgstr "Pengar: %s"
+
+#: src/gui/outfitwindow.cpp:83
+#, fuzzy
+msgid "Unequip first"
+msgstr "Avrusta"
+
+#: src/gui/outfitwindow.cpp:86
+msgid "Away outfit"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:116 src/gui/popupmenu.cpp:482
+#, fuzzy
+msgid "@@trade|Trade@@"
+msgstr "@@trade|Handla med %s@@"
+
+#. TRANSLATORS: Attacking a player.
+#: src/gui/popupmenu.cpp:118 src/gui/popupmenu.cpp:237
+#: src/gui/popupmenu.cpp:483
+#, fuzzy
+msgid "@@attack|Attack@@"
+msgstr "@@attack|Attackera %s@@"
+
+#. TRANSLATORS: Whispering a player.
+#: src/gui/popupmenu.cpp:120 src/gui/popupmenu.cpp:289
+#, fuzzy
+msgid "@@whisper|Whisper@@"
+msgstr "@@use|Använd@@"
+
+#: src/gui/popupmenu.cpp:124 src/gui/popupmenu.cpp:487
+#, fuzzy
+msgid "@@heal|Heal@@"
+msgstr "@@cancel|Avbryt@@"
+
+#: src/gui/popupmenu.cpp:130 src/gui/popupmenu.cpp:295
+#: src/gui/popupmenu.cpp:493
+#, fuzzy
+msgid "@@friend|Befriend@@"
+msgstr "@@retrieve|Hämta@@"
+
+#: src/gui/popupmenu.cpp:131 src/gui/popupmenu.cpp:136
+#: src/gui/popupmenu.cpp:154 src/gui/popupmenu.cpp:296
+#: src/gui/popupmenu.cpp:302 src/gui/popupmenu.cpp:320
+#: src/gui/popupmenu.cpp:494 src/gui/popupmenu.cpp:499
+#: src/gui/popupmenu.cpp:517
+#, fuzzy
+msgid "@@disregard|Disregard@@"
+msgstr "@@disregard|Strunta i %s@@"
+
+#: src/gui/popupmenu.cpp:132 src/gui/popupmenu.cpp:137
+#: src/gui/popupmenu.cpp:297 src/gui/popupmenu.cpp:303
+#: src/gui/popupmenu.cpp:495 src/gui/popupmenu.cpp:500
+#, fuzzy
+msgid "@@ignore|Ignore@@"
+msgstr "@@ignore|Ignorera %s@@"
+
+#: src/gui/popupmenu.cpp:133 src/gui/popupmenu.cpp:138
+#: src/gui/popupmenu.cpp:144 src/gui/popupmenu.cpp:149
+#: src/gui/popupmenu.cpp:298 src/gui/popupmenu.cpp:304
+#: src/gui/popupmenu.cpp:310 src/gui/popupmenu.cpp:315
+#: src/gui/popupmenu.cpp:496 src/gui/popupmenu.cpp:501
+#: src/gui/popupmenu.cpp:507 src/gui/popupmenu.cpp:512
+#, fuzzy
+msgid "@@erase|Erase@@"
+msgstr "@@use|Använd@@"
+
+#: src/gui/popupmenu.cpp:142 src/gui/popupmenu.cpp:148
+#: src/gui/popupmenu.cpp:153 src/gui/popupmenu.cpp:308
+#: src/gui/popupmenu.cpp:314 src/gui/popupmenu.cpp:319
+#: src/gui/popupmenu.cpp:505 src/gui/popupmenu.cpp:511
+#: src/gui/popupmenu.cpp:516
+#, fuzzy
+msgid "@@unignore|Unignore@@"
+msgstr "@@unignore|Sluta ignorera %s@@"
+
+#: src/gui/popupmenu.cpp:143 src/gui/popupmenu.cpp:155
+#: src/gui/popupmenu.cpp:309 src/gui/popupmenu.cpp:321
+#: src/gui/popupmenu.cpp:506 src/gui/popupmenu.cpp:518
+#, fuzzy
+msgid "@@ignore|Completely ignore@@"
+msgstr "@@ignore|Ignorera %s fullständigt@@"
+
+#: src/gui/popupmenu.cpp:163 src/gui/popupmenu.cpp:329
+#: src/gui/popupmenu.cpp:526
+msgid "@@follow|Follow@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:164 src/gui/popupmenu.cpp:330
+#: src/gui/popupmenu.cpp:527
+msgid "@@imitation|Imitation@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174 src/gui/popupmenu.cpp:546
+#, fuzzy
+msgid "@@party|Invite to party@@"
+msgstr "/party > Bjud in en spelare till din grupp"
+
+#: src/gui/popupmenu.cpp:179 src/gui/popupmenu.cpp:551
+#, fuzzy
+msgid "@@kick party|Kick from party@@"
+msgstr "@@admin-kick|Sparka spelare@@"
+
+#: src/gui/popupmenu.cpp:194 src/gui/popupmenu.cpp:337
+#: src/gui/popupmenu.cpp:565
+#, fuzzy
+msgid "@@guild-kick|Kick from guild@@"
+msgstr "@@admin-kick|Sparka spelare@@"
+
+#: src/gui/popupmenu.cpp:196 src/gui/popupmenu.cpp:338
+#: src/gui/popupmenu.cpp:567
+msgid "@@guild-pos|Change pos in guild >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:201 src/gui/popupmenu.cpp:342
+#: src/gui/popupmenu.cpp:572
+#, fuzzy
+msgid "@@guild|Invite to guild@@"
+msgstr "/party > Bjud in en spelare till din grupp"
+
+#: src/gui/popupmenu.cpp:208
+msgid "@@admin-kick|Kick player@@"
+msgstr "@@admin-kick|Sparka spelare@@"
+
+#: src/gui/popupmenu.cpp:210
+msgid "@@nuke|Nuke@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:211 src/gui/popupmenu.cpp:231
+#: src/gui/popupmenu.cpp:528
+msgid "@@move|Move@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:212 src/gui/popupmenu.cpp:529
+#, fuzzy
+msgid "@@undress|Undress@@"
+msgstr "@@unignore|Sluta ignorera %s@@"
+
+#: src/gui/popupmenu.cpp:217 src/gui/popupmenu.cpp:228
+#: src/gui/popupmenu.cpp:349 src/gui/popupmenu.cpp:534
+msgid "@@buy|Buy@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:218 src/gui/popupmenu.cpp:229
+#: src/gui/popupmenu.cpp:350 src/gui/popupmenu.cpp:535
+#, fuzzy
+msgid "@@sell|Sell@@"
+msgstr "@@use|Använd@@"
+
+#: src/gui/popupmenu.cpp:226
+#, fuzzy
+msgid "@@talk|Talk@@"
+msgstr "@@attack|Attackera %s@@"
+
+#: src/gui/popupmenu.cpp:240
+#, fuzzy
+msgid "@@admin-kick|Kick@@"
+msgstr "@@admin-kick|Sparka spelare@@"
+
+#: src/gui/popupmenu.cpp:248 src/gui/popupmenu.cpp:353
+#, fuzzy
+msgid "@@name|Add name to chat@@"
+msgstr "@@name|Använd namn i chatt@@"
+
+#: src/gui/popupmenu.cpp:252 src/gui/popupmenu.cpp:272
+#: src/gui/popupmenu.cpp:357 src/gui/popupmenu.cpp:380
+#: src/gui/popupmenu.cpp:399 src/gui/popupmenu.cpp:412
+#: src/gui/popupmenu.cpp:430 src/gui/popupmenu.cpp:577
+#: src/gui/popupmenu.cpp:601
+msgid "@@cancel|Cancel@@"
+msgstr "@@cancel|Avbryt@@"
+
+#: src/gui/popupmenu.cpp:267
+#, c-format
+msgid "@@player_%u|%s >@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:375
+#, fuzzy
+msgid "@@pickup|Pick up@@"
+msgstr "@@pickup|Plocka upp %s@@"
+
+#: src/gui/popupmenu.cpp:376
+#, fuzzy
+msgid "@@chat|Add to chat@@"
+msgstr "@@chat|Nämn i chattfönstret@@"
+
+#: src/gui/popupmenu.cpp:394
+msgid "Map Item"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:395
+msgid "@@rename map|Rename@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:396
+msgid "@@remove map|Remove@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:409
+msgid "@@load old outfits|Load old outfits@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:425 src/gui/windowmenu.cpp:90
+msgid "Spells"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:426
+msgid "@@load old spells|Load old spells@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:427
+#, fuzzy
+msgid "@@edit spell|Edit spell@@"
+msgstr "@@use|Använd@@"
+
+#: src/gui/popupmenu.cpp:445
+msgid "@@chat close|Close@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:453
+#, fuzzy
+msgid "Disable highlight"
+msgstr "Flikmarkering"
+
+#: src/gui/popupmenu.cpp:459
+#, fuzzy
+msgid "Enable highlight"
+msgstr "Flikmarkering"
+
+#: src/gui/popupmenu.cpp:465
+msgid "@@leave party|Leave@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:585
+#, fuzzy
+msgid "Change guild position"
+msgstr "Ändra"
+
+#: src/gui/popupmenu.cpp:598
+#, c-format
+msgid "@@guild-pos-%d|%s@@"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:942
+msgid "Rename map sign "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:943
+msgid "Name: "
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1091
+#, fuzzy
+msgid "Store 10"
+msgstr "Lagra"
+
+#: src/gui/popupmenu.cpp:1094
+#, fuzzy
+msgid "Store half"
+msgstr "Lagra"
+
+#: src/gui/popupmenu.cpp:1096
+#, fuzzy
+msgid "Store all"
+msgstr "Lagra"
+
+#: src/gui/popupmenu.cpp:1110
+#, fuzzy
+msgid "Retrieve 10"
+msgstr "Hämta"
+
+#: src/gui/popupmenu.cpp:1113
+#, fuzzy
+msgid "Retrieve half"
+msgstr "Hämta"
+
+#: src/gui/popupmenu.cpp:1115
+#, fuzzy
+msgid "Retrieve all"
+msgstr "Hämta"
+
+#: src/gui/popupmenu.cpp:1118 src/gui/popupmenu.cpp:1186
+#: src/gui/popupmenu.cpp:1224
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Nämn i chattfönstret@@"
+
+#: src/gui/popupmenu.cpp:1145 src/gui/popupmenu.cpp:1190
+msgid "Load old item shortcuts"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:1228
+msgid "Load old drop shortcuts"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:50
+msgid "Save state"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:51
+msgid "Switch server"
+msgstr "Byt server"
+
+#: src/gui/quitdialog.cpp:52
+msgid "Switch character"
+msgstr "Byt karaktär"
+
+#: src/gui/register.cpp:74
+msgid "Confirm:"
+msgstr "Bekräfta:"
+
+#: src/gui/register.cpp:105
+msgid "Email:"
+msgstr "E-post:"
+
+#: src/gui/register.cpp:173
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Användarnamnet måste vara minst %d tecken långt."
+
+#: src/gui/register.cpp:181
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Användarnamnet måste vara kortare än %d tecken."
+
+#: src/gui/register.cpp:189 src/gui/unregisterdialog.cpp:118
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Lösenordet måste vara minst %d tecken långt."
+
+#: src/gui/register.cpp:197 src/gui/unregisterdialog.cpp:125
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Lösenordet måste vara kortare än %d tecken."
+
+#: src/gui/register.cpp:204
+msgid "Passwords do not match."
+msgstr "Lösenorden stämmer inte överens."
+
+#: src/gui/serverdialog.cpp:207
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Välj din server"
+
+#: src/gui/serverdialog.cpp:222
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:223
+#, fuzzy
+msgid "Server type:"
+msgstr "Server:"
+
+#: src/gui/serverdialog.cpp:245
+msgid "Load"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:246
+#, fuzzy
+msgid "Connect"
+msgstr "Ansluter..."
+
+#: src/gui/serverdialog.cpp:247
+#, fuzzy
+msgid "Custom Server"
+msgstr "Särskild muspekare"
+
+#: src/gui/serverdialog.cpp:351
+msgid "Please type both the address and the port of a server."
+msgstr "Var vänlig skriv både adressen och porten till en server."
+
+#: src/gui/serverdialog.cpp:482
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:488
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Väntar på server"
+
+#: src/gui/serverdialog.cpp:492
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:496
+msgid "Error retreiving server list!"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:593
+msgid "requires a newer version"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:595
+#, c-format
+msgid "requires v%s"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:46
+msgid "Enable Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Enable game sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:48
+msgid "Enable gui sfx"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:49
+#, fuzzy
+msgid "Enable music"
+msgstr "Aktivera joystick"
+
+#: src/gui/setup_audio.cpp:50
+#, fuzzy
+msgid "Enable mumble voice chat"
+msgstr "Aktivera joystick"
+
+#: src/gui/setup_audio.cpp:52
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:57
+msgid "Audio"
+msgstr "Ljud"
+
+#: src/gui/setup_audio.cpp:60
+msgid "Sfx volume"
+msgstr "Volym för ljudeffekter"
+
+#: src/gui/setup_audio.cpp:61
+msgid "Music volume"
+msgstr "Musikvolym"
+
+#: src/gui/setup_audio.cpp:117
+#, fuzzy
+msgid "Notice"
+msgstr "Ingen text"
+
+#: src/gui/setup_audio.cpp:117
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:130
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:64
+msgid "Remove colors from received chat messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:68
+msgid "Log magic messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:75
+msgid "Allow magic and GM commands in all chat tabs"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:80
+msgid "Show server messages in debug tab"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:84
+msgid "Enable chat Log"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:88
+#, fuzzy
+msgid "Enable trade tab"
+msgstr "Kan inte köpa."
+
+#: src/gui/setup_chat.cpp:92
+msgid "Hide shop messages"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:96
+msgid "Show chat history"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:100
+#, fuzzy
+msgid "Enable battle tab"
+msgstr "Kan inte köpa."
+
+#: src/gui/setup_chat.cpp:104
+#, fuzzy
+msgid "Show battle events"
+msgstr "Visa namn"
+
+#: src/gui/setup_chat.cpp:108
+msgid "Show chat colors list"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:111 src/gui/setup_chat.cpp:119
+#: src/gui/setup_other.cpp:135 src/gui/setup_other.cpp:139
+msgid "Edit"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:114
+msgid "Limit max chars in chat line"
+msgstr ""
+
+#: src/gui/setup_chat.cpp:123
+msgid "Limit max lines in chat"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:46
+msgid "This is what the color looks like"
+msgstr "Så här ser färgen ut"
+
+#: src/gui/setup_colors.cpp:51
+msgid "Colors"
+msgstr "Färger"
+
+#: src/gui/setup_colors.cpp:72
+#, fuzzy
+msgid "Type:"
+msgstr "Typ: "
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:398
+msgid "Static"
+msgstr "Statisk"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:399
+msgid "Pulse"
+msgstr "Pulserande"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:400
+msgid "Rainbow"
+msgstr "Regnbåge"
+
+#: src/gui/setup_colors.cpp:89 src/gui/setup_colors.cpp:90
+#: src/gui/setup_colors.cpp:400
+msgid "Spectrum"
+msgstr "Spektrum"
+
+#: src/gui/setup_colors.cpp:94 src/gui/setup_colors.cpp:310
+#, fuzzy
+msgid "Delay:"
+msgstr "Fördröjning: "
+
+#: src/gui/setup_colors.cpp:109
+#, fuzzy
+msgid "Red:"
+msgstr "Röd: "
+
+#: src/gui/setup_colors.cpp:124
+#, fuzzy
+msgid "Green:"
+msgstr "Grön: "
+
+#: src/gui/setup_colors.cpp:139
+#, fuzzy
+msgid "Blue:"
+msgstr "Blå: "
+
+#: src/gui/setup_colors.cpp:305
+msgid "Alpha:"
+msgstr ""
+
+#: src/gui/setup.cpp:63
+msgid "Apply"
+msgstr "Verkställ"
+
+#: src/gui/setup.cpp:66
+msgid "Reset Windows"
+msgstr "Återställ fönster"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:76
+msgid "Press the button to start calibration"
+msgstr "Klicka på knappen för att starta kalibreringen"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:74
+msgid "Calibrate"
+msgstr "Kalibrera"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Aktivera joystick"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Joystick"
+
+#: src/gui/setup_joystick.cpp:81
+msgid "Stop"
+msgstr "Stopp"
+
+#: src/gui/setup_joystick.cpp:82
+msgid "Rotate the stick"
+msgstr "Rotera spaken"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Tangentbord"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Tilldela"
+
+#: src/gui/setup_keyboard.cpp:90
+#, fuzzy
+msgid "Unassign"
+msgstr "Tilldela"
+
+#: src/gui/setup_keyboard.cpp:94
+msgid "Default"
+msgstr "Förval"
+
+#: src/gui/setup_keyboard.cpp:130
+msgid "Key Conflict(s) Detected."
+msgstr "Samma tangent används på flera ställen."
+
+#: src/gui/setup_other.cpp:92
+msgid "Misc"
+msgstr ""
+
+#: src/gui/setup_other.cpp:95
+msgid "Show damage inflicted to monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:100
+msgid "Auto target only reachable monsters"
+msgstr ""
+
+#: src/gui/setup_other.cpp:104
+#, fuzzy
+msgid "Highlight map portals"
+msgstr "Markering"
+
+#: src/gui/setup_other.cpp:109
+msgid "Highlight player attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:114
+msgid "Highlight monster attack range"
+msgstr ""
+
+#: src/gui/setup_other.cpp:118
+msgid "Cycle player targets"
+msgstr ""
+
+#: src/gui/setup_other.cpp:121
+#, fuzzy
+msgid "Cycle monster targets"
+msgstr "Visa namn"
+
+#: src/gui/setup_other.cpp:124
+#, fuzzy
+msgid "Enable bot checker"
+msgstr "Aktivera joystick"
+
+#: src/gui/setup_other.cpp:127
+#, fuzzy
+msgid "Highlight floor items"
+msgstr "Markering"
+
+#: src/gui/setup_other.cpp:130
+msgid "Crazy move A program"
+msgstr ""
+
+#: src/gui/setup_other.cpp:141
+#, fuzzy
+msgid "Enable shop mode"
+msgstr "Tillåt/neka handel"
+
+#: src/gui/setup_other.cpp:145
+msgid "Enable buggy servers protection"
+msgstr ""
+
+#: src/gui/setup_other.cpp:149
+#, fuzzy
+msgid "Enable debug log"
+msgstr "Kan inte köpa."
+
+#: src/gui/setup_other.cpp:153
+#, fuzzy
+msgid "Enable server side attack"
+msgstr "Kan inte köpa."
+
+#: src/gui/setup_other.cpp:157
+msgid "Auto fix position"
+msgstr ""
+
+#: src/gui/setup_other.cpp:161
+msgid "Attack while moving"
+msgstr ""
+
+#: src/gui/setup_other.cpp:165
+#, fuzzy
+msgid "Enable quick stats"
+msgstr "Aktivera joystick"
+
+#: src/gui/setup_other.cpp:169
+#, fuzzy
+msgid "Show warps particles"
+msgstr "som partikel"
+
+#: src/gui/setup_other.cpp:173
+msgid "Accept sell/buy requests"
+msgstr ""
+
+#: src/gui/setup_other.cpp:177
+msgid "Show monster hp bar"
+msgstr ""
+
+#: src/gui/setup_players.cpp:60
+msgid "Relation"
+msgstr "Relation"
+
+#: src/gui/setup_players.cpp:65
+msgid "Neutral"
+msgstr "Neutral"
+
+#: src/gui/setup_players.cpp:66
+msgid "Friend"
+msgstr "Vän"
+
+#: src/gui/setup_players.cpp:67
+msgid "Disregarded"
+msgstr "Förbisedd"
+
+#: src/gui/setup_players.cpp:68
+msgid "Ignored"
+msgstr "Ignorerad"
+
+#: src/gui/setup_players.cpp:69
+msgid "Erased"
+msgstr ""
+
+#: src/gui/setup_players.cpp:238
+msgid "Allow trading"
+msgstr "Tillåt byteshandel"
+
+#: src/gui/setup_players.cpp:240
+msgid "Allow whispers"
+msgstr "Tillåt viskningar"
+
+#: src/gui/setup_players.cpp:243
+msgid "Old"
+msgstr ""
+
+#: src/gui/setup_players.cpp:245
+msgid "Put all whispers in tabs"
+msgstr "Visa alla viskningar i egna flikar"
+
+#: src/gui/setup_players.cpp:248
+#, fuzzy
+msgid "Show gender"
+msgstr "Visa namn"
+
+#: src/gui/setup_players.cpp:253
+msgid "Players"
+msgstr "Spelare"
+
+#: src/gui/setup_players.cpp:278
+msgid "When ignoring:"
+msgstr "Vid ignorering:"
+
+#: src/gui/setup_players.cpp:301
+#, fuzzy
+msgid "Show level"
+msgstr "Visa namn"
+
+#: src/gui/setup_players.cpp:305
+#, fuzzy
+msgid "Show own name"
+msgstr "Visa namn"
+
+#: src/gui/setup_players.cpp:309
+#, fuzzy
+msgid "Target dead players"
+msgstr "Välj spelare"
+
+#: src/gui/setup_theme.cpp:107
+msgid "Theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:109
+msgid "Gui theme"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:110
+msgid "Main Font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:111
+msgid "Bold font"
+msgstr ""
+
+#: src/gui/setup_theme.cpp:112
+#, fuzzy
+msgid "Particle font"
+msgstr "Partikeleffekter"
+
+#: src/gui/setup_theme.cpp:113
+#, fuzzy
+msgid "Help font"
+msgstr "Hjälp"
+
+#: src/gui/setup_theme.cpp:223
+#, fuzzy
+msgid "Theme Changed"
+msgstr "Ändra"
+
+#: src/gui/setup_theme.cpp:224 src/gui/setup_video.cpp:714
+#: src/gui/setup_video.cpp:719
+msgid "Restart your client for the change to take effect."
+msgstr "Starta om din klient för att ändringen ska börja gälla."
+
+#: src/gui/setup_video.cpp:143
+#, fuzzy
+msgid "Tiny (10)"
+msgstr "Pytteliten"
+
+#: src/gui/setup_video.cpp:144
+#, fuzzy
+msgid "Small (11)"
+msgstr "Liten"
+
+#: src/gui/setup_video.cpp:145
+#, fuzzy
+msgid "Medium (12)"
+msgstr "Mellan"
+
+#: src/gui/setup_video.cpp:146
+#, fuzzy
+msgid "Large (13)"
+msgstr "Stor"
+
+#: src/gui/setup_video.cpp:147
+msgid "Big (14)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:148
+msgid "Huge (15)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:171
+msgid "Software"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+#, fuzzy
+msgid "Fast OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:173
+#, fuzzy
+msgid "Safe OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:200
+msgid "No text"
+msgstr "Ingen text"
+
+#: src/gui/setup_video.cpp:202
+msgid "Text"
+msgstr "Text"
+
+#: src/gui/setup_video.cpp:204
+msgid "Bubbles, no names"
+msgstr "Textbubblor utan namn"
+
+#: src/gui/setup_video.cpp:206
+msgid "Bubbles with names"
+msgstr "Textbubblor med namn"
+
+#: src/gui/setup_video.cpp:219
+msgid "off"
+msgstr "av"
+
+#: src/gui/setup_video.cpp:221 src/gui/setup_video.cpp:238
+msgid "low"
+msgstr "låg"
+
+#: src/gui/setup_video.cpp:223 src/gui/setup_video.cpp:242
+msgid "high"
+msgstr "hög"
+
+#: src/gui/setup_video.cpp:240
+msgid "medium"
+msgstr "medium"
+
+#: src/gui/setup_video.cpp:244
+msgid "max"
+msgstr "maximal"
+
+#: src/gui/setup_video.cpp:276
+msgid "Full screen"
+msgstr "Helskärm"
+
+#: src/gui/setup_video.cpp:277
+#, fuzzy
+msgid "Hw acceleration"
+msgstr "Relation"
+
+#: src/gui/setup_video.cpp:278
+msgid "Custom cursor"
+msgstr "Särskild muspekare"
+
+#: src/gui/setup_video.cpp:280
+msgid "Visible names"
+msgstr "Synliga namn"
+
+#: src/gui/setup_video.cpp:282
+msgid "Particle effects"
+msgstr "Partikeleffekter"
+
+#: src/gui/setup_video.cpp:284
+msgid "Log NPC dialogue"
+msgstr ""
+
+#: src/gui/setup_video.cpp:285
+msgid "Show pickup notification"
+msgstr "Visa erhållna saker"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:287
+msgid "in chat"
+msgstr "i chattfönster"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:289
+msgid "as particle"
+msgstr "som partikel"
+
+#: src/gui/setup_video.cpp:291
+msgid "Hide shield sprite"
+msgstr ""
+
+#: src/gui/setup_video.cpp:293
+msgid "Low traffic mode"
+msgstr ""
+
+#: src/gui/setup_video.cpp:295
+msgid "Sync player move"
+msgstr ""
+
+#: src/gui/setup_video.cpp:297
+msgid "Draw hotkeys on map"
+msgstr ""
+
+#: src/gui/setup_video.cpp:299
+msgid "Draw path"
+msgstr ""
+
+#: src/gui/setup_video.cpp:300
+msgid "Show job"
+msgstr ""
+
+#: src/gui/setup_video.cpp:301
+#, fuzzy
+msgid "Enable opacity cache"
+msgstr "Aktivera joystick"
+
+#: src/gui/setup_video.cpp:302
+#, fuzzy
+msgid "Show background"
+msgstr "Bakgrund"
+
+#: src/gui/setup_video.cpp:307
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS-gräns:"
+
+#: src/gui/setup_video.cpp:311 src/gui/setup_video.cpp:350
+#: src/gui/setup_video.cpp:646 src/gui/setup_video.cpp:809
+#, fuzzy
+msgid "Alt FPS limit: "
+msgstr "FPS-gräns:"
+
+#: src/gui/setup_video.cpp:321
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:326
+msgid "Overhead text"
+msgstr "Text ovanför huvudet"
+
+#: src/gui/setup_video.cpp:327
+msgid "Gui opacity"
+msgstr "Genomskinlighet"
+
+#: src/gui/setup_video.cpp:328
+msgid "Ambient FX"
+msgstr "Omgivande FX"
+
+#: src/gui/setup_video.cpp:329
+#, fuzzy
+msgid "Particle detail"
+msgstr "Partikeldetaljer"
+
+#: src/gui/setup_video.cpp:330
+msgid "Font size"
+msgstr "Typsnittsgrad"
+
+#: src/gui/setup_video.cpp:348 src/gui/setup_video.cpp:351
+#: src/gui/setup_video.cpp:645 src/gui/setup_video.cpp:796
+#: src/gui/setup_video.cpp:807
+#, fuzzy
+msgid "None"
+msgstr "Nej"
+
+#: src/gui/setup_video.cpp:528
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "läge och återgång till det gamla läget misslyckades också!"
+
+#: src/gui/setup_video.cpp:534
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "läge och återgång till det gamla läget misslyckades också!"
+
+#: src/gui/setup_video.cpp:545
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Byte till helskärm"
+
+#: src/gui/setup_video.cpp:546
+msgid "Restart needed for changes to take effect."
+msgstr "Omstart krävs för att ändringarna ska synas."
+
+#: src/gui/setup_video.cpp:558
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Ändrar OpenGL"
+
+#: src/gui/setup_video.cpp:559
+msgid "Applying change to OpenGL requires restart."
+msgstr "Ändringar i OpenGL kräver omstart."
+
+#: src/gui/setup_video.cpp:697
+msgid "Custom resolution (example: 1024x768)"
+msgstr ""
+
+#: src/gui/setup_video.cpp:698
+msgid "Enter new resolution: "
+msgstr ""
+
+#: src/gui/setup_video.cpp:713 src/gui/setup_video.cpp:718
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Skärmupplösning ändrad"
+
+#: src/gui/setup_video.cpp:716
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:750
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Inställningar för partikeleffekter ändrade."
+
+#: src/gui/setup_video.cpp:751
+msgid "Changes will take effect on map change."
+msgstr "Förändringar kommer att börja gälla när du byter karta."
+
+#: src/gui/shopwindow.cpp:71
+msgid "Personal Shop"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:113
+msgid "Buy items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:114
+msgid "Sell items"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:116 src/gui/shopwindow.cpp:119 src/gui/trade.cpp:85
+msgid "Add"
+msgstr "Lägg till"
+
+#: src/gui/shopwindow.cpp:118 src/gui/shopwindow.cpp:121
+msgid "Announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:122
+msgid "Show links in announce"
+msgstr ""
+
+#: src/gui/shopwindow.cpp:706 src/net/manaserv/tradehandler.cpp:126
+#: src/net/tmwa/tradehandler.cpp:121
+msgid "Request for Trade"
+msgstr "Förfrågan om byteshandel"
+
+#: src/gui/shopwindow.cpp:707
+#, fuzzy, c-format
+msgid "%s wants to %s %s do you accept?"
+msgstr "%s vill byteshandla med dig, accepterar du?"
+
+#: src/gui/skilldialog.cpp:227 src/gui/windowmenu.cpp:77
+msgid "Skills"
+msgstr "Färdigheter"
+
+#: src/gui/skilldialog.cpp:238
+msgid "Up"
+msgstr "Upp"
+
+#: src/gui/skilldialog.cpp:290
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "Färdighetspoäng: %d"
+
+#: src/gui/skilldialog.cpp:374
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "Färdighetspoäng: %d"
+
+#: src/gui/skilldialog.cpp:384
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Färdigheter"
+
+#: src/gui/skilldialog.cpp:469
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Nivå: %d"
+
+#: src/gui/skilldialog.cpp:477
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Nivå: %d"
+
+#: src/gui/socialwindow.cpp:114 src/net/tmwa/gui/guildtab.cpp:47
+msgid "Guild"
+msgstr "Gille"
+
+#: src/gui/socialwindow.cpp:143
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:157
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "Gille skapat."
+
+#: src/gui/socialwindow.cpp:184
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:185
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:194
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Skapa gille"
+
+#: src/gui/socialwindow.cpp:195
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Är du säker på att du vill avsluta?"
+
+#: src/gui/socialwindow.cpp:212 src/net/tmwa/gui/partytab.cpp:47
+msgid "Party"
+msgstr "Grupp"
+
+#: src/gui/socialwindow.cpp:240
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Bjud in en spelare till din grupp"
+
+#: src/gui/socialwindow.cpp:254
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:281
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Bjud in en spelare till din grupp"
+
+#: src/gui/socialwindow.cpp:282
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:291
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:292
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Är du säker på att du vill avsluta?"
+
+#: src/gui/socialwindow.cpp:514
+msgid "Nav"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:783
+msgid "Create Guild"
+msgstr "Skapa gille"
+
+#: src/gui/socialwindow.cpp:784 src/gui/socialwindow.cpp:1186
+#, fuzzy
+msgid "Create Party"
+msgstr "Skapa karaktär"
+
+#: src/gui/socialwindow.cpp:826 src/gui/windowmenu.cpp:87
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:847
+#, fuzzy
+msgid "Invite"
+msgstr "Bjud in spelare"
+
+#: src/gui/socialwindow.cpp:848
+#, fuzzy
+msgid "Leave"
+msgstr "Stor"
+
+#: src/gui/socialwindow.cpp:975
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Accepterade injudan från %s."
+
+#: src/gui/socialwindow.cpp:985
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Avslog inbjudan från %s."
+
+#: src/gui/socialwindow.cpp:1002
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Accepterade injudan från %s."
+
+#: src/gui/socialwindow.cpp:1012
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Avslog inbjudan från %s."
+
+#: src/gui/socialwindow.cpp:1056
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "Kunde inte skapa gille."
+
+#: src/gui/socialwindow.cpp:1079
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1093
+#, fuzzy
+msgid "Guild Name"
+msgstr "Gille"
+
+#: src/gui/socialwindow.cpp:1094
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Välj din server"
+
+#: src/gui/socialwindow.cpp:1108
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Mottog en gruppinbjudan, men du har redan en annan inbjudan."
+
+#: src/gui/socialwindow.cpp:1114
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s har bjudit in dig till %ss grupp."
+
+#: src/gui/socialwindow.cpp:1120
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Acceptera gruppinbjudan"
+
+#: src/gui/socialwindow.cpp:1135
+msgid "Received party request, but one already exists."
+msgstr "Mottog en gruppinbjudan, men du har redan en annan inbjudan."
+
+#: src/gui/socialwindow.cpp:1146
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s har bjudit in dig till sin grupp."
+
+#: src/gui/socialwindow.cpp:1150
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s har bjudit in dig till %ss grupp."
+
+#: src/gui/socialwindow.cpp:1158
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s har bjudit in dig till sin grupp."
+
+#: src/gui/socialwindow.cpp:1163
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s har bjudit in dig till %ss grupp."
+
+#: src/gui/socialwindow.cpp:1172
+msgid "Accept Party Invite"
+msgstr "Acceptera gruppinbjudan"
+
+#: src/gui/socialwindow.cpp:1187
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:1192
+#, fuzzy
+msgid "Party Name"
+msgstr "Grupp"
+
+#: src/gui/socialwindow.cpp:1193
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Välj din server"
+
+#: src/gui/specialswindow.cpp:79 src/gui/windowmenu.cpp:83
+msgid "Specials"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:126 src/gui/statuswindow.cpp:252
+#: src/gui/statuswindow.cpp:311
+#, c-format
+msgid "Level: %d"
+msgstr "Nivå: %d"
+
+#: src/gui/statuswindow.cpp:127 src/gui/statuswindow.cpp:238
+#: src/gui/statuswindow.cpp:278
+#, c-format
+msgid "Money: %s"
+msgstr "Pengar: %s"
+
+#: src/gui/statuswindow.cpp:133
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:140
+msgid "Exp:"
+msgstr "EP:"
+
+#: src/gui/statuswindow.cpp:154
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:186 src/gui/statuswindow.cpp:327
+#, c-format
+msgid "Job: %d"
+msgstr "Jobb: %d"
+
+#: src/gui/statuswindow.cpp:187
+msgid "Job:"
+msgstr "Jobb:"
+
+#: src/gui/statuswindow.cpp:241 src/gui/statuswindow.cpp:285
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Karaktärens värden okej"
+
+#: src/gui/statuswindow.cpp:247
+#, fuzzy, c-format
+msgid "Level: %d (GM %d)"
+msgstr "Nivå: %d"
+
+#: src/gui/statuswindow.cpp:299
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "Färdighetspoäng: %d"
+
+#: src/gui/textcommandeditor.cpp:109
+#, fuzzy
+msgid "No Target"
+msgstr "Gå åt vänster"
+
+#: src/gui/textcommandeditor.cpp:110
+#, fuzzy
+msgid "Allow Target"
+msgstr "Tillåt byteshandel"
+
+#: src/gui/textcommandeditor.cpp:111
+#, fuzzy
+msgid "Need Target"
+msgstr "Gå åt vänster"
+
+#: src/gui/textcommandeditor.cpp:116
+#, fuzzy
+msgid "General Magic"
+msgstr "Allmänt"
+
+#: src/gui/textcommandeditor.cpp:117
+#, fuzzy
+msgid "Life Magic"
+msgstr "Magi"
+
+#: src/gui/textcommandeditor.cpp:118
+#, fuzzy
+msgid "War Magic"
+msgstr "Magi"
+
+#: src/gui/textcommandeditor.cpp:119
+msgid "Transmute Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:120
+msgid "Nature Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:121
+msgid "Astral Magic"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:164
+#, fuzzy
+msgid "Command Editor"
+msgstr "Kommando: /item"
+
+#: src/gui/textcommandeditor.cpp:181
+#, fuzzy
+msgid "magic"
+msgstr "Magi"
+
+#: src/gui/textcommandeditor.cpp:185
+msgid "other"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:190
+msgid "Symbol:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:193
+#, fuzzy
+msgid "Command:"
+msgstr "Kommando: /who"
+
+#: src/gui/textcommandeditor.cpp:196
+msgid "Mana:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:201
+#, fuzzy
+msgid "Target Type:"
+msgstr "Välj spelare"
+
+#: src/gui/textcommandeditor.cpp:206
+msgid "Icon:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:212
+#, fuzzy
+msgid "Magic level:"
+msgstr "Maxnivå"
+
+#: src/gui/textcommandeditor.cpp:217
+msgid "Magic School:"
+msgstr ""
+
+#: src/gui/textcommandeditor.cpp:223
+#, fuzzy
+msgid "School level:"
+msgstr "Visa namn"
+
+#: src/gui/textcommandeditor.cpp:228
+msgid "Save"
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Propose trade"
+msgstr "Föreslå handel"
+
+#: src/gui/trade.cpp:55
+msgid "Confirmed. Waiting..."
+msgstr "Bekräftat. Väntar…"
+
+#: src/gui/trade.cpp:56
+msgid "Agree trade"
+msgstr "Godkänn handel"
+
+#: src/gui/trade.cpp:57
+msgid "Agreed. Waiting..."
+msgstr "Godkänt. Väntar…"
+
+#: src/gui/trade.cpp:60
+msgid "Trade: You"
+msgstr "Byteshandel: du"
+
+#: src/gui/trade.cpp:82 src/gui/trade.cpp:83 src/gui/widgets/tradetab.cpp:41
+msgid "Trade"
+msgstr "Byteshandla"
+
+#: src/gui/trade.cpp:107 src/gui/trade.cpp:148
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Du får %s."
+
+#: src/gui/trade.cpp:108
+msgid "You give:"
+msgstr "Du ger:"
+
+#: src/gui/trade.cpp:112
+msgid "Change"
+msgstr "Ändra"
+
+#: src/gui/trade.cpp:312
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+"Kan inte lägga till vald sak. Det går inte att byteshandla med samma slags "
+"sak flera gånger."
+
+#: src/gui/trade.cpp:357
+msgid "You don't have enough money."
+msgstr "Du har inte tillräckligt med pengar."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Namn: %s"
+
+#: src/gui/updatewindow.cpp:132
+msgid "Updating..."
+msgstr "Uppdaterar..."
+
+#: src/gui/updatewindow.cpp:151
+msgid "Connecting..."
+msgstr "Ansluter..."
+
+#: src/gui/updatewindow.cpp:154
+msgid "Play"
+msgstr "Spela"
+
+#: src/gui/updatewindow.cpp:534
+msgid "##1 The update process is incomplete."
+msgstr "##1 Uppdateringsprocessen är inte avslutad."
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:536
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Det rekommenderar verkligen att"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:538
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 du försöker igen senare"
+
+#: src/gui/updatewindow.cpp:663
+msgid "Completed"
+msgstr "Färdig"
+
+#: src/gui/userpalette.cpp:109
+msgid "Being"
+msgstr "Varelse"
+
+#: src/gui/userpalette.cpp:110
+#, fuzzy
+msgid "Friend Names"
+msgstr "Vän"
+
+#: src/gui/userpalette.cpp:111
+#, fuzzy
+msgid "Disregarded Names"
+msgstr "Förbisedd"
+
+#: src/gui/userpalette.cpp:112
+#, fuzzy
+msgid "Ignored Names"
+msgstr "Ignorerad"
+
+#: src/gui/userpalette.cpp:113
+#, fuzzy
+msgid "Erased Names"
+msgstr "GM-namn"
+
+#: src/gui/userpalette.cpp:114
+msgid "Other Players' Names"
+msgstr "Andra spelares namn"
+
+#: src/gui/userpalette.cpp:115
+msgid "Own Name"
+msgstr "Eget namn"
+
+#: src/gui/userpalette.cpp:116
+msgid "GM Names"
+msgstr "GM-namn"
+
+#: src/gui/userpalette.cpp:117
+msgid "NPCs"
+msgstr "NPC:er"
+
+#: src/gui/userpalette.cpp:118
+msgid "Monsters"
+msgstr "Monster"
+
+#: src/gui/userpalette.cpp:119
+#, fuzzy
+msgid "Monster HP bar"
+msgstr "Monster slår spelare"
+
+#: src/gui/userpalette.cpp:121
+msgid "Monster HP bar (second color)"
+msgstr ""
+
+#: src/gui/userpalette.cpp:122
+#, fuzzy
+msgid "Party Members"
+msgstr "Grupp"
+
+#: src/gui/userpalette.cpp:123
+#, fuzzy
+msgid "Guild Members"
+msgstr "Gille"
+
+#: src/gui/userpalette.cpp:124
+msgid "Particle Effects"
+msgstr "Partikeleffekter"
+
+#: src/gui/userpalette.cpp:125
+msgid "Pickup Notification"
+msgstr "Upplocksnotis"
+
+#: src/gui/userpalette.cpp:126
+msgid "Exp Notification"
+msgstr "XP-notifiering"
+
+#: src/gui/userpalette.cpp:127
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Spelare slår monster"
+
+#: src/gui/userpalette.cpp:128
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Monster slår spelare"
+
+#: src/gui/userpalette.cpp:130
+#, fuzzy
+msgid "Other Player Hits Local Player"
+msgstr "Andra spelares namn"
+
+#: src/gui/userpalette.cpp:131
+msgid "Critical Hit"
+msgstr "Kritisk träff"
+
+#: src/gui/userpalette.cpp:133
+#, fuzzy
+msgid "Local Player Hits Monster"
+msgstr "Spelare slår monster"
+
+#: src/gui/userpalette.cpp:135
+#, fuzzy
+msgid "Local Player Critical Hit"
+msgstr "Spelare slår monster"
+
+#: src/gui/userpalette.cpp:137
+#, fuzzy
+msgid "Local Player Miss"
+msgstr "Kom ihåg spelarlista"
+
+#: src/gui/userpalette.cpp:138
+msgid "Misses"
+msgstr "Missar"
+
+#: src/gui/userpalette.cpp:139
+#, fuzzy
+msgid "Portal Highlight"
+msgstr "Flikmarkering"
+
+#: src/gui/userpalette.cpp:141
+#, fuzzy
+msgid "Collision Highlight"
+msgstr "Markering"
+
+#: src/gui/userpalette.cpp:143
+#, fuzzy
+msgid "Walkable Highlight"
+msgstr "Flikmarkering"
+
+#: src/gui/userpalette.cpp:145
+msgid "Local Player Attack Range"
+msgstr ""
+
+#: src/gui/userpalette.cpp:147
+msgid "Local Player Attack Range Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:149
+#, fuzzy
+msgid "Monster Attack Range"
+msgstr "Monster slår spelare"
+
+#: src/gui/userpalette.cpp:151
+msgid "Home Place"
+msgstr ""
+
+#: src/gui/userpalette.cpp:153
+msgid "Home Place Border"
+msgstr ""
+
+#: src/gui/userpalette.cpp:155
+msgid "Road Point"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:70 src/gui/whoisonline.cpp:457
+msgid "Who Is Online - Updating"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:90
+msgid "Update"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:283
+msgid "Who Is Online - "
+msgstr ""
+
+#: src/gui/whoisonline.cpp:471
+msgid "Who Is Online - error"
+msgstr ""
+
+#: src/gui/whoisonline.cpp:501
+msgid "Who Is Online - Update"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+"/users > Visar en lista över de spelare som finns i den aktuella chattkanalen"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Sätter ämnet för chattkanalen"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Lämnar chattkanalen"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Gör en spelare till chattkanalsoperatör"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Sparka ut en spelare från chattkanalen"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Kommando: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Det här kommandot visar alla spelare i den här chattkanalen."
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Kommando: /topic <meddelande>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Det här kommandot sätter ämnet till <meddelande>."
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Kommando: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Det här kommandot gör att du lämnar aktuell chattkanal."
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Om du är den sista spelaren i chattkanalen tas den bort."
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Kommando: /op <spelare>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "Det här kommandot gör <spelare> till chattkanalsoperatör."
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Operatörer kan sparka ut och ge operatörsstatus till andra spelare i "
+"chattkanalen."
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Kommando: /kick <spelare>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Det här kommandot sparkar ut <spelare> ur chattkanalen."
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Du måste ange vilken spelare som ska få operatörsstatus!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Du måste ange vilken spelare som ska sparkas ut!"
+
+#: src/gui/widgets/chattab.cpp:145
+msgid "Global announcement:"
+msgstr "Globalt meddelande:"
+
+#: src/gui/widgets/chattab.cpp:151
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Globalt meddelande från %s:"
+
+#: src/gui/widgets/chattab.cpp:177
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s viskar: "
+
+#: src/gui/widgets/whispertab.cpp:104
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:105
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:106
+msgid "/close > Close the whisper tab"
+msgstr "/close > Stänger viskningsfliken"
+
+#: src/gui/widgets/whispertab.cpp:116
+msgid "Command: /close"
+msgstr "Kommando: /close"
+
+#: src/gui/widgets/whispertab.cpp:117
+msgid "This command closes the current whisper tab."
+msgstr "Det här kommandot stänger aktuell viskningsflik."
+
+#: src/gui/widgets/whispertab.cpp:121
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Kommando: /item"
+
+#: src/gui/widgets/whispertab.cpp:122
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Det här kommandot visar antalet spelare som är inloggade just nu."
+
+#: src/gui/widgets/whispertab.cpp:128
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "Det här kommandot startar loggning av chatten till <filnamn>."
+
+#: src/gui/windowmenu.cpp:61
+msgid "BC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+#, fuzzy
+msgid "Bot checker"
+msgstr "Chattfönster"
+
+#: src/gui/windowmenu.cpp:63
+msgid "ONL"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:63
+msgid "Who is online"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:65
+msgid "KS"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:67
+#, fuzzy
+msgid "Smiles"
+msgstr "Smiley"
+
+#: src/gui/windowmenu.cpp:69
+msgid "STA"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:69
+msgid "Status"
+msgstr "Status"
+
+#: src/gui/windowmenu.cpp:70
+msgid "EQU"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:72
+msgid "INV"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:77
+msgid "SKI"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:83
+msgid "SPE"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:87
+msgid "SOC"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+msgid "SH"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:88
+#, fuzzy
+msgid "Shortcuts"
+msgstr "Genvägar"
+
+#: src/gui/windowmenu.cpp:90
+msgid "SP"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:91
+msgid "DR"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:92
+msgid "SET"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:74
+#, fuzzy
+msgid "Select World"
+msgstr "Välj okej"
+
+#: src/gui/worldselectdialog.cpp:79
+#, fuzzy
+msgid "Change Login"
+msgstr "Ändra"
+
+#: src/gui/worldselectdialog.cpp:80
+#, fuzzy
+msgid "Choose World"
+msgstr "Välj din server"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Up"
+msgstr "Gå uppåt"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Down"
+msgstr "Gå nedåt"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Left"
+msgstr "Gå åt vänster"
+
+#: src/keyboardconfig.cpp:44
+msgid "Move Right"
+msgstr "Gå åt höger"
+
+#: src/keyboardconfig.cpp:46
+msgid "Target & Attack"
+msgstr "Välj & attackera"
+
+#: src/keyboardconfig.cpp:48
+#, fuzzy
+msgid "Move to Target"
+msgstr "Gå åt vänster"
+
+#: src/keyboardconfig.cpp:50
+msgid "Change Move to Target type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Move to Home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Set home location"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Move to navigation point"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58
+msgid "Smilie"
+msgstr "Smiley"
+
+#: src/keyboardconfig.cpp:60
+msgid "Stop Attack"
+msgstr "Sluta attackera"
+
+#: src/keyboardconfig.cpp:61
+#, fuzzy
+msgid "Target Closest"
+msgstr "Välj närmaste"
+
+#: src/keyboardconfig.cpp:63
+msgid "Target NPC"
+msgstr "Välj NPC"
+
+#: src/keyboardconfig.cpp:64
+msgid "Target Player"
+msgstr "Välj spelare"
+
+#: src/keyboardconfig.cpp:66
+msgid "Pickup"
+msgstr "Plocka upp"
+
+#: src/keyboardconfig.cpp:67
+msgid "Change Pickup Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:69
+msgid "Hide Windows"
+msgstr "Dölj fönster"
+
+#: src/keyboardconfig.cpp:70
+msgid "Sit"
+msgstr "Sitt"
+
+#: src/keyboardconfig.cpp:71
+msgid "Screenshot"
+msgstr "Skärmbild"
+
+#: src/keyboardconfig.cpp:72
+msgid "Enable/Disable Trading"
+msgstr "Tillåt/neka handel"
+
+#: src/keyboardconfig.cpp:74
+#, fuzzy
+msgid "Change Map View Mode"
+msgstr "Ändra epostadress"
+
+#: src/keyboardconfig.cpp:76
+#, fuzzy
+msgid "Item Shortcuts Key"
+msgstr "Tangent för snabbåtkomst %d"
+
+#: src/keyboardconfig.cpp:78 src/keyboardconfig.cpp:80
+#: src/keyboardconfig.cpp:82 src/keyboardconfig.cpp:84
+#: src/keyboardconfig.cpp:86 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:90 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:94 src/keyboardconfig.cpp:96
+#: src/keyboardconfig.cpp:98 src/keyboardconfig.cpp:100
+#: src/keyboardconfig.cpp:102 src/keyboardconfig.cpp:104
+#: src/keyboardconfig.cpp:106 src/keyboardconfig.cpp:109
+#: src/keyboardconfig.cpp:111 src/keyboardconfig.cpp:113
+#: src/keyboardconfig.cpp:115 src/keyboardconfig.cpp:117
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Tangent för snabbåtkomst %d"
+
+#: src/keyboardconfig.cpp:118
+msgid "Help Window"
+msgstr "Hjälpfönster"
+
+#: src/keyboardconfig.cpp:119
+msgid "Status Window"
+msgstr "Statusfönster"
+
+#: src/keyboardconfig.cpp:121
+msgid "Inventory Window"
+msgstr "Inventorium"
+
+#: src/keyboardconfig.cpp:123
+msgid "Equipment Window"
+msgstr "Utrustningsfönster"
+
+#: src/keyboardconfig.cpp:125
+msgid "Skill Window"
+msgstr "Färdighetsfönster"
+
+#: src/keyboardconfig.cpp:127
+msgid "Minimap Window"
+msgstr "Minikarta"
+
+#: src/keyboardconfig.cpp:129
+msgid "Chat Window"
+msgstr "Chattfönster"
+
+#: src/keyboardconfig.cpp:130
+msgid "Item Shortcut Window"
+msgstr "Snabbåtkomstfönster"
+
+#: src/keyboardconfig.cpp:132
+msgid "Setup Window"
+msgstr "Inställningsfönster"
+
+#: src/keyboardconfig.cpp:134
+msgid "Debug Window"
+msgstr "Felsökningsfönster"
+
+#: src/keyboardconfig.cpp:136
+#, fuzzy
+msgid "Social Window"
+msgstr "Färdighetsfönster"
+
+#: src/keyboardconfig.cpp:138
+msgid "Emote Shortcut Window"
+msgstr "Smileyfönster"
+
+#: src/keyboardconfig.cpp:140
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Statusfönster"
+
+#: src/keyboardconfig.cpp:142
+#, fuzzy
+msgid "Shop Window"
+msgstr "Inställningsfönster"
+
+#: src/keyboardconfig.cpp:143
+#, fuzzy
+msgid "Quick drop Window"
+msgstr "Dölj fönster"
+
+#: src/keyboardconfig.cpp:145
+#, fuzzy
+msgid "Kills Stats Window"
+msgstr "Statusfönster"
+
+#: src/keyboardconfig.cpp:147
+#, fuzzy
+msgid "Commands Window"
+msgstr "Kommando: /item"
+
+#: src/keyboardconfig.cpp:149
+#, fuzzy
+msgid "Bot Checker Window"
+msgstr "Chattfönster"
+
+#: src/keyboardconfig.cpp:152
+msgid "Who Is Online Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:154
+#, fuzzy
+msgid "Previous Social Tab"
+msgstr "Föregående chattflik"
+
+#: src/keyboardconfig.cpp:155
+#, fuzzy
+msgid "Next Social Tab"
+msgstr "Nästa chattflik"
+
+#: src/keyboardconfig.cpp:157 src/keyboardconfig.cpp:159
+#: src/keyboardconfig.cpp:161 src/keyboardconfig.cpp:163
+#: src/keyboardconfig.cpp:165 src/keyboardconfig.cpp:167
+#: src/keyboardconfig.cpp:169 src/keyboardconfig.cpp:171
+#: src/keyboardconfig.cpp:173 src/keyboardconfig.cpp:175
+#: src/keyboardconfig.cpp:177 src/keyboardconfig.cpp:179
+#: src/keyboardconfig.cpp:182 src/keyboardconfig.cpp:184
+#: src/keyboardconfig.cpp:186 src/keyboardconfig.cpp:188
+#: src/keyboardconfig.cpp:190 src/keyboardconfig.cpp:192
+#: src/keyboardconfig.cpp:194 src/keyboardconfig.cpp:196
+#: src/keyboardconfig.cpp:198 src/keyboardconfig.cpp:200
+#: src/keyboardconfig.cpp:202 src/keyboardconfig.cpp:204
+#: src/keyboardconfig.cpp:206 src/keyboardconfig.cpp:209
+#: src/keyboardconfig.cpp:212 src/keyboardconfig.cpp:215
+#: src/keyboardconfig.cpp:217 src/keyboardconfig.cpp:219
+#: src/keyboardconfig.cpp:221 src/keyboardconfig.cpp:223
+#: src/keyboardconfig.cpp:225 src/keyboardconfig.cpp:227
+#: src/keyboardconfig.cpp:229 src/keyboardconfig.cpp:231
+#: src/keyboardconfig.cpp:233 src/keyboardconfig.cpp:236
+#: src/keyboardconfig.cpp:238 src/keyboardconfig.cpp:240
+#: src/keyboardconfig.cpp:242 src/keyboardconfig.cpp:244
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "Tangent för smiley %d"
+
+#: src/keyboardconfig.cpp:246
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:248
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:250
+msgid "Copy Equiped to Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:252
+msgid "Toggle Chat"
+msgstr "Växla chattfönster"
+
+#: src/keyboardconfig.cpp:254
+msgid "Scroll Chat Up"
+msgstr "Rulla upp chatt"
+
+#: src/keyboardconfig.cpp:256
+msgid "Scroll Chat Down"
+msgstr "Rulla ned chatt"
+
+#: src/keyboardconfig.cpp:258
+msgid "Previous Chat Tab"
+msgstr "Föregående chattflik"
+
+#: src/keyboardconfig.cpp:260
+msgid "Next Chat Tab"
+msgstr "Nästa chattflik"
+
+#: src/keyboardconfig.cpp:262
+#, fuzzy
+msgid "Previous chat tab line"
+msgstr "Föregående chattflik"
+
+#: src/keyboardconfig.cpp:264
+#, fuzzy
+msgid "Next chat tab line"
+msgstr "Nästa chattflik"
+
+#: src/keyboardconfig.cpp:266
+msgid "Chat Auto Complete"
+msgstr ""
+
+#: src/keyboardconfig.cpp:268
+msgid "Deactivate Chat Input"
+msgstr ""
+
+#: src/keyboardconfig.cpp:270
+msgid "Select OK"
+msgstr "Välj okej"
+
+#: src/keyboardconfig.cpp:272
+msgid "Ignore input 1"
+msgstr "Ignorera inmatning 1"
+
+#: src/keyboardconfig.cpp:274
+msgid "Ignore input 2"
+msgstr "Ignorera inmatning 2"
+
+#: src/keyboardconfig.cpp:276
+msgid "Direct Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:277
+#, fuzzy
+msgid "Direct Down"
+msgstr "Gå nedåt"
+
+#: src/keyboardconfig.cpp:279
+#, fuzzy
+msgid "Direct Left"
+msgstr "Gå åt vänster"
+
+#: src/keyboardconfig.cpp:280
+#, fuzzy
+msgid "Direct Right"
+msgstr "Gå åt höger"
+
+#: src/keyboardconfig.cpp:282
+msgid "Crazy moves"
+msgstr ""
+
+#: src/keyboardconfig.cpp:284
+msgid "Change Crazy Move mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:286
+msgid "Quick Drop N Items from 0 slot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:288
+msgid "Quick Drop N Items"
+msgstr ""
+
+#: src/keyboardconfig.cpp:290
+msgid "Switch Quick Drop Counter"
+msgstr ""
+
+#: src/keyboardconfig.cpp:292
+msgid "Quick heal target or self"
+msgstr ""
+
+#: src/keyboardconfig.cpp:294
+msgid "Use #itenplz spell"
+msgstr ""
+
+#: src/keyboardconfig.cpp:296
+msgid "Use magic attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:298
+#, fuzzy
+msgid "Switch magic attack"
+msgstr "Byt karaktär"
+
+#: src/keyboardconfig.cpp:300
+#, fuzzy
+msgid "Change move type"
+msgstr "Server"
+
+#: src/keyboardconfig.cpp:302
+msgid "Change Attack Weapon Type"
+msgstr ""
+
+#: src/keyboardconfig.cpp:304
+#, fuzzy
+msgid "Change Attack Type"
+msgstr "Välj & attackera"
+
+#: src/keyboardconfig.cpp:306
+#, fuzzy
+msgid "Change Follow mode"
+msgstr "Ändra lösenord"
+
+#: src/keyboardconfig.cpp:308
+#, fuzzy
+msgid "Change Imitation mode"
+msgstr "Ändra epostadress"
+
+#: src/keyboardconfig.cpp:311
+msgid "Disbale / Enable Game modifier keys"
+msgstr ""
+
+#: src/keyboardconfig.cpp:312
+msgid "On / Off audio"
+msgstr ""
+
+#: src/keyboardconfig.cpp:314
+#, fuzzy
+msgid "Enable / Disable away mode"
+msgstr "Tillåt/neka handel"
+
+#: src/keyboardconfig.cpp:316
+msgid "Emulate right click from keyboard"
+msgstr ""
+
+#: src/keyboardconfig.cpp:318
+msgid "Toggle camera mode"
+msgstr ""
+
+#: src/keyboardconfig.cpp:380
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Se till att använda olika tangenter, annars kan det bli konstigheter."
+
+#: src/localplayer.cpp:325
+msgid "You were killed by "
+msgstr ""
+
+#: src/localplayer.cpp:1305
+msgid "Unable to pick up item."
+msgstr "Kunde inte plocka upp."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:1315
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "Du plockade upp %s [@@%d|%s@@]."
+msgstr[1] "Du plockade upp %s [@@%d|%s@@]."
+
+#: src/localplayer.cpp:2979
+msgid "Away"
+msgstr ""
+
+#: src/localplayer.cpp:3617
+#, fuzzy
+msgid "You see "
+msgstr "Du får %s."
+
+#: src/main.cpp:44
+msgid "manaplus [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:45
+msgid "[mana-file] : The mana file is an XML file (.mana)"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " used to set custom parameters"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " to the mana client."
+msgstr ""
+
+#: src/main.cpp:49
+msgid "Options:"
+msgstr "Alternativ:"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -l --log-file : Log file to use"
+msgstr " -C --config-file : Konfigurationsfil att använda"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -L --chat-log-dir : Chat log dir to use"
+msgstr " -C --config-file : Konfigurationsfil att använda"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : Visa aktuell version"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : Visa den här hjälpen"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : Konfigurationsfil att använda"
+
+#: src/main.cpp:55
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username : Logga in med det här användarnamnet"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : Logga in med det här lösenordet"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : Logga in med den här karaktären"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : Namn eller IP-adress för inloggningsserver"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : Port på inloggningsserver"
+
+#: src/main.cpp:60
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : Använd den här uppdateringsvärden"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : Välj förvald karaktärsserver och karaktär"
+
+#: src/main.cpp:63
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : Ladda inte ner uppdateringar"
+
+#: src/main.cpp:64
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : Katalog att hämta speldata från"
+
+#: src/main.cpp:66
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : Katalog att använda som hemkatalog"
+
+#: src/main.cpp:68
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : Katalog att använda som hemkatalog"
+
+#: src/main.cpp:69
+msgid " --safemode : Start game in safe mode"
+msgstr ""
+
+#: src/main.cpp:71
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : Använd inte OpenGL den här sessionen"
+
+#: src/net/manaserv/attributes.cpp:159 src/net/tmwa/generalhandler.cpp:247
+msgid "Strength"
+msgstr "Styrka"
+
+#: src/net/manaserv/attributes.cpp:166
+#, fuzzy, c-format
+msgid "Strength %+.1f"
+msgstr "Styrka %+d"
+
+#: src/net/manaserv/attributes.cpp:172 src/net/tmwa/generalhandler.cpp:248
+msgid "Agility"
+msgstr "Smidighet"
+
+#: src/net/manaserv/attributes.cpp:179
+#, fuzzy, c-format
+msgid "Agility %+.1f"
+msgstr "Smidighet %+d"
+
+#: src/net/manaserv/attributes.cpp:185 src/net/tmwa/generalhandler.cpp:251
+msgid "Dexterity"
+msgstr "Skicklighet"
+
+#: src/net/manaserv/attributes.cpp:192
+#, fuzzy, c-format
+msgid "Dexterity %+.1f"
+msgstr "Skicklighet %+d"
+
+#: src/net/manaserv/attributes.cpp:198 src/net/tmwa/generalhandler.cpp:249
+msgid "Vitality"
+msgstr "Hälsa"
+
+#: src/net/manaserv/attributes.cpp:205
+#, fuzzy, c-format
+msgid "Vitality %+.1f"
+msgstr "Livskraft %+d"
+
+#: src/net/manaserv/attributes.cpp:211 src/net/tmwa/generalhandler.cpp:250
+msgid "Intelligence"
+msgstr "Intelligens"
+
+#: src/net/manaserv/attributes.cpp:218
+#, fuzzy, c-format
+msgid "Intelligence %+.1f"
+msgstr "Intelligens %+d"
+
+#: src/net/manaserv/attributes.cpp:224
+#, fuzzy
+msgid "Willpower"
+msgstr "Viljestyrka:"
+
+#: src/net/manaserv/attributes.cpp:231
+#, fuzzy, c-format
+msgid "Willpower %+.1f"
+msgstr "Viljekraft %+d"
+
+#: src/net/manaserv/beinghandler.cpp:314 src/net/tmwa/playerhandler.cpp:104
+msgid "You are dead."
+msgstr "Du är död."
+
+#: src/net/manaserv/beinghandler.cpp:315 src/net/tmwa/playerhandler.cpp:105
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+"Vi beklagar att behöva meddela dig om att din karaktär dödades i strid."
+
+#: src/net/manaserv/beinghandler.cpp:317 src/net/tmwa/playerhandler.cpp:107
+msgid "You are not that alive anymore."
+msgstr "Du är inte så värst levande längre."
+
+#: src/net/manaserv/beinghandler.cpp:318 src/net/tmwa/playerhandler.cpp:108
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "Liemannens svala händer sträcker sig efter din själ."
+
+#: src/net/manaserv/beinghandler.cpp:319 src/net/tmwa/playerhandler.cpp:109
+msgid "Game Over!"
+msgstr "Spelet är slut!"
+
+#: src/net/manaserv/beinghandler.cpp:320 src/net/tmwa/playerhandler.cpp:111
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+"Barn, barn. Din karaktär dog egentligen inte. Den… öh… kom till ett bättre "
+"ställe."
+
+#: src/net/manaserv/beinghandler.cpp:322 src/net/tmwa/playerhandler.cpp:113
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+"Din plan att ha sönder dina fiendens vapen genom att krossa dem med din hals "
+"misslyckades."
+
+#: src/net/manaserv/beinghandler.cpp:324 src/net/tmwa/playerhandler.cpp:115
+msgid "I guess this did not run too well."
+msgstr "Jag antar att det kunde gått bättre."
+
+#: src/net/manaserv/beinghandler.cpp:325 src/net/tmwa/playerhandler.cpp:117
+msgid "Do you want your possessions identified?"
+msgstr "Vill du att dina tillhörigheter ska identifieras?"
+
+#: src/net/manaserv/beinghandler.cpp:326 src/net/tmwa/playerhandler.cpp:119
+msgid "Sadly, no trace of you was ever found..."
+msgstr "Ledsamt nog så kunde inga spår efter dig någonsin hittas…"
+
+#: src/net/manaserv/beinghandler.cpp:328 src/net/tmwa/playerhandler.cpp:121
+msgid "Annihilated."
+msgstr "Tillintetgjord."
+
+#: src/net/manaserv/beinghandler.cpp:329 src/net/tmwa/playerhandler.cpp:123
+msgid "Looks like you got your head handed to you."
+msgstr "Verkar som att som att någon gav dig ditt huvud."
+
+#: src/net/manaserv/beinghandler.cpp:331 src/net/tmwa/playerhandler.cpp:125
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+"Du klantade till det igen, släng din kropp vid kloakerna och skaffa dig en "
+"ny."
+
+#: src/net/manaserv/beinghandler.cpp:336
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " Klicka okej för att återuppstå"
+
+#: src/net/manaserv/beinghandler.cpp:337
+#, fuzzy
+msgid "You Died"
+msgstr "Du dog"
+
+#: src/net/manaserv/charhandler.cpp:144 src/net/manaserv/charhandler.cpp:215
+#, fuzzy
+msgid "Not logged in."
+msgstr "Redan inloggad"
+
+#: src/net/manaserv/charhandler.cpp:147
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:150
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:153
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Användarnamnet finns redan"
+
+#: src/net/manaserv/charhandler.cpp:156
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:159
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:162
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:165
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Karaktärens värden okej"
+
+#: src/net/manaserv/charhandler.cpp:168
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Karaktärens värden okej"
+
+#: src/net/manaserv/charhandler.cpp:171
+#, c-format
+msgid "At least one statis out of the permitted range: (%u - %u)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:177 src/net/manaserv/loginhandler.cpp:98
+#: src/net/manaserv/loginhandler.cpp:130 src/net/manaserv/loginhandler.cpp:166
+#: src/net/manaserv/loginhandler.cpp:286 src/net/manaserv/loginhandler.cpp:323
+#: src/net/tmwa/loginhandler.cpp:99 src/net/tmwa/loginhandler.cpp:187
+#, fuzzy
+msgid "Unknown error."
+msgstr "Okänt fel"
+
+#: src/net/manaserv/charhandler.cpp:206 src/net/tmwa/charserverhandler.cpp:149
+msgid "Info"
+msgstr "Information"
+
+#: src/net/manaserv/charhandler.cpp:206
+#, fuzzy
+msgid "Player deleted."
+msgstr "Karaktär borttagen."
+
+#: src/net/manaserv/charhandler.cpp:218
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Välj antal föremål att handla med."
+
+#: src/net/manaserv/charhandler.cpp:221
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Okänt fel"
+
+#: src/net/manaserv/charhandler.cpp:257
+msgid "No gameservers are available."
+msgstr "Ingen spelserver finns tillgänglig."
+
+#: src/net/manaserv/chathandler.cpp:185 src/net/manaserv/chathandler.cpp:308
+#: src/net/manaserv/guildhandler.cpp:264
+#, c-format
+msgid "Topic: %s"
+msgstr "Ämne: %s"
+
+#: src/net/manaserv/chathandler.cpp:190 src/net/manaserv/chathandler.cpp:268
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Spelare slår monster"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Kommando: /join <chattkanal>"
+
+#: src/net/manaserv/chathandler.cpp:213
+#, fuzzy
+msgid "Listing channels."
+msgstr "Skickar förfrågan att gå in i chattkanalen %s."
+
+#: src/net/manaserv/chathandler.cpp:225
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:298
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s anslöt sig till gruppen."
+
+#: src/net/manaserv/chathandler.cpp:303
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:319
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:330
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:336
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Okänt kommando."
+
+#: src/net/manaserv/guildhandler.cpp:84 src/net/tmwa/guildhandler.cpp:104
+msgid "Guild created."
+msgstr "Gille skapat."
+
+#: src/net/manaserv/guildhandler.cpp:89
+msgid "Error creating guild."
+msgstr "Kunde inte skapa gille."
+
+#: src/net/manaserv/guildhandler.cpp:99
+msgid "Invite sent."
+msgstr "Inbjudan skickad."
+
+#: src/net/manaserv/guildhandler.cpp:206
+msgid "Member was promoted successfully."
+msgstr "Medlem befordrad."
+
+#: src/net/manaserv/guildhandler.cpp:211
+msgid "Failed to promote member."
+msgstr "Kunde inte befordra medlem."
+
+#: src/net/manaserv/loginhandler.cpp:89
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "Fel magic_token"
+
+#: src/net/manaserv/loginhandler.cpp:92 src/net/manaserv/loginhandler.cpp:276
+#, fuzzy
+msgid "Already logged in."
+msgstr "Redan inloggad"
+
+#: src/net/manaserv/loginhandler.cpp:95
+#, fuzzy
+msgid "Account banned."
+msgstr "Konto raderat"
+
+#: src/net/manaserv/loginhandler.cpp:120
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Det nya lösenordet stämmer inte överens"
+
+#: src/net/manaserv/loginhandler.cpp:123 src/net/tmwa/loginhandler.cpp:93
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "Det gamla lösenordet är fel"
+
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:159
+msgid "Account not connected. Please login first."
+msgstr "Kontot är inte anslutet. Var god logga in först."
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Den nya epostadressen är felaktig."
+
+#: src/net/manaserv/loginhandler.cpp:155
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "Den gamla epostadressen är fel."
+
+#: src/net/manaserv/loginhandler.cpp:163
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "Den nya epostadressen används redan."
+
+#: src/net/manaserv/loginhandler.cpp:244
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:270 src/net/manaserv/loginhandler.cpp:307
+#, fuzzy
+msgid "Client version is too old."
+msgstr "Du har en för gammal version av klienten"
+
+#: src/net/manaserv/loginhandler.cpp:273
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "Felaktigt användarnamn eller lösenord"
+
+#: src/net/manaserv/loginhandler.cpp:279
+#, fuzzy
+msgid "Account banned"
+msgstr "Konto raderat"
+
+#: src/net/manaserv/loginhandler.cpp:282
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:310
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "Felaktigt användarnamn, lösenord eller epostadress"
+
+#: src/net/manaserv/loginhandler.cpp:313
+#, fuzzy
+msgid "Username already exists."
+msgstr "Användarnamnet finns redan"
+
+#: src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Email address already exists."
+msgstr "Epostadressen finns redan"
+
+#: src/net/manaserv/loginhandler.cpp:319
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:89
+msgid "Joined party."
+msgstr "Anslöt dig till grupp."
+
+#: src/net/manaserv/partyhandler.cpp:107
+#, c-format
+msgid "%s joined the party."
+msgstr "%s anslöt sig till gruppen."
+
+#: src/net/manaserv/partyhandler.cpp:125
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s avvisade din inbjudan."
+
+#: src/net/manaserv/tradehandler.cpp:106
+msgid "Accepting incoming trade requests."
+msgstr "Accepterar byteshandelsförfrågningar."
+
+#: src/net/manaserv/tradehandler.cpp:108
+msgid "Ignoring incoming trade requests."
+msgstr "Ignorerar byteshandelsförfrågningar."
+
+#: src/net/manaserv/tradehandler.cpp:127 src/net/tmwa/tradehandler.cpp:122
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s vill byteshandla med dig, accepterar du?"
+
+#: src/net/manaserv/tradehandler.cpp:145
+#, c-format
+msgid "Trading with %s"
+msgstr "Byteshandlar med %s"
+
+#: src/net/manaserv/tradehandler.cpp:159 src/net/tmwa/tradehandler.cpp:268
+msgid "Trade canceled."
+msgstr "Byteshandel avbruten."
+
+#: src/net/manaserv/tradehandler.cpp:166 src/net/tmwa/tradehandler.cpp:278
+msgid "Trade completed."
+msgstr "Byteshandel genomförd."
+
+#: src/net/tmwa/adminhandler.cpp:64
+msgid "Kick failed!"
+msgstr "Kunde inte sparka ut!"
+
+#: src/net/tmwa/adminhandler.cpp:66
+msgid "Kick succeeded!"
+msgstr "Klarade av att sparka ut!"
+
+#: src/net/tmwa/buysellhandler.cpp:122
+msgid "Nothing to sell."
+msgstr "Inget att sälja."
+
+#: src/net/tmwa/buysellhandler.cpp:129
+msgid "Thanks for buying."
+msgstr "Tack för köpet."
+
+#: src/net/tmwa/buysellhandler.cpp:137
+msgid "Unable to buy."
+msgstr "Kan inte köpa."
+
+#: src/net/tmwa/buysellhandler.cpp:143
+msgid "Thanks for selling."
+msgstr "Tack för en god affär."
+
+#: src/net/tmwa/buysellhandler.cpp:145
+msgid "Unable to sell."
+msgstr "Kan inte sälja."
+
+#: src/net/tmwa/charserverhandler.cpp:106
+msgid "Access denied. Most likely, there are too many players on this server."
+msgstr ""
+
+#: src/net/tmwa/charserverhandler.cpp:110
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Kan inte använda ID"
+
+#: src/net/tmwa/charserverhandler.cpp:113
+#, fuzzy
+msgid "Unknown char-server failure."
+msgstr "Okänt fel"
+
+#: src/net/tmwa/charserverhandler.cpp:137
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "Kan inte skapa karaktär. Troligtvis används namnet av någon annan."
+
+#: src/net/tmwa/charserverhandler.cpp:149
+msgid "Character deleted."
+msgstr "Karaktär borttagen."
+
+#: src/net/tmwa/charserverhandler.cpp:154
+msgid "Failed to delete character."
+msgstr "Kunde inte ta bort karaktär."
+
+#: src/net/tmwa/charserverhandler.cpp:286
+msgid "Strength:"
+msgstr "Styrka:"
+
+#: src/net/tmwa/charserverhandler.cpp:287
+msgid "Agility:"
+msgstr "Smidighet:"
+
+#: src/net/tmwa/charserverhandler.cpp:288
+msgid "Vitality:"
+msgstr "Hälsa:"
+
+#: src/net/tmwa/charserverhandler.cpp:289
+msgid "Intelligence:"
+msgstr "Intelligens:"
+
+#: src/net/tmwa/charserverhandler.cpp:290
+msgid "Dexterity:"
+msgstr "Skicklighet:"
+
+#: src/net/tmwa/charserverhandler.cpp:291
+msgid "Luck:"
+msgstr "Tur:"
+
+#: src/net/tmwa/chathandler.cpp:103
+#, fuzzy, c-format
+msgid "Whisper could not be sent, %s is offline."
+msgstr "Kunde inte viska eftersom spelaren inte är inloggad."
+
+#: src/net/tmwa/chathandler.cpp:111
+#, fuzzy, c-format
+msgid "Whisper could not be sent, ignored by %s."
+msgstr "Kunde inte viska eftersom ignorerad av spelaren."
+
+#: src/net/tmwa/chathandler.cpp:333
+#, fuzzy
+msgid "MVP player."
+msgstr "Spelare"
+
+#: src/net/tmwa/chathandler.cpp:337
+#, fuzzy
+msgid "MVP player: "
+msgstr "Spelare"
+
+#: src/net/tmwa/chathandler.cpp:390 src/net/tmwa/chathandler.cpp:396
+#: src/net/tmwa/chathandler.cpp:401 src/net/tmwa/chathandler.cpp:407
+#: src/net/tmwa/chathandler.cpp:412 src/net/tmwa/chathandler.cpp:418
+#: src/net/tmwa/chathandler.cpp:425 src/net/tmwa/chathandler.cpp:431
+msgid "Channels are not supported!"
+msgstr "Chattkanaler stöds inte!"
+
+#: src/net/tmwa/gamehandler.cpp:92
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Game"
+msgstr "Namn"
+
+#: src/net/tmwa/gamehandler.cpp:102
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "Förfrågan om byteshandel"
+
+#: src/net/tmwa/generalhandler.cpp:104
+#, c-format
+msgid "Strength %+d"
+msgstr "Styrka %+d"
+
+#: src/net/tmwa/generalhandler.cpp:105
+#, c-format
+msgid "Agility %+d"
+msgstr "Smidighet %+d"
+
+#: src/net/tmwa/generalhandler.cpp:106
+#, c-format
+msgid "Vitality %+d"
+msgstr "Livskraft %+d"
+
+#: src/net/tmwa/generalhandler.cpp:107
+#, c-format
+msgid "Intelligence %+d"
+msgstr "Intelligens %+d"
+
+#: src/net/tmwa/generalhandler.cpp:108
+#, c-format
+msgid "Dexterity %+d"
+msgstr "Skicklighet %+d"
+
+#: src/net/tmwa/generalhandler.cpp:109
+#, c-format
+msgid "Luck %+d"
+msgstr "Tur %+d"
+
+#: src/net/tmwa/generalhandler.cpp:135
+#, fuzzy
+msgid "Authentication failed."
+msgstr "Behörighetskontroll misslyckades"
+
+#: src/net/tmwa/generalhandler.cpp:138
+#, fuzzy
+msgid "No servers available."
+msgstr "Ingen server är tillgänglig"
+
+#: src/net/tmwa/generalhandler.cpp:142
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "Någon annan försöker att använda det här kontot"
+
+#: src/net/tmwa/generalhandler.cpp:145
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "Det här kontot är redan inloggat"
+
+#: src/net/tmwa/generalhandler.cpp:148
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "Ett hastighetshack har upptäckts"
+
+#: src/net/tmwa/generalhandler.cpp:151
+#, fuzzy
+msgid "Duplicated login."
+msgstr "Dubbel inloggning"
+
+#: src/net/tmwa/generalhandler.cpp:154
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "Okänt anslutningsfel"
+
+#: src/net/tmwa/generalhandler.cpp:220
+msgid "Got disconnected from server!"
+msgstr "Kopplades från servern!"
+
+#: src/net/tmwa/generalhandler.cpp:252
+msgid "Luck"
+msgstr "Tur"
+
+#: src/net/tmwa/generalhandler.cpp:255
+#, fuzzy
+msgid "Defense"
+msgstr "Försvar:"
+
+#: src/net/tmwa/generalhandler.cpp:256
+#, fuzzy
+msgid "M.Attack"
+msgstr "M. attack:"
+
+#: src/net/tmwa/generalhandler.cpp:257
+#, fuzzy
+msgid "M.Defense"
+msgstr "M. försvar:"
+
+#: src/net/tmwa/generalhandler.cpp:258
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Träffsäkerhet:"
+
+#: src/net/tmwa/generalhandler.cpp:259
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% Kringgå:"
+
+#: src/net/tmwa/generalhandler.cpp:260
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Kritisk träff"
+
+#: src/net/tmwa/generalhandler.cpp:261
+#, fuzzy
+msgid "Attack Delay"
+msgstr "Attack %+d"
+
+#: src/net/tmwa/generalhandler.cpp:263
+#, fuzzy
+msgid "Walk Delay"
+msgstr "Attack %+d"
+
+#: src/net/tmwa/generalhandler.cpp:265
+#, fuzzy
+msgid "Attack Range"
+msgstr "Monster slår spelare"
+
+#: src/net/tmwa/gui/guildtab.cpp:74 src/net/tmwa/gui/partytab.cpp:66
+msgid "/help > Display this help."
+msgstr "/help > Visa den här hjälpen"
+
+#: src/net/tmwa/gui/guildtab.cpp:75
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > Bjud in en spelare till din grupp"
+
+#: src/net/tmwa/gui/guildtab.cpp:76
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > Lämna gruppen du är i"
+
+#: src/net/tmwa/gui/guildtab.cpp:77
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Sparka ut någon från din grupp"
+
+#: src/net/tmwa/gui/guildtab.cpp:86 src/net/tmwa/gui/partytab.cpp:80
+msgid "Command: /invite <nick>"
+msgstr "Kommando: /invite <spelare>"
+
+#: src/net/tmwa/gui/guildtab.cpp:87
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Det här kommandot bjuder in <spelare> till din grupp."
+
+#: src/net/tmwa/gui/guildtab.cpp:93 src/net/tmwa/gui/partytab.cpp:87
+msgid "Command: /leave"
+msgstr "Kommando: /leave"
+
+#: src/net/tmwa/gui/guildtab.cpp:94
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Det här kommandot får spelaren att lämna gruppen."
+
+#: src/net/tmwa/guildhandler.cpp:109 src/net/tmwa/guildhandler.cpp:114
+#, fuzzy
+msgid "You already in guild."
+msgstr "Kunde inte skapa gille."
+
+#: src/net/tmwa/guildhandler.cpp:119
+msgid "Emperium check failed."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:124
+#, fuzzy
+msgid "Unknown server response."
+msgstr "Okänt injudningssvar från %s."
+
+#: src/net/tmwa/guildhandler.cpp:202
+#, fuzzy, c-format
+msgid "Guild name: %s"
+msgstr "Gille"
+
+#: src/net/tmwa/guildhandler.cpp:204
+#, fuzzy, c-format
+msgid "Guild master: %s"
+msgstr "Gille"
+
+#: src/net/tmwa/guildhandler.cpp:206
+#, fuzzy, c-format
+msgid "Guild level: %d"
+msgstr "Nivå: %d"
+
+#: src/net/tmwa/guildhandler.cpp:208
+#, c-format
+msgid "Online members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:210
+#, c-format
+msgid "Max members: %d"
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:212
+#, fuzzy, c-format
+msgid "Average level: %d"
+msgstr "Maxnivå"
+
+#: src/net/tmwa/guildhandler.cpp:214
+#, fuzzy, c-format
+msgid "Guild exp: %d"
+msgstr "Gille"
+
+#: src/net/tmwa/guildhandler.cpp:216
+#, fuzzy, c-format
+msgid "Guild next exp: %d"
+msgstr "Gille skapat."
+
+#: src/net/tmwa/guildhandler.cpp:218
+#, fuzzy, c-format
+msgid "Guild castle: %s"
+msgstr "Gille skapat."
+
+#: src/net/tmwa/guildhandler.cpp:433
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:438
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:443
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s är nu en medlem i din grupp."
+
+#: src/net/tmwa/guildhandler.cpp:448
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:453
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "Okänt injudningssvar från %s."
+
+#: src/net/tmwa/guildhandler.cpp:475
+#, fuzzy
+msgid "You have left the guild."
+msgstr "Du har lämnat gruppen."
+
+#: src/net/tmwa/guildhandler.cpp:489
+#, fuzzy, c-format
+msgid "%s has left your guild."
+msgstr "%s har lämnat din grupp."
+
+#: src/net/tmwa/guildhandler.cpp:521
+msgid "You was kicked from guild."
+msgstr ""
+
+#: src/net/tmwa/guildhandler.cpp:535
+#, fuzzy, c-format
+msgid "%s has kicked from your guild."
+msgstr "%s är nu en medlem i din grupp."
+
+#: src/net/tmwa/gui/partytab.cpp:67
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > Bjud in en spelare till din grupp"
+
+#: src/net/tmwa/gui/partytab.cpp:68
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > Lämna gruppen du är i"
+
+#: src/net/tmwa/gui/partytab.cpp:69
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > Sparka ut någon från din grupp"
+
+#: src/net/tmwa/gui/partytab.cpp:70
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > Visa/ändra delningsalternativ för upplock inom gruppen"
+
+#: src/net/tmwa/gui/partytab.cpp:71
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > Visa/ändra hur erfarenhet fördelas i gruppen"
+
+#: src/net/tmwa/gui/partytab.cpp:88
+msgid "This command causes the player to leave the party."
+msgstr "Det här kommandot får spelaren att lämna gruppen."
+
+#: src/net/tmwa/gui/partytab.cpp:92
+msgid "Command: /item <policy>"
+msgstr "Kommando: /item <alternativ>"
+
+#: src/net/tmwa/gui/partytab.cpp:94
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+"Det här kommandot ändrar huruvida gruppen ska kunna plocka upp efter alla."
+
+#: src/net/tmwa/gui/partytab.cpp:95
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<alternativ> kan vara antingen ”1”, ”yes” eller ”true” för att dela på "
+"upplocken inom gruppen (vem som helst inom gruppen kan direkt plocka upp "
+"efter alla gruppmedlemmar), eller ”0”, ”no” eller ”false” för att inte dela "
+"på upplocken."
+
+#: src/net/tmwa/gui/partytab.cpp:98
+msgid "Command: /item"
+msgstr "Kommando: /item"
+
+#: src/net/tmwa/gui/partytab.cpp:99
+msgid "This command displays the party's current item sharing policy."
+msgstr "Det här kommandot visar huruvida gruppen kan plocka upp efter alla."
+
+#: src/net/tmwa/gui/partytab.cpp:104
+msgid "Command: /exp <policy>"
+msgstr "Kommando: /exp <alternativ>"
+
+#: src/net/tmwa/gui/partytab.cpp:105
+msgid "This command changes the party's experience sharing policy."
+msgstr "Det här kommandot ändrar hur erfarenhet fördelas inom gruppen."
+
+#: src/net/tmwa/gui/partytab.cpp:107
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<alternativ> kan vara antingen ”1”, ”yes” eller ”true” för att tillåta "
+"delning av erfarenhet, eller ”0”, ”no” eller ”false” för att inte dela på "
+"erfarenhet."
+
+#: src/net/tmwa/gui/partytab.cpp:110
+msgid "Command: /exp"
+msgstr "Kommando: /exp"
+
+#: src/net/tmwa/gui/partytab.cpp:111
+msgid "This command displays the party's current experience sharing policy."
+msgstr "Det här kommandot visar om erfarenhet delas inom gruppen."
+
+#: src/net/tmwa/gui/partytab.cpp:145 src/net/tmwa/partyhandler.cpp:263
+msgid "Item sharing enabled."
+msgstr "Upplocksdelning aktiverad."
+
+#: src/net/tmwa/gui/partytab.cpp:148 src/net/tmwa/partyhandler.cpp:273
+msgid "Item sharing disabled."
+msgstr "Upplocksdelning avaktiverad."
+
+#: src/net/tmwa/gui/partytab.cpp:151 src/net/tmwa/partyhandler.cpp:283
+msgid "Item sharing not possible."
+msgstr "Upplocksdelning är inte möjligt."
+
+#: src/net/tmwa/gui/partytab.cpp:154
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "Upplocksdelning aktiverad."
+
+#: src/net/tmwa/gui/partytab.cpp:184 src/net/tmwa/partyhandler.cpp:225
+msgid "Experience sharing enabled."
+msgstr "Fördelning av erfarenhet aktiverad."
+
+#: src/net/tmwa/gui/partytab.cpp:187 src/net/tmwa/partyhandler.cpp:235
+msgid "Experience sharing disabled."
+msgstr "Fördelning av erfarenhet inaktiverad."
+
+#: src/net/tmwa/gui/partytab.cpp:190 src/net/tmwa/partyhandler.cpp:245
+msgid "Experience sharing not possible."
+msgstr "Fördelning av erfarenhet ej möjlig."
+
+#: src/net/tmwa/gui/partytab.cpp:193
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "Fördelning av erfarenhet aktiverad."
+
+#: src/net/tmwa/inventoryhandler.cpp:329
+msgid "Failed to use item."
+msgstr "Kunde inte använda föremål."
+
+#: src/net/tmwa/inventoryhandler.cpp:452
+msgid "Unable to equip."
+msgstr "Kan inte utrusta."
+
+#: src/net/tmwa/loginhandler.cpp:90
+msgid "Account was not found. Please re-login."
+msgstr "Kontot kunde inte hittas. Var vänlig att logga in på nytt."
+
+#: src/net/tmwa/loginhandler.cpp:96
+#, fuzzy
+msgid "New password too short."
+msgstr "Det nya lösenordet är för kort"
+
+#: src/net/tmwa/loginhandler.cpp:161
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Oregistrerat ID"
+
+#: src/net/tmwa/loginhandler.cpp:164
+#, fuzzy
+msgid "Wrong password."
+msgstr "Fel lösenord"
+
+#: src/net/tmwa/loginhandler.cpp:167
+#, fuzzy
+msgid "Account expired."
+msgstr "Konto raderat"
+
+#: src/net/tmwa/loginhandler.cpp:170
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Nekad tillträde till servern"
+
+#: src/net/tmwa/loginhandler.cpp:173
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "Du har permanent blivit bannlyst från spelet. Kontakta en GM."
+
+#: src/net/tmwa/loginhandler.cpp:177
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"Du har tillfälligt blivit utkastat från spelet till %s.\n"
+"Var vänlig kontakta en GM i forumet."
+
+#: src/net/tmwa/loginhandler.cpp:184
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "Det här användarnamnet finns redan"
+
+#: src/net/tmwa/network.cpp:147
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/tmwa/network.cpp:351
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "Kan inte sälja."
+
+#: src/net/tmwa/network.cpp:421
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "Ansluter till kartservern..."
+
+#: src/net/tmwa/partyhandler.cpp:84
+msgid "Could not create party."
+msgstr "Kunde inte skapa grupp."
+
+#: src/net/tmwa/partyhandler.cpp:86
+msgid "Party successfully created."
+msgstr "Grupp skapad."
+
+#: src/net/tmwa/partyhandler.cpp:153
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s är redan medlem i en grupp."
+
+#: src/net/tmwa/partyhandler.cpp:158
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s avvisade din inbjudan."
+
+#: src/net/tmwa/partyhandler.cpp:163
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s är nu en medlem i din grupp."
+
+#: src/net/tmwa/partyhandler.cpp:168
+#, c-format
+msgid "%s cant joid your party because party is full."
+msgstr ""
+
+#: src/net/tmwa/partyhandler.cpp:173
+#, fuzzy, c-format
+msgid "QQQ Unknown invite response for %s."
+msgstr "Okänt injudningssvar från %s."
+
+#: src/net/tmwa/partyhandler.cpp:333
+msgid "You have left the party."
+msgstr "Du har lämnat gruppen."
+
+#: src/net/tmwa/partyhandler.cpp:345
+#, c-format
+msgid "%s has left your party."
+msgstr "%s har lämnat din grupp."
+
+#: src/net/tmwa/partyhandler.cpp:421
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "En okänd medlem försökte säga: %s"
+
+#: src/net/tmwa/partyhandler.cpp:503
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s är inte med i din grupp!"
+
+#: src/net/tmwa/playerhandler.cpp:110
+msgid "Insert coin to continue."
+msgstr "Stoppa i mynt för att fortsätta."
+
+#: src/net/tmwa/playerhandler.cpp:128
+msgid "You're not dead yet. You're just resting."
+msgstr "Du är inte död än. Du vilar bara."
+
+#: src/net/tmwa/playerhandler.cpp:129
+msgid "You are no more."
+msgstr "Du finns inte längre."
+
+#: src/net/tmwa/playerhandler.cpp:130
+msgid "You have ceased to be."
+msgstr "Du har slutat att existera."
+
+#: src/net/tmwa/playerhandler.cpp:131
+msgid "You've expired and gone to meet your maker."
+msgstr "Du är passé och har givit dig av för att träffa din skapare."
+
+#: src/net/tmwa/playerhandler.cpp:132
+msgid "You're a stiff."
+msgstr "Du är en steling."
+
+#: src/net/tmwa/playerhandler.cpp:133
+msgid "Bereft of life, you rest in peace."
+msgstr "Berövad på ditt liv vilar du numera i frid."
+
+#: src/net/tmwa/playerhandler.cpp:134
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+"Om du inte vore så livfull skulle du vara blomnäring vid det här laget."
+
+#: src/net/tmwa/playerhandler.cpp:135
+msgid "Your metabolic processes are now history."
+msgstr "Dina metaboliska processer är nu historia."
+
+#: src/net/tmwa/playerhandler.cpp:136
+msgid "You're off the twig."
+msgstr "Du har trillat av pinn."
+
+#: src/net/tmwa/playerhandler.cpp:137
+msgid "You've kicked the bucket."
+msgstr "Du har kastat in handduken."
+
+#: src/net/tmwa/playerhandler.cpp:138
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr "Du tog ner skylten, kilade runt hörnet och bet i gräset."
+
+#: src/net/tmwa/playerhandler.cpp:140
+msgid "You are an ex-player."
+msgstr "Du är en före detta spelare."
+
+#: src/net/tmwa/playerhandler.cpp:141
+msgid "You're pining for the fjords."
+msgstr "Du har gått till de sälla jaktmarkerna."
+
+#: src/net/tmwa/playerhandler.cpp:327 src/net/tmwa/playerhandler.cpp:336
+#: src/net/tmwa/playerhandler.cpp:415
+msgid "Message"
+msgstr "Meddelande"
+
+#: src/net/tmwa/playerhandler.cpp:328
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "Du bär mer än halva din vikt på dig. Du kan inte återfå hälsa."
+
+#: src/net/tmwa/playerhandler.cpp:337
+#, fuzzy
+msgid "You are carrying less than half your weight. You are can regain health."
+msgstr "Du bär mer än halva din vikt på dig. Du kan inte återfå hälsa."
+
+#: src/net/tmwa/playerhandler.cpp:442
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Du plockade upp "
+
+#: src/net/tmwa/playerhandler.cpp:448
+#, fuzzy, c-format
+msgid "You spent %s."
+msgstr "Du får %s."
+
+#: src/net/tmwa/playerhandler.cpp:493
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/tmwa/playerhandler.cpp:613
+msgid "Equip arrows first."
+msgstr "Utrusta dig med pilar först."
+
+#: src/net/tmwa/specialhandler.cpp:149
+msgid "Trade failed!"
+msgstr "Byteshandel misslyckades!"
+
+#: src/net/tmwa/specialhandler.cpp:152
+msgid "Emote failed!"
+msgstr "Kan inte visa smiley!"
+
+#: src/net/tmwa/specialhandler.cpp:155
+msgid "Sit failed!"
+msgstr "Kan inte sitta!"
+
+#: src/net/tmwa/specialhandler.cpp:158
+msgid "Chat creating failed!"
+msgstr "Kan inte skicka chattmeddelande!"
+
+#: src/net/tmwa/specialhandler.cpp:161
+msgid "Could not join party!"
+msgstr "Kan inte ansluta till gruppen!"
+
+#: src/net/tmwa/specialhandler.cpp:164
+msgid "Cannot shout!"
+msgstr "Kan inte skrika!"
+
+#: src/net/tmwa/specialhandler.cpp:177
+msgid "You have not yet reached a high enough lvl!"
+msgstr "Du har inte nått en tillräckligt hög nivå än!"
+
+#: src/net/tmwa/specialhandler.cpp:181
+msgid "Insufficient HP!"
+msgstr "Otillräckligt med HP!"
+
+#: src/net/tmwa/specialhandler.cpp:184
+msgid "Insufficient SP!"
+msgstr "Otillräckligt med SP!"
+
+#: src/net/tmwa/specialhandler.cpp:187
+msgid "You have no memos!"
+msgstr "Du har inga anteckningar!"
+
+#: src/net/tmwa/specialhandler.cpp:190
+msgid "You cannot do that right now!"
+msgstr "Du kan inte göra det just nu!"
+
+#: src/net/tmwa/specialhandler.cpp:193
+msgid "Seems you need more money... ;-)"
+msgstr "Verkar som att du behöver mer pengar… ;-)"
+
+#: src/net/tmwa/specialhandler.cpp:196
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "Det går inte att använda den här förmågan med det där vapenslaget!"
+
+#: src/net/tmwa/specialhandler.cpp:200
+msgid "You need another red gem!"
+msgstr "Du behöver en till röd juvel!"
+
+#: src/net/tmwa/specialhandler.cpp:203
+msgid "You need another blue gem!"
+msgstr "Du behöver en till blå juvel!"
+
+#: src/net/tmwa/specialhandler.cpp:206
+msgid "You're carrying to much to do this!"
+msgstr "Du bär på för mycket för att kunna göra det här!"
+
+#: src/net/tmwa/specialhandler.cpp:209
+msgid "Huh? What's that?"
+msgstr "Öh? Vad är det där?"
+
+#: src/net/tmwa/specialhandler.cpp:220
+msgid "Warp failed..."
+msgstr "Kartförflyttning misslyckades..."
+
+#: src/net/tmwa/specialhandler.cpp:223
+msgid "Could not steal anything..."
+msgstr "Kunde inte stjäla något..."
+
+#: src/net/tmwa/specialhandler.cpp:226
+msgid "Poison had no effect..."
+msgstr "Giftet tog inte..."
+
+#: src/net/tmwa/tradehandler.cpp:145
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "Byteshandel är inte möjligt. Handelspartnern är för långt borta."
+
+#: src/net/tmwa/tradehandler.cpp:149
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "Byteshandel är inte möjligt. Karaktären existerar inte."
+
+#: src/net/tmwa/tradehandler.cpp:153
+msgid "Trade cancelled due to an unknown reason."
+msgstr "Byteshandel avbröts av okänd anledning."
+
+#: src/net/tmwa/tradehandler.cpp:161
+#, c-format
+msgid "Trade: You and %s"
+msgstr "Byteshandel: du och %s"
+
+#: src/net/tmwa/tradehandler.cpp:171
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "Byteshandel med %s avbruten."
+
+#: src/net/tmwa/tradehandler.cpp:184
+#, fuzzy
+msgid "Unhandled trade cancel packet."
+msgstr "Ett okänt paket för att avbryta byteshandeln påträffades."
+
+#: src/net/tmwa/tradehandler.cpp:241
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "Kunde inte lägga till föremål. Bytespartnern är överfull."
+
+#: src/net/tmwa/tradehandler.cpp:246
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "Kunde inte lägga till föremål. Bytespartnern har inget ledigt utrymme."
+
+#: src/net/tmwa/tradehandler.cpp:250
+msgid "Failed adding item for unknown reason."
+msgstr "Kunde inte lägga till föremål av okänd anledning."
+
+#: src/playerrelations.cpp:404
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Ignorera %s fullständigt@@"
+
+#: src/playerrelations.cpp:418
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:438
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:483
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:486
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "Attack %+d"
+msgstr "Attack %+d"
+
+#: src/resources/itemdb.cpp:56
+#, c-format
+msgid "Defense %+d"
+msgstr "Försvar %+d"
+
+#: src/resources/itemdb.cpp:57
+#, c-format
+msgid "HP %+d"
+msgstr "Hälsa %+d"
+
+#: src/resources/itemdb.cpp:58
+#, c-format
+msgid "MP %+d"
+msgstr "Mana %+d"
+
+#: src/resources/itemdb.cpp:155
+msgid "Unknown item"
+msgstr "Okänt föremål"
+
+#: src/resources/itemdb.cpp:210 src/resources/monsterdb.cpp:78
+msgid "unnamed"
+msgstr "namnlös"
+
+#, fuzzy
+#~ msgid "Particle detail: %s"
+#~ msgstr "Partikeldetaljer"
+
+#, fuzzy
+#~ msgid "Ambient FX: %s"
+#~ msgstr "Omgivande FX"
+
+#, fuzzy
+#~ msgid "Emote Shortcut %d"
+#~ msgstr "Tangent för smiley %d"
+
+#, fuzzy
+#~ msgid "Player position:"
+#~ msgstr "Spelare slår monster"
+
+#, fuzzy
+#~ msgid "Music: %s"
+#~ msgstr "Ämne: %s"
+
+#, fuzzy
+#~ msgid "Map: %s"
+#~ msgstr "Namn: %s"
+
+#, fuzzy
+#~ msgid "Minimap: %s"
+#~ msgstr "Minikarta"
+
+#~ msgid "/record > Start recording the chat to an external file"
+#~ msgstr "/record > Påbörja loggning av chatten till en extern fil"
+
+#~ msgid "Command: /record <filename>"
+#~ msgstr "Kommando: /record <filnamn>"
+
+#~ msgid "This command starts recording the chat log to the file <filename>."
+#~ msgstr "Det här kommandot startar loggning av chatten till <filnamn>."
+
+#~ msgid "Command: /record"
+#~ msgstr "Kommando: /record"
+
+#~ msgid "This command finishes a recording session."
+#~ msgstr "Det här kommandot slutar loggning av chatten."
+
+#~ msgid "Attendance written to record log."
+#~ msgstr "Närvaro loggades till fil."
+
+#~ msgid "Finishing recording."
+#~ msgstr "Avslutar chattloggning."
+
+#~ msgid "Not currently recording."
+#~ msgstr "Loggar inte chattmeddelanden till fil."
+
+#~ msgid "Already recording."
+#~ msgstr "Loggar chattmeddelanden till fil."
+
+#~ msgid "Starting to record..."
+#~ msgstr "Börjar logga chattmeddelanden…"
+
+#~ msgid "Failed to start recording."
+#~ msgstr "Misslyckades att börja logga chattmeddelanden."
+
+#~ msgid "Recording..."
+#~ msgstr "Loggar chattmeddelanden…"
+
+#~ msgid "Stop recording"
+#~ msgstr "Sluta logga chattmeddelanden"
+
+#~ msgid "Find Path to Mouse"
+#~ msgstr "Gå till muspekaren"
+
+#, fuzzy
+#~ msgid "HP"
+#~ msgstr "HP:"
+
+#, fuzzy
+#~ msgid "MP"
+#~ msgstr "MP:"
+
+#, fuzzy
+#~ msgid "Exp"
+#~ msgstr "EP:"
+
+#, fuzzy
+#~ msgid "Money"
+#~ msgstr "Pengar: %d"
+
+#, fuzzy
+#~ msgid "Job"
+#~ msgstr "Jobb:"
+
+#, fuzzy
+#~ msgid "Level"
+#~ msgstr "Nivå: %d"
+
+#, fuzzy
+#~ msgid "Player successfully ignored!"
+#~ msgstr "Grupp skapad."
+
+#, fuzzy
+#~ msgid "Player could not be ignored!"
+#~ msgstr "Kunde inte viska eftersom ignorerad av spelaren."
+
+#, fuzzy
+#~ msgid " -C --config-file : Configuration file to use"
+#~ msgstr " -C --config-file : Konfigurationsfil att använda"
+
+#, fuzzy
+#~ msgid " -l --chat-log-dir : Chat log dir to use"
+#~ msgstr " -C --config-file : Konfigurationsfil att använda"
+
+#~ msgid "Sound"
+#~ msgstr "Ljud"
+
+#, fuzzy
+#~ msgid "Access denied."
+#~ msgstr "Tillträde nekat"
+
+#, fuzzy
+#~ msgid "Unknown failure to select character."
+#~ msgstr "Kunde inte välja karaktär av okänd anledning"
+
+#~ msgid "Inviting like this isn't supported at the moment."
+#~ msgstr ""
+#~ "För tillfället är det inte möjligt att bjuda in något på det här viset."
+
+#, fuzzy
+#~ msgid "You can only invite when you are in a party!"
+#~ msgstr "%s har bjudit in dig till sin grupp."
+
+#~ msgid "Willpower:"
+#~ msgstr "Viljestyrka:"
+
+#, fuzzy
+#~ msgid "Server is full."
+#~ msgstr "Servern är full"
+
+#, fuzzy
+#~ msgid "Trade with %s..."
+#~ msgstr "Byteshandlar med %s"
+
+#, fuzzy
+#~ msgid "Whisper %s"
+#~ msgstr "Viskning"
+
+#, fuzzy
+#~ msgid "Befriend %s"
+#~ msgstr "@@friend|Lägg till %s som vän@@"
+
+#, fuzzy
+#~ msgid "Disregard %s"
+#~ msgstr "Förbisedd"
+
+#, fuzzy
+#~ msgid "Completely ignore %s"
+#~ msgstr "@@ignore|Ignorera %s fullständigt@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your guild"
+#~ msgstr "@@guild|Bjud in %s till ditt gille@@"
+
+#, fuzzy
+#~ msgid "Invite %s to join your party"
+#~ msgstr "@@party|Bjud in %s till din grupp@@"
+
+#, fuzzy
+#~ msgid "Kick player"
+#~ msgstr "Kunde inte sparka ut!"
+
+#, fuzzy
+#~ msgid "Talk to %s"
+#~ msgstr "@@talk|Prata med %s@@"
+
+#, fuzzy
+#~ msgid "Kick monster"
+#~ msgstr "@@admin-kick|Sparka monster@@"
+
+#, fuzzy
+#~ msgid "Pick up %s"
+#~ msgstr "Plocka upp"
+
+#~ msgid "Cannot send empty chat!"
+#~ msgstr "Kan inte skicka ett tomt chattmeddelande!"
+
+#~ msgid "Unable to unequip."
+#~ msgstr "Kan inte avrusta."
+
+#~ msgid "Text Shadow"
+#~ msgstr "Textskugga"
+
+#~ msgid "Text Outline"
+#~ msgstr "Textkontur"
+
+#~ msgid "Progress Bar Labels"
+#~ msgstr "Förloppsindikatoretiketter"
+
+#, fuzzy
+#~ msgid "Item Too Expensive"
+#~ msgstr "Den är för dyr"
+
+#, fuzzy
+#~ msgid "Item Is Equipped"
+#~ msgstr "Du har utrustat dig"
+
+#~ msgid "GM"
+#~ msgstr "GM"
+
+#~ msgid "Player"
+#~ msgstr "Spelare"
+
+#~ msgid "Whisper"
+#~ msgstr "Viskning"
+
+#~ msgid "Is"
+#~ msgstr "Är"
+
+#~ msgid "Server"
+#~ msgstr "Server"
+
+#~ msgid "Logger"
+#~ msgstr "Loggning"
+
+#~ msgid "Unknown Item Type"
+#~ msgstr "Okänt föremålsslag"
+
+#~ msgid "Generics"
+#~ msgstr "Allmänna föremål"
+
+#~ msgid "Hats"
+#~ msgstr "Huvudbonader"
+
+#~ msgid "Usables"
+#~ msgstr "Förbrukningsvaror"
+
+#~ msgid "Shirts"
+#~ msgstr "Tröjor"
+
+#, fuzzy
+#~ msgid "One Handed Weapons"
+#~ msgstr "Enhandsvapen"
+
+#~ msgid "Pants"
+#~ msgstr "Byxor"
+
+#~ msgid "Shoes"
+#~ msgstr "Skor"
+
+#, fuzzy
+#~ msgid "Two Handed Weapons"
+#~ msgstr "Enhandsvapen"
+
+#~ msgid "Shields"
+#~ msgstr "Sköldar"
+
+#~ msgid "Rings"
+#~ msgstr "Ringar"
+
+#~ msgid "Necklaces"
+#~ msgstr "Halsband"
+
+#~ msgid "Arms"
+#~ msgstr "Handskar"
+
+#~ msgid "Ammo"
+#~ msgstr "Ammunition"
+
+#~ msgid "HP Bar"
+#~ msgstr "Full hälsostapel"
+
+#~ msgid "3/4 HP Bar"
+#~ msgstr "Trekvarts hälsostapel"
+
+#~ msgid "1/2 HP Bar"
+#~ msgstr "Halv hälsostapel"
+
+#~ msgid "1/4 HP Bar"
+#~ msgstr "Kvarts hälsostapel"
+
+#~ msgid "no"
+#~ msgstr "nej"
+
+#~ msgid "Buddy"
+#~ msgstr "Kompis"
+
+#~ msgid "Buddy List"
+#~ msgstr "Kompislista"
+
+#~ msgid "Description: %s"
+#~ msgstr "Beskrivning: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Effekt: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Föregående"
+
+#~ msgid "New"
+#~ msgstr "Ny"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Jobbnivå: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Närvarande: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Lämna gille"
+
+#~ msgid "Ok"
+#~ msgstr "Okej"
+
+#~ msgid "Recent:"
+#~ msgstr "Senaste:"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Använd testmagi 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Använd testmagi 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Använd testmagi 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "Tvåhandsvapen"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Avrusta@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Utrusta@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Släpp@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Dela@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Lager@@"
+
+#~ msgid "Select Server"
+#~ msgstr "Välj server"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Kunde inte byta till "
+
+#~ msgid "windowed"
+#~ msgstr "fönster"
+
+#~ msgid "fullscreen"
+#~ msgstr "helskärms"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "Mystisk förmåga"
+
+#~ msgid "Weapons"
+#~ msgstr "Vapen"
+
+#~ msgid "Crafts"
+#~ msgstr "Hantverk"
+
+#~ msgid "Stats"
+#~ msgstr "Statistik"
+
+#~ msgid "Total"
+#~ msgstr "Totalt"
+
+#~ msgid "Cost"
+#~ msgstr "Kostnad"
+
+#~ msgid "Attack:"
+#~ msgstr "Attack:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% Reflexer:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Återstående statuspoäng: %d"
+
+#~ msgid "curl error "
+#~ msgstr "curl-fel "
+
+#~ msgid " host: "
+#~ msgstr " värd: "
+
+#~ msgid "Buddys"
+#~ msgstr "Kompisar"
+
+#~ msgid "Party Window"
+#~ msgstr "Gruppfönster"
+
+#~ msgid "Unarmed"
+#~ msgstr "Obeväpnad"
+
+#~ msgid "Knife"
+#~ msgstr "Kniv"
+
+#~ msgid "Sword"
+#~ msgstr "Svärd"
+
+#~ msgid "Staff"
+#~ msgstr "Stav"
+
+#~ msgid "Whip"
+#~ msgstr "Piska"
+
+#~ msgid "Bow"
+#~ msgstr "Båge"
+
+#~ msgid "Shooting"
+#~ msgstr "Skjutvapen"
+
+#~ msgid "Mace"
+#~ msgstr "Spikklubba"
+
+#~ msgid "Axe"
+#~ msgstr "Yxa"
+
+#~ msgid "Craft"
+#~ msgstr "Hantverk"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Okänd förmåga"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " kan inte skapas och existerar inte! Avslutar."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Kunde inte välja "
+
+#~ msgid " video mode: "
+#~ msgstr " -videoläge: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "Ansluter till karaktärsservern..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "Ansluter till kontoservern..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > Alias för /create"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "Kommando: /new <grupp>"
+
+#~ msgid "a"
+#~ msgstr "en"
+
+#~ msgid "Unnamed"
+#~ msgstr "Namnlös"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@pickup|Plocka upp %s@@"
+
+#~ msgid "Scroll radius"
+#~ msgstr "Rullningsradie"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Tröghet för rullning"
+
+#~ msgid "Unable to load selection.png"
+#~ msgstr "Kan inte ladda selection.png"
+
+#~ msgid ""
+#~ "\n"
+#~ "> Cancel\n"
+#~ msgstr ""
+#~ "\n"
+#~ "> Avbryt\n"
+
+#~ msgid "skills.xml"
+#~ msgstr "skills.xml"
+
+#~ msgid "monsters.xml"
+#~ msgstr "monsters.xml"
+
+#~ msgid "items.xml"
+#~ msgstr "items.xml"
+
+#~ msgid "NPC Text Request"
+#~ msgstr "NPC-textefterfrågan"
+
+#~ msgid "NPC Number Request"
+#~ msgstr "NPC-nummerefterfrågan"
+
+#~ msgid "%s: %s"
+#~ msgstr "%s: %s"
+
+#~ msgid " -D --default : Bypass the login process with default settings"
+#~ msgstr ""
+#~ " -D --default : Kringgå inloggningsprocessen och använd "
+#~ "grundinställningarna"
+
+#~ msgid "Slots: "
+#~ msgstr "Utrymme: "
+
+#~ msgid " cancelled"
+#~ msgstr " avbruten"
diff --git a/po/te.po b/po/te.po
new file mode 100644
index 000000000..6d05301fa
--- /dev/null
+++ b/po/te.po
@@ -0,0 +1,3598 @@
+# Telugu translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-10-13 03:45+0000\n"
+"Last-Translator: వీవెన్ (Veeven) <Unknown>\n"
+"Language-Team: Telugu <te@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr ""
+
+#: src/client.cpp:623
+msgid "Connecting to server"
+msgstr ""
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "ప్రవేశించు"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "పొరపాటు"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "సంకేతపదం:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "గుర్తుతెలియని ఆదేశం."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- సహాయం--"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "మరింత సమాచారం కోసం, /help <ఆదేశం> అని టైపు చెయ్యండి."
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "సాధారణ"
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr ""
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "వెల: %s / మొత్తం: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "నిష్క్రమించు"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "గరిష్ఠ"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "రద్దుచేయి"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "ఈమెయిల్ చిరునామాని మార్చు"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "ఖాతా: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "మీ పేరు కనీసం 4 అక్షరాల పొడవుండాలి."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "మీ పేరు కనీసం 4 అక్షరాల పొడవుండాలి."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "సంకేతపదాన్ని మార్చు"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "సంకేతపదం:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "మీ పేరు కనీసం 4 అక్షరాల పొడవుండాలి."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "మీ పేరు కనీసం 4 అక్షరాల పొడవుండాలి."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "పేరు:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "వెంట్రుకల రంగు:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "వెంట్రుకల శైలి:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "సృష్టించు"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "పురుషుడు"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "స్త్రీ"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "మీ పేరు కనీసం 4 అక్షరాల పొడవుండాలి."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "ఈమెయిల్ చిరునామాని మార్చు"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "తొలగించు"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "రంగులు"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "అవును"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "కాదు"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "పేరు: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "ఖాతా: %s"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "వెల: %s / మొత్తం: %s"
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "సహాయం"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "బరువు:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "సరే"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "అన్నీ"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "బరువు: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "ప్రవేశించు"
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr ""
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "పటం"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "తదుపరి"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "తదుపరి"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "పంపించు"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "పాఠ్యం"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "పాఠ్యపు నీడ"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "నేపథ్యం"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "ఆటగాడు"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "చొక్కాలు"
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "బూట్లు"
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "ఉంగరాలు"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr ""
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "ఈమెయిల్:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+msgid "Connect"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "రంగులు"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "రకం: "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "ఇంద్ర ధనస్సు"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "పేరు"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "ఆటగాళ్ళు"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "గరిష్ఠ"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "నిండుతెర"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "కాదు"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "స్థాయి: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "స్థాయి: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "సృష్టించు"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "స్థాయి: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "స్థాయి: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "పేరు: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr ""
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "ఆటగాడు"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "పేరు"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "తొలగించు"
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "గుర్తుతెలియని ఆదేశం."
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "సంకేతపదాన్ని మార్చు"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "గుర్తుతెలియని ఆదేశం."
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "గుర్తుతెలియని ఆదేశం."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "no"
+#~ msgstr "కాదు"
+
+#~ msgid "Buddy"
+#~ msgstr "మిత్రుడు"
+
+#~ msgid "Buddy List"
+#~ msgstr "మిత్రుల జాబితా"
+
+#~ msgid "Description: %s"
+#~ msgstr "వివరణ: %s"
+
+#~ msgid "Previous"
+#~ msgstr "గత"
+
+#~ msgid "New"
+#~ msgstr "కొత్త"
+
+#~ msgid "Ok"
+#~ msgstr "సరే"
+
+#~ msgid "fullscreen"
+#~ msgstr "నిండుతెర"
diff --git a/po/th.po b/po/th.po
new file mode 100644
index 000000000..265629444
--- /dev/null
+++ b/po/th.po
@@ -0,0 +1,3585 @@
+# Thai translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-11-06 15:29+0000\n"
+"Last-Translator: Krit Marukawisutthigul <Unknown>\n"
+"Language-Team: Thai <th@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "ตั้งค่า"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "กำลังเชื่อมต่อ..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "เข้าระบบ"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "ผิดพลาด"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "รหัสผ่าน:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+msgid "Email Change"
+msgstr ""
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+msgid "Unregister Successful"
+msgstr ""
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr ""
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr ""
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr ""
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr ""
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr ""
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr ""
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr ""
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr ""
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr ""
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr ""
+
+#: src/commandhandler.cpp:177
+msgid "/createparty > Create a new party"
+msgstr ""
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr ""
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr ""
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr ""
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr ""
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr ""
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr ""
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr ""
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr ""
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr ""
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr ""
+
+#: src/commandhandler.cpp:215
+msgid "Command: /ignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:216
+msgid "This command ignores the given player regardless of current relations."
+msgstr ""
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr ""
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+msgid "Command: /createparty <name>"
+msgstr ""
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+msgid "Command: /unignore <player>"
+msgstr ""
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr ""
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr ""
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr ""
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr ""
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr ""
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+msgid "The connection to the server was lost."
+msgstr ""
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+msgid "Could Not Load Map"
+msgstr ""
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "ซื้อ"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "ออก"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr ""
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "ยกเลิก"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "เปลี่ยนที่อยู่ Email"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "บัญชี: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:134
+#, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "เปลี่ยนรหัสผ่าน"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "รหัสผ่าน:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:123
+#, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "สร้างตัวละคร"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "ชื่อ:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "สีผม:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "ทรงผม:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "สร้าง"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "ชาย"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "หญิง"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "ยืนยันการลบตัวละคร"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "คุณแน่ใจแล้วหรือที่จะลบตัวละครนี้?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "เปลี่ยนที่อยู่ Email"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "ลบทิ้ง"
+
+#: src/gui/charselectdialog.cpp:387
+msgid "Choose"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "ใช่"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "ไม่"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "ชื่อ: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "บัญชี: %s"
+
+#: src/gui/debugwindow.cpp:116
+#, c-format
+msgid "Particle detail: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr ""
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "ใช้"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "ทิ้ง"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "ทิ้ง"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr ""
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, c-format
+msgid "Weight: %s"
+msgstr ""
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "เข้าระบบ"
+
+#: src/gui/login.cpp:58
+msgid "Remember username"
+msgstr ""
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "สมัครสมาชิก"
+
+#: src/gui/login.cpp:60
+msgid "Change Server"
+msgstr ""
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "ถัดไป"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "ถัดไป"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, c-format
+msgid "Attack %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr ""
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "ยืนยัน:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "Email:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:143
+msgid "Server type:"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "กำลังเชื่อมต่อ..."
+
+#: src/gui/serverdialog.cpp:184
+msgid "Custom Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+msgid "Waiting for server..."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+msgid "Delay:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr ""
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr ""
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr ""
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr ""
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr ""
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr ""
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr ""
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+msgid "FPS limit:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr ""
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "ไม่"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr ""
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, c-format
+msgid "Skill %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "เลเวล: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "เลเวล: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "คุณแน่ใจแล้วหรือที่จะลบตัวละครนี้?"
+
+#: src/gui/socialwindow.cpp:182
+#, c-format
+msgid "Invited user %s to party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+msgid "Member Invite to Party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "คุณแน่ใจแล้วหรือที่จะลบตัวละครนี้?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "สร้างตัวละคร"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "เลเวล: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+msgid "Money"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:225
+msgid "Job"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:229
+#, c-format
+msgid "Character points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "เลเวล: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr ""
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr ""
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr ""
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "ชื่อ: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "กำลังเชื่อมต่อ..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+msgid "Command: /ignore"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:88
+msgid "This command ignores the other player regardless of current relations."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "สถานะ"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+msgid "Select World"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:76
+msgid "Change Login"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+msgid " -h --help : Display this help"
+msgstr ""
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "Strength:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "Agility:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "Vitality:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "Intelligence:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "Dexterity:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+msgid "MVP player."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "ชื่อ:"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "ลบทิ้ง"
+
+#: src/net/ea/generalhandler.cpp:225
+msgid "M.Attack"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:226
+msgid "M.Defense"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+msgid "/invite > Invite a player to your guild"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+msgid "This command invites <nick> to the guild you're in."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+msgid "This command causes the player to leave the guild."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+msgid "Unknown error."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:149
+msgid "Unregistered ID."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "เปลี่ยนรหัสผ่าน"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+msgid "Character's stats are too high."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:152
+msgid "Character's stats are too low."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, c-format
+msgid "Unknown error (%d)."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "Willpower:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+msgid "Error joining channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+msgid "Unknown channel event."
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "Willpower:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+msgid "Completely ignore"
+msgstr ""
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Description: %s"
+#~ msgstr "รายละเอียด: %s"
+
+#~ msgid "Previous"
+#~ msgstr "ก่อนหน้า"
+
+#~ msgid "New"
+#~ msgstr "สร้างใหม่"
+
+#~ msgid "Ok"
+#~ msgstr "ตกลง"
diff --git a/po/tr.po b/po/tr.po
new file mode 100644
index 000000000..3c5503599
--- /dev/null
+++ b/po/tr.po
@@ -0,0 +1,3699 @@
+# Turkish translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2010-02-12 09:43+0000\n"
+"Last-Translator: Bekir AVCI <bilgi@turkuazyakit.com>\n"
+"Language-Team: Turkish <tr@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "Kur"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Sunucu bekleniyor"
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "Oturum Aç"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+msgid "Requesting characters"
+msgstr ""
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Hata"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Şifre:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "Değiştir"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Hesabı Kapat"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Bilinmeyen komut."
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- Yardım --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/help > Bu yardımı görüntüler"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "Harita adını gösterir"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > Çevirimiçi kullanıcı sayısını görüntüler"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > Hakkınızda birşey yazın"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > Bu pencereyi temizler"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Bir kullanıcıya özel mesaj gönder"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Alias of msg"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > Alias of msg"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Diğer kullanıcılarla özel mesajlar için bir sekme yaratır."
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr ""
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > Bütün genel kanalları gösterir"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "Bir kanala katıl veya bir kanal oluştur"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "Guruba bir kullanıcı davet et."
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "Guruba bir kullanıcı davet et."
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "Yazışmayı bir dış dosyaya kaydet."
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "Genel duyuru (yalnız GM)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "Daha fazla bilgi için ,yardım/yaz <komut>."
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "Komut: /yardım"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "Bu komut kullanılabilir bütün komutların bir listesini gösterir."
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "Komut: /help <command>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "Bu komut <komut> hakkında yardımı gösterir."
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "Komut: / duyuru <msg>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** Sadece GM için mevcut ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "Bu komut şuanda çevirimiçi olan bütün oyunculara mesaj <msg> gönderir."
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "Komut : /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "Bu komut önceki yazışma girdilerini siler."
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Komut: /join <channel>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Bu komut şu anda çevrimiçi oyuncu sayısını gösterir."
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "Komut: /join <channel>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr ""
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr ""
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "Komut: /list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr ""
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "Komut: /me <message>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr ""
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "Komut: /msg <nick> <message>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "Komut: /whisper <nick> <message>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "Komut: /w <nick> <message>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "Komut: /query <nick>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "Komut: /q <nick>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Komut: /party <nick>"
+
+#: src/commandhandler.cpp:254
+msgid "This command creates a new party called <name>."
+msgstr ""
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "Komut: /party <nick>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr "Bu komut <nick> adlı kişiyi partinize davet eder."
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "Komut: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "Komut: /record <filename>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "Komut: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr "Komut: /toggle <state>"
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr "Komut: /toggle"
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Komut: / duyuru <msg>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "Komut: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "Bu komut geçerli haritanın adını gösterir."
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "Komut: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "Bu komut şu anda çevrimiçi oyuncu sayısını gösterir."
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "Komutların bir listesi için /help yazın."
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr "Sohbeti kapatır."
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "Genel"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Ekran Görüntüsü"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "Ekrangörüntüsü kaydı başarısız."
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Sunucu bağlantısı koptu,Program şimdi kapatılacak"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "Ağ Hatası"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr "Gelen takas istekleri görmezden geliniyor."
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "Gelen takas istekleri kabul ediliyor"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Harita yüklenemedi"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Parti"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "Satın al"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Fiyat: %s / Toplam: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Çıkış"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "En Fazla"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "Mağaza"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Satış"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "İptal"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Hesab:% s"
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Adınızda en az 4 karakter gerekir."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Adınızda en az 4 karakter gerekir."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "Şifre Değiştir"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Şifre:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Adınızda en az 4 karakter gerekir."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Adınızda en az 4 karakter gerekir."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Karakter oluşturma"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "İsim:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Saç Rengi:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Saç Stili:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "Oluştur"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "Erkek"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "Kadın"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Adınızda en az 4 karakter gerekir."
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Karakter İstatistik Tamam"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Bu karakteri silmek istediğinize emin misiniz?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "Hesap ve Karakter Yönetimi"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Hesabı Kapat"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Değiştir"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Sil"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "Kapat"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "Sohbet"
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr ""
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Evet"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Hayır"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "İsim: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Hesab:% s"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "Fiyat: %s / Toplam: %s"
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Ekipman"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr ""
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "Yardım"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "Kapat"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "Envanter"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "Donatmak"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Kullan"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+msgid "Drop..."
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "Bölme"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "Ağırlık:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr ""
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "Tamam"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "Hepsi"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr ""
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr ""
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr ""
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Ağırlık: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "Oturum Aç"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "Kullanıcı adını hatırla"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Üye ol"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Sunucu"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "Harita"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "Sunucu bekleniyor"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Sonraki"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "Sıfırla"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Sonraki"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr "Alıcı:"
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "Gönder"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+msgid "Unequip first"
+msgstr ""
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "Metin"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "Metin Gölgesi"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr "Metin Anahat"
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "Arka plan"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "Öğe çok pahalı"
+
+#: src/gui/palette.cpp:94
+#, fuzzy
+msgid "Item Is Equipped"
+msgstr "Öğe bulunuyor"
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr "GM"
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "Oyuncu"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "Parti"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr "Birlik"
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "Sunucu"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "Diğer oyuncuların isimleri"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "GM isimleri"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "Canavarlar"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr "Bilinmeyen Öğe Türü"
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr "Jenerik"
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "Şapkalar"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "Gömlek"
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "Ayakkabılar"
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "Kalkanlar"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "Yüzükler"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "Kolye"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr "Silah"
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr "Kritik Hit"
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr "HP Bar"
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr "3/4 HP Bar"
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr "1/2 HP Bar"
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr "1/4 HP Bar"
+
+#: src/gui/popupmenu.cpp:84
+#, c-format
+msgid "Trade with %s..."
+msgstr ""
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "Saldırı"
+
+#: src/gui/popupmenu.cpp:92
+#, c-format
+msgid "Whisper %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, c-format
+msgid "Ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "Canavarlar"
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr "Depo"
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr "Almak"
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "Geçiş sunucusu"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "Geçiş karakteri"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr "Kayıt başlatılıyor ..."
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr "Kayıt başlatılamadı."
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr "Kaydediliyor..."
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr "Kaydı durdur"
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "Onayla:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "E-Posta:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr ""
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Parolalar uyuşmuyor."
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Sunucu Seçin"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Sunucu:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Bağlantı Noktası:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Sunucu:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "Bağlanıyor..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Sunucu"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr ""
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Sunucu bekleniyor"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "Ses"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "Ses"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "SFX ses"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Müzik ses seviyesi"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "Metin yok"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "Renkler"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "Türü: "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr "Sabit"
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "Darbe"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "Gökkuşağı"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "Spektrum"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "Başlat"
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "Kırmızı: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "Yeşil: "
+
+#: src/gui/setup_colors.cpp:137
+#, fuzzy
+msgid "Blue:"
+msgstr "Mavi: "
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Uygula"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "Kalibrasyon"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "Dur"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Klavye"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Atamak"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "Varsayılan"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr ""
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "İsim"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr ""
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr ""
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "Arkadaş"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr ""
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr ""
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr ""
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "Adı göster"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "Oyuncular"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "Küçük"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "Normal"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "Büyük"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "Metin yok"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "kapalı"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "düşük"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "yüksek"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "orta"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "max"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "Tam ekran"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr ""
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "Adı göster"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr "sohbet"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS Limit:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "Video"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "Adı göster"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr ""
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+msgid "Particle detail"
+msgstr ""
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "Yazı tipi boyutu"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Hayır"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+msgid "Switching to Full Screen"
+msgstr ""
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "Değişikliklerin etkili olması için yeniden başlatılması gerekli."
+
+#: src/gui/setup_video.cpp:411
+msgid "Changing to OpenGL"
+msgstr ""
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "OpenGL değişikliklerini uygulamak yeniden başlatma gerektirir."
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Ekran çözünürlüğü değiştirildi"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Beceriler"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "Yukarı"
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Beceriler"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Seviye: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Seviye: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Birlik oluşturma"
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Çıkmak istediğinize emin misiniz?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "Guruba bir kullanıcı davet et."
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "Guruba bir kullanıcı davet et."
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Çıkmak istediğinize emin misiniz?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr "Birlik oluşturma"
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Karakter oluşturma"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "Büyük"
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "Birlik"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Sunucu Seçin"
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "Parti"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Sunucu Seçin"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Seviye: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr "İş:"
+
+#: src/gui/statuswindow.cpp:194
+#, fuzzy
+msgid "HP"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:200
+#, fuzzy
+msgid "MP"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:206
+#, fuzzy
+msgid "Exp"
+msgstr "Exp:"
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Para: %d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "İş:"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Karakter İstatistik Tamam"
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Seviye: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr ""
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "Ticaret"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "Ekle"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, c-format
+msgid "You get %s"
+msgstr ""
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr ""
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "Değiştir"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr ""
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "Yeterli para yok."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "İsim: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "Güncelleniyor..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "Bağlanıyor..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr "Başlat"
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "Tamamlandı"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Komut: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Komut: /topic <message>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Komut: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Komut: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Komut: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "Global duyuru:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:150
+#, c-format
+msgid "%s whispers: %s"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr "Komut: /close"
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Komut: /where"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Bu komut şu anda çevrimiçi oyuncu sayısını gösterir."
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "Durum"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "Kısayol"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "Sunucu Seç"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "Değiştir"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "Sunucu Seçin"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr "Yukarı Taşı"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr "Aşağı Taşı"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr "Sola Taşı"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr "Sağa Taşı"
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr "Saldırı"
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr "Konuş"
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "Hedef Oyuncu"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr "Hedef Oyuncu"
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "Ekran Görüntüsü"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr "Durum penceresi"
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr "Sohbet Penceresi"
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr "Hata Ayıklama Penceresi"
+
+#: src/keyboardconfig.cpp:80
+#, fuzzy
+msgid "Social Window"
+msgstr "Durum penceresi"
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Durum penceresi"
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr ""
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "/help > Bu yardımı görüntüler"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "Oyuncu"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "İsim"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "Güçlülük"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "Çeviklik"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "yaşama gücü"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "Istihbarat"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "Maharet"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "Şans"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Savunma:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "Saldırı"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "Savunma:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, c-format
+msgid "% Accuracy"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:228
+#, c-format
+msgid "% Evade"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:229
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Kritik Hit"
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "Guruba bir kullanıcı davet et."
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Bu komut <nick> adlı kişiyi partinize davet eder."
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Bu komut geçerli haritanın adını gösterir."
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Bilinmeyen komut."
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Hesabı Kapat"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "Şifre Değiştir"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+msgid "Rejected from server."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+msgid "You Died"
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Karakter İstatistik Tamam"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Karakter İstatistik Tamam"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+msgid "Selection out of range."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Bilinmeyen komut."
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Komut: /join <channel>"
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Bilinmeyen komut."
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+msgid "Willpower"
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "Tamamlandı"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr "isimsiz"
+
+#~ msgid "no"
+#~ msgstr "hayır"
+
+#~ msgid "Buddy"
+#~ msgstr "Arkadaş"
+
+#~ msgid "Buddy List"
+#~ msgstr "Arkadaş Listesi"
+
+#~ msgid "Description: %s"
+#~ msgstr "Açıklama: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Etkisi:% s"
+
+#~ msgid "Previous"
+#~ msgstr "Önceki"
+
+#~ msgid "New"
+#~ msgstr "Yeni"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Iş Düzeyi:% d"
+
+#~ msgid "Ok"
+#~ msgstr "Tamam"
+
+#~ msgid "Magic"
+#~ msgstr "Büyü"
+
+#~ msgid "windowed"
+#~ msgstr "pencereli"
+
+#~ msgid "fullscreen"
+#~ msgstr "tam ekran"
+
+#~ msgid "Weapons"
+#~ msgstr "Silahlar"
+
+#~ msgid "Crafts"
+#~ msgstr "El sanatları"
+
+#~ msgid "Stats"
+#~ msgstr "Istatistikler"
+
+#~ msgid "Total"
+#~ msgstr "Toplam"
+
+#~ msgid "Cost"
+#~ msgstr "Maliyet"
+
+#~ msgid "Attack:"
+#~ msgstr "Saldırı:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "Refleks %:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "Kalan Durum Puanı:% d"
+
+#~ msgid "Unnamed"
+#~ msgstr "İsimsiz"
diff --git a/po/uk.po b/po/uk.po
new file mode 100644
index 000000000..873c67801
--- /dev/null
+++ b/po/uk.po
@@ -0,0 +1,3889 @@
+# Ukrainian translation for mana
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-10-16 13:01+0000\n"
+"Last-Translator: tivasyk <tivasyk@gmail.com>\n"
+"Language-Team: Ukrainian <uk@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 or n%100>=20) ? 1 : 2);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "Налаштування"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "Очікування відповіді сервера"
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "Логін"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "Вимагається приєднання до каналу %s."
+
+#: src/client.cpp:768
+msgid "Connecting to the game server"
+msgstr ""
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "Помилка"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "Пароль:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "Заміна"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "Не зареєстрований"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "Невідомий сервер оновлення: "
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr "Неможливо створити теку для оновлень!"
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "Чорт зна яка команда"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- Довідка --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/help > Показати це вікно"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > Показати ім'я мапи"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > Показати кількість гравців он-лайн"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > Розказати щось про себе"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > Очистити оце вікно"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > Надіслати приватне повідомлення користувачеві"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > Варіант msg"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > Варіант msg"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > Створює закладку для приватної розмови з іншим користувачем"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q > Варіант query"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > Показати усі публічні канали"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/join > Приєднатись чи створити канал"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/party > Запросити гравця до групи"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "/party > Запросити гравця до групи"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/record > Розпочати запис чату у зовнішній файл"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > Встановити, чи \"Ентер\" перемикатиме вас на вікно чату"
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr ""
+"/present > Показати список всіх гравців он-лайн (надсилає в лог чату, якщо "
+"увімкнена опція логу чату)"
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > Глобальне оголошення (лише для GM)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "Хочете знати більше - введіть /help <команда>."
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "Команда: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "Ця команда показує список всіх доступних команд"
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "Команда: /help <_команда_>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "Ця команда відображає коротку інформацію про <_команда_>"
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "Команда: /announce <_текст_>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** доступне лише для GM ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr ""
+"Ця команда надсилає <_текст_> всім гравцям, що знаходяться в режимі он-лайн"
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "Команда: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "Ця команда очищає вікно логу чату від попередніх повідомлень"
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "Команда: /join <_канал_>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "Відображає кількість гравців он-лайн"
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "Команда: /join <_канал_>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "Ця команда приєднує вас до <_канал_>"
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "Якщо <_канал_> не існує, він буде створений"
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "Команда: /list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "Ця команда показує список всіх доступних каналів"
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "Команда: /me <_текст_>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr "Ця команда каже всім гравцям <_текст_> (або що ви робите)"
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "Команда: /msg <_ім'я_> <_текст_>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "Команда: /whisper <_ім'я_> <_текст_>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "Команда: /w <_ім'я_> <_текст_>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "Ця команда надсилає <_текст_> гравцеві <_ім'я_>."
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr ""
+"Якщо <_ім'я_> містить пробіли, візьміть все _ім'я_ в подвійні лапки (\r\n"
+"name surname\")"
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "Команда: /query <_ім'я_>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "Команда: /q <_ім'я_>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+"Ця команда намагається створити закладинку для перешіптування між вами та "
+"гравцем <_ім'я_>"
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "Команда: /party <_ім'я_>"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "Ця команда приєднує вас до <_канал_>"
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "Команда: /party <_ім'я_>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr "Ця команда запрошує гравця <_ім'я_> до вас в групу"
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "Команда: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+"Ця команда отримує список гравців, які можуть почути вас і надсилає його або "
+"в файл логу чату (якщо увімкнена опція ведення логу), або до вікна чату"
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "Команда: /record <_файл_>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+"Ця команда вмикає ведення журналу чату (записує весь вміст чату у <_файл_>)"
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "Команда: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr "Завершує ведення журналу (логу) чату"
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr "Команда: /toggle <_режим_>"
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+"Ця команда встановлює, чи буде натиснення клавіші Enter автоматично "
+"перемикатиме на вікно чату"
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"<_режим_> може бути \"1\", \"yes\", або \"true\" щоб увімкнути опцію, або ж "
+"\"0\", \"no\", чи \"false\" щоб вимкнути її."
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr "Команда: /toggle"
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr "Показує режим клавіші Enter"
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "Команда: /announce <_текст_>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "Команда: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "Показує назву поточної локації"
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "Команда: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "Відображає кількість гравців он-лайн"
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "Введіть /help щоб побачити список всіх команд"
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr "Не можна надсилати порожні повідомлення!"
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+"Неможливо створити закладинку для спілкування з гравцем \"%s\" - або така "
+"вже існує, або ви намагаєтесь перешіптуватись сам з собою =Р"
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "Вимагається приєднання до каналу %s."
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr "Enter перемикає на чат"
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr "Повідомлення закриваж вікно чату"
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr "Enter тепер перемикає на вікно чату"
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr "Тепер повідомлення закриватиме вікно чату"
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+"Можливими опціями для /%s є: \"yes\", \"no\", \"true\", \"false\", \"1\", \"0"
+"\"."
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "Загальне"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "Фотознімок екрану (скріншот) збережено до теки ~/"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "Збереження скріншоту провалилось!"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "Втрачено з'єднання з сервером, програма завершуєтьсся"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "Мережева помилка"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr "Ігнорування вхідних пропозицій торгівлі"
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "Приймання вхідних пропозицій торгівлі"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "Неможливо завантажити локацію"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "Помилка під час завантаження %s"
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "Група (%s)"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "Придбати"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "Ціна: %s / Загалом: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "Вийти"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "Максимум"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "Магазин"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "Продати"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "Скасувати"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "Змінити адресу електронної пошти"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "Обліковий запис: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "Двічі введіть вашу нову адресу електронної пошти:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "Ім'я користувача повинне складатись хоча б з %d символів."
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "Ім'я користувача повинне складатись не більш, як з %d символів."
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "Змінити пароль"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "Пароль:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "Введіть новий пароль двічі:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "Пароль повинен складатись мінімум з %d символів."
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "Пароль повинен складатись менш, ніж з %d символів."
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "Створити персонажа"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "Ім'я"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "Колір волосся:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "Зачіска:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "Створити"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "Чоловік"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "Жінка"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "Будь ласка, розподіліть %d балів"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "Ім'я повинно містити принаймні 4 символи"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "Характеристики персонажа в нормі"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "Будь ласка, видаліть %d балів"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "Підтвердіть видалення персонажа"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "Ви дійсно бажаєте знищити персонажа?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "Керування обліковими записами та персонажами"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "Не зареєстрований"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "Змінити адресу електронної пошти"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "Видалити"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "Закрити"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "Чат"
+
+#: src/gui/chat.cpp:287
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d гравців он-лайн"
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr "Аудиторія занесена до журналу"
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "Шепчу до %s: %s"
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "Так"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "Ні"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "Ім'я: %s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "Вікно мінімапи"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "Ефекти часток"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "Деталізація ефектів частинок"
+
+#: src/gui/debugwindow.cpp:121
+#, fuzzy, c-format
+msgid "Ambient FX: %s"
+msgstr "Звуки оточення"
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "Обладунки"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "Зняти"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "Довідка"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "Закрити"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "Сумка"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "Зняти"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "Використати"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "Викинути"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "Поділити"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr "Комірки"
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "Вага:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "Викинути"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "Ок"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "Все"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "Вкажіть кількість предметів"
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "Вкажіть кількість предметів, щоб викинути"
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr "Вкажіть кількість предметів для зберігання"
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr "Вкажіть кількість предметів для отримання"
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "Вкажіть кількість предметів для розподілу"
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "Вага: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "Логін"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "Запам'ятати ім'я користувача"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "Зареєструватись"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "Сервер"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "Локація"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "Очікування відповіді сервера"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "Далі"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr "Підтвердити"
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "Спробувати знову"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "Далі"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr "Для:"
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "Надіслати"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "Неможливо надіслати, так як адресант або лист некорректні"
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "Зняти"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "Текст"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "Відтінок тексту"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr "Виділення тексту"
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr "Позначки на індикаторах прогресу"
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "Тло"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr "Підсвічення"
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr "Підсвічення закладинок"
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "Предмет надто дорогий"
+
+#: src/gui/palette.cpp:94
+#, fuzzy
+msgid "Item Is Equipped"
+msgstr "Предмет одягнено"
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr "GM"
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "Гравець"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr "Шепіт"
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr "Є"
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "Група"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr "Гільдія"
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "Сервер"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr "Логер"
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr "Посилання"
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr "Істота"
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "Імена інших гравців"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr "Власне ім'я"
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "Імена GM"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "NPC"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "Тварюки"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr "Невідомий тип предмета"
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr "Загальні"
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "Капелюхи"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr "Використання"
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "Сорочки"
+
+#: src/gui/palette.cpp:119
+#, fuzzy
+msgid "One Handed Weapons"
+msgstr "\"Однорука\" зброя"
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "Штанці"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "Чоботи"
+
+#: src/gui/palette.cpp:122
+#, fuzzy
+msgid "Two Handed Weapons"
+msgstr "\"Однорука\" зброя"
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "Щити"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "Кільця"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "Ошийники"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr "Руки"
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "Боєприпаси"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr "Ефекти часток"
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr "Повідомлення про підбирання"
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr "Повідомлення про зміну досвіду"
+
+#: src/gui/palette.cpp:133
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "Гравець вдарив Тварюку"
+
+#: src/gui/palette.cpp:135
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "Тварюка вдарила гравця"
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr "Критичний удар"
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr "Промах"
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr "Рядок HP"
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr "3/4 рядка НР"
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr "1/2 рядка НР"
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr "1/4 здоров'я"
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "@@trade|Торгувати з %s@@"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "Нападати"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "Шепіт"
+
+#: src/gui/popupmenu.cpp:101
+#, fuzzy, c-format
+msgid "Befriend %s"
+msgstr "@@friend|Товаришувати з %s@@"
+
+#: src/gui/popupmenu.cpp:106
+#, fuzzy, c-format
+msgid "Disregard %s"
+msgstr "Не зважати"
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "Ігнорувати повністю"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, fuzzy, c-format
+msgid "Completely ignore %s"
+msgstr "@@ignore|Повністю ігнорувати %s@@"
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, fuzzy, c-format
+msgid "Invite %s to join your guild"
+msgstr "@@guild|Запросити %s до вашої гільдії@@"
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "@@party|Запросити %s до вашої групи@@"
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, fuzzy, c-format
+msgid "Talk to %s"
+msgstr "@@talk|Шоворити з %s@@"
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "@@admin-kick|Викинути тварюку@@"
+
+#: src/gui/popupmenu.cpp:174
+#, fuzzy
+msgid "Add name to chat"
+msgstr "@@name|додати ім'я до чату@@"
+
+#: src/gui/popupmenu.cpp:191
+#, fuzzy, c-format
+msgid "Pick up %s"
+msgstr "Підняти"
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|Додати до чату@@"
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "Змінити сервер"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "Змінити персонажа"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr "Запис завершено"
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr "На даний момент запис не ведеться"
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr "Вже записується"
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr "Починається запис..."
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr "Початок запису провалився."
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr "Запис..."
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr "Припинити запис"
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "Підтвердіть:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "Пошта:"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "Ім'я користувача повинне складатись хоча б з %d символів."
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "Ім'я користувача повинне складатись не більш, як з %d символів."
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "Пароль повинен складатись мінімум з %d символів."
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "Пароль повинен складатись менш, ніж з %d символів."
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "Не ідентичні паролі!"
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "Оберіть сервер"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "Сервер:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Порт:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "Сервер:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "З'єднуюсь..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "Красивий вказівник"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "Будь ласка, введіть порт і адресу серверу"
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "Очікування відповіді сервера"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "ЗвукАуді"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "Аудіо"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "Гучність ефектів"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "Гучність музики"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "Без тексту"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr "Ось, як виглядає цей колір"
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "Кольори"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "Тип: "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr "Статичне"
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "Пульсуюче"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "Веселка"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "Спектр"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "Затримка: "
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "Червоний: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "Зелений: "
+
+#: src/gui/setup_colors.cpp:137
+#, fuzzy
+msgid "Blue:"
+msgstr "Синій: "
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "Застосувати"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "Збити налаштування вікон"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "Натисніть кнопку для початку налаштування"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "Налаштувати"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "Використовувати джойстик"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "Джойстик"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr ""
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr ""
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "Клавіатура"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "Призначити"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "Типово"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr "Деякі скорочення дублюють одне одного"
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "Назва"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr "Стосунки"
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "Нейтрально"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "Друзі"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr "Не зважати"
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "Ігнорувати повністю"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "Дозволити торгівлю"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr "Дозволити шепіт (приватне спілкування)"
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr "Шепіт (приватне спілкування) в окремих вкладках"
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "Показувати ім'я"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "Гравці"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr ""
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr "Крихітний"
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "Малий"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "Середній"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "Великий"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "Без тексту"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr "Лише бульбашки, без імен"
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr "Бульбашки та імена"
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "вимкнено"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "низький"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "високий"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "середній"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "максимальний"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "На повний екран"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "Красивий вказівник"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr "Видимі імена"
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr "Ефекти частинок"
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "Показувати ім'я"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr "Повідомляти, коли піднято предмет"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr "у балачці"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr "як частинки"
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "Обмеження частоти кадрів"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "Відео"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "Показувати ім'я"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr "Текст зверху"
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "Прозорість інтерфейсу"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr "Звуки оточення"
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "Деталізація ефектів частинок"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "Розмір шрифта"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "Ні"
+
+#: src/gui/setup_video.cpp:381
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "Невдалося встановити режим і відновити попередній!"
+
+#: src/gui/setup_video.cpp:387
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "Невдалося встановити режим і відновити попередній!"
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "Перемикання на повний екран"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "Потрібно перезапустити для застосування змін"
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "Перемикання OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "Потрібно перезапустити для застосування змін OpenGL"
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "Розподільчу здатність встановлено"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr "Перезавантажте клієнт, щоби застосувати зміни"
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "Налаштування ефектів частинок застосовано"
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr "Зміни буде застосовано після завантаження мапи"
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "Навички"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:262
+#, c-format
+msgid "Skill points available: %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:314
+#, c-format
+msgid "Skill Set %d"
+msgstr ""
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "Навички"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "Рівень: %d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "Рівень: %d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "Створити гільдію"
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "Ви дійсно хочете вийти?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > Запросити гравця до групи"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > Запросити гравця до групи"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "Ви дійсно хочете вийти?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr "Створити гільдію"
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "Створити персонажа"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "Запросити гравця"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "Великий"
+
+#: src/gui/socialwindow.cpp:394
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "Прийнято запрошення від %s."
+
+#: src/gui/socialwindow.cpp:400
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "Відхилено запрошення від %s."
+
+#: src/gui/socialwindow.cpp:413
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "Прийнято запрошення від %s."
+
+#: src/gui/socialwindow.cpp:419
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "Відхилено запрошення від %s."
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "Гільдія"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "Оберіть сервер"
+
+#: src/gui/socialwindow.cpp:497
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "Отримано запрошення до групи, але одне вже є."
+
+#: src/gui/socialwindow.cpp:502
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s запрошує вас до групи %s."
+
+#: src/gui/socialwindow.cpp:507
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "Запрошення до групи прийнято"
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr "Отримано запрошення до групи, але одне вже є."
+
+#: src/gui/socialwindow.cpp:529
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s запрошує вас приєднатись до їх групи."
+
+#: src/gui/socialwindow.cpp:533
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s запрошує вас до групи %s."
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s запрошує вас приєднатись до їх групи."
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s запрошує вас до групи %s."
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr "Запрошення до групи прийнято"
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "Група"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "Оберіть сервер"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "Рівень: %d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "Кошти: %s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr "Професія: %d"
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr "Професія:"
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "Кошти: %d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "Професія:"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "Характеристики персонажа в нормі"
+
+#: src/gui/statuswindow.cpp:235
+#, c-format
+msgid "Correction points: %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "Рівень: %d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "Запропонувати торгівлю"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr "Прийнято. Чекаємо..."
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr "Згодитися торгувати"
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr "Згода. Чекаємо..."
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr "Торгівля: ти"
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "Обмінятися"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "Додати"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "Ти отримуєш: %s."
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "Ти віддаєш: %s."
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "Заміна"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr "Не вдається додати предмет. Не можна накладати предмети одного типу."
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "У тебе недостатньо грошей!"
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "Ім'я: %s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "Оновлення..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "З'єднуюсь..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr ""
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr "##1 Процес поновлення не завершився!"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr "##1 Настійно рекомендовано:"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 спробувати ще раз пізніше"
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "Закінчено"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > Показує перелік користувачів поточного каналу"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > Встановлює тему для поточного каналу"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > Полишити канал"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > Призначити користувача оператором каналу"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > Вигнати користувача з каналу"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "Команда: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "Ця команда показує користувачів каналу"
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "Команда: /topic <тема каналу>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "Ця команда встановлює тему каналу"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "Команда: /quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "Команда закриває поточний канал"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "Якщо ти останній користувач каналу — його буде закрито"
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "Комманда: /op <псевдонім>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+"Ця команда призначає оператором каналу користувача зі вказаним псевдонімом"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+"Оператори каналу можуть виганяти користувачів, або призначати нових "
+"операторів"
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "Команда: /kick <псевдонім>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "Ця команда виганяє з каналу користувача зі вказаним псевдонімом"
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "Потрібно вказати користувача для призначення оператором"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "Потрібно вказати користувача для вигнання з каналу"
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "Глобальне повідомлення:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "Глобальне повідомлення від %s:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s шепоче: "
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr "Чи ж можна говорити без слів?"
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr "Закрити вкладку приватної бесіди"
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr "Команда: /close"
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr "Ця команда закриває вкладку приватної бесіди"
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "Команда: /where"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "Відображає кількість гравців он-лайн"
+
+#: src/gui/widgets/whispertab.cpp:94
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+"Ця команда вмикає ведення журналу чату (записує весь вміст чату у <_файл_>)"
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "Стан"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr ""
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "Оберіть сервер"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "Заміна"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "Оберіть сервер"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr "Підняти"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr "Опустити"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr "Пересунути вліво"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr "Пересунути вправо"
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr "Нападати"
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr "Вибрати ціль і нападати"
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr "Емоція"
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr "Розмовляти"
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr "Зупинити напад"
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "Вибрати найближчу ціль"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr "Вибрати комп'ютерного персонажа"
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr "Вибрати ігрока"
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr "Підняти"
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr "Сховати вікна"
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr "Присісти й відпочити"
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "Знімок екрану"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr "Дозволити/заборонити торгівлю"
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr "Прямувати до вказівника миші"
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "Скорочений доступ %d"
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr "Вікно підказки"
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr "Вікно стану"
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr "Вікно майна"
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr "Вікно екіпіровки"
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr "Вікно навичок"
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr "Вікно мінімапи"
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr "Вікно балачки"
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr "Вікно скороченого доступу"
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr "Вікно налаштувань"
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr "Вікно зневаждення"
+
+#: src/keyboardconfig.cpp:80
+#, fuzzy
+msgid "Social Window"
+msgstr "Вікно навичок"
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr "Вікно емоцій"
+
+#: src/keyboardconfig.cpp:82
+#, fuzzy
+msgid "Outfits Window"
+msgstr "Вікно стану"
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr "Перейти до балачки"
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr "Гортати балачку вище"
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr "Гортати балачку нижче"
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr "Попередня вкладка балачки"
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr "Наступна вкладка балачки"
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "Необхідно усунути повтори, інакше керування може бути ускладненим"
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr "Параметри:"
+
+#: src/main.cpp:45
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -h --help : показати ще раз цю довідку"
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : показати ще раз цю довідку"
+
+#: src/main.cpp:47
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : файл, з якого необхідно завантажити налаштування"
+
+#: src/main.cpp:48
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -P --password : зареєструватися на сервері зі вказаним паролем"
+
+#: src/main.cpp:49
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : зареєструватися на сервері зі вказаним паролем"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -P --password : зареєструватися на сервері зі вказаним паролем"
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -P --password : зареєструватися на сервері зі вказаним паролем"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : сервер, з якого необхідно завантажити оновлення"
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -H --update-host : сервер, з якого необхідно завантажити оновлення"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data : тека, з якої необхідно завантажити данні"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : тека, котру необхідно вживати як домашню"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : тека, котру необхідно вживати як домашню"
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "Не можна надсилати порожні повідомлення!"
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "Гравець"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "Назва"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+msgid "Authentication failed."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "Сила"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "Спритність"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "Витривалість"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "Інтелект"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "Вправність"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "Талан"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "Захист:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "Маг. напад:"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "Маг. захист:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "Точність (%):"
+
+#: src/net/ea/generalhandler.cpp:228
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "Ухиляння (%):"
+
+#: src/net/ea/generalhandler.cpp:229
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "Критичний удар"
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/party > Запросити гравця до групи"
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > Вигнати користувача з каналу"
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "Ця команда запрошує гравця <_ім'я_> до вас в групу"
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "Ця команда встановлює тему каналу"
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "Чорт зна яка команда"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "Не зареєстрований"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "Змінити пароль"
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "Відхилено запрошення від %s."
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+msgid "Connection to server terminated. "
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "Ти отримуєш: %s."
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "Ти віддаєш: %s."
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "Отримано запрошення до групи, але одне вже є."
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "Характеристики персонажа в нормі"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "Характеристики персонажа в нормі"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "Вкажіть кількість предметів"
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "Чорт зна яка команда"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "Гравець вдарив Тварюку"
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "Команда: /join <_канал_>"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Listing channels."
+msgstr "Вимагається приєднання до каналу %s."
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "Чорт зна яка команда"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "Шепіт"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+#, fuzzy
+msgid "Already logged in."
+msgstr "Вже записується"
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "Введіть новий пароль двічі:"
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "Двічі введіть вашу нову адресу електронної пошти:"
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "Відхилено запрошення від %s."
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|Повністю ігнорувати %s@@"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "no"
+#~ msgstr "ні"
+
+#~ msgid "Buddy"
+#~ msgstr "Товариш"
+
+#~ msgid "Buddy List"
+#~ msgstr "Список товаришів"
+
+#~ msgid "Description: %s"
+#~ msgstr "Опис: %s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "Ефект: %s"
+
+#~ msgid "Previous"
+#~ msgstr "Повернутись"
+
+#~ msgid "New"
+#~ msgstr "Новий"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "Рівень професії: %d"
+
+#~ msgid "Present: "
+#~ msgstr "Присутній: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "Покинути гільдію"
+
+#~ msgid "Ok"
+#~ msgstr "Ок"
+
+#~ msgid "Recent:"
+#~ msgstr "Нещодавні:"
+
+#~ msgid "Magic"
+#~ msgstr "Магія"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "Вимовити пробне закляття №1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "Вимовити пробне закляття №2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "Вимовити пробне закляття №3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "\"Дворука\" зброя"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@attack|Напасти на %s@@"
+
+#~ msgid "@@disregard|Disregard %s@@"
+#~ msgstr "@@disregard|Нехтувати %s@@"
+
+#~ msgid "@@ignore|Ignore %s@@"
+#~ msgstr "@@ignore|Ігнорувати %s@@"
+
+#~ msgid "@@unignore|Un-Ignore %s@@"
+#~ msgstr "@@unignore|Не ігнорувати %s@@"
+
+#~ msgid "@@admin-kick|Kick player@@"
+#~ msgstr "@@admin-kick|Викинути гравця@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@cancel|Скасувати@@"
+
+#~ msgid "@@pickup|Pick up %s@@"
+#~ msgstr "@@pickup|Підняти %s@@"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|Зняти@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|Зняти@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@use|Використати@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|Викинути@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|Розділити@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|Помістити@@"
+
+#~ msgid "@@retrieve|Retrieve@@"
+#~ msgstr "@@retrieve|Забрати@@"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "Не вдалося перемкнути до "
+
+#~ msgid "windowed"
+#~ msgstr "у вікні"
+
+#~ msgid "fullscreen"
+#~ msgstr "на весь екран"
+
+#~ msgid "Weapons"
+#~ msgstr "Зброя"
+
+#~ msgid "Crafts"
+#~ msgstr "Ремесла"
+
+#~ msgid "Stats"
+#~ msgstr "Статистика"
+
+#~ msgid "Total"
+#~ msgstr "Загалом"
+
+#~ msgid "Cost"
+#~ msgstr "Ціна"
+
+#~ msgid "Attack:"
+#~ msgstr "Напад:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "РЕакція (%)"
+
+#~ msgid "Max level"
+#~ msgstr "Найвищий рівень"
+
+#~ msgid " host: "
+#~ msgstr " сервер: "
+
+#~ msgid "Guilds"
+#~ msgstr "Гільдії"
+
+#~ msgid "Buddys"
+#~ msgstr "Приятелі"
+
+#~ msgid "Party Window"
+#~ msgstr "Вікно групи"
+
+#~ msgid "Unarmed"
+#~ msgstr "Без зброї"
+
+#~ msgid "Knife"
+#~ msgstr "Ніж"
+
+#~ msgid "Sword"
+#~ msgstr "Меч"
+
+#~ msgid "Polearm"
+#~ msgstr "Патериця"
+
+#~ msgid "Staff"
+#~ msgstr "Палиця"
+
+#~ msgid "Whip"
+#~ msgstr "Батіг"
+
+#~ msgid "Bow"
+#~ msgstr "Лук"
+
+#~ msgid "Shooting"
+#~ msgstr "Стрільба"
+
+#~ msgid "Mace"
+#~ msgstr "Булава"
+
+#~ msgid "Axe"
+#~ msgstr "Сокира"
+
+#~ msgid "Thrown"
+#~ msgstr "Для кидання"
+
+#~ msgid "Craft"
+#~ msgstr "Ремесло"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "Невідома навичка"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " ще не існує, і неможливо створити! Закінчую."
+
+#~ msgid "Couldn't set "
+#~ msgstr "Неможливо встановити "
+
+#~ msgid " video mode: "
+#~ msgstr " відеорежим: "
diff --git a/po/zh_CN.po b/po/zh_CN.po
new file mode 100644
index 000000000..e8e52e5a6
--- /dev/null
+++ b/po/zh_CN.po
@@ -0,0 +1,3966 @@
+# Simplified Chinese translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+#
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+# Hong Hao <oahong@gmail.com>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2010-01-05 23:49+0000\n"
+"Last-Translator: luojie-dune <Unknown>\n"
+"Language-Team: Chinese Simplified <themanaworld-devel@lists.sourceforge."
+"net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+"X-Poedit-Country: China\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "设置"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "正在连接 地图 服务器..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "登录"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "选择角色"
+
+#: src/client.cpp:768
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "正在连接 地图 服务器..."
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "错误"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "密码:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "改变"
+
+#: src/client.cpp:863
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "会员晋升成功。"
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "注销"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "无效的更新主机: "
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr "创建更新目录错误!"
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "未知命令。"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- 帮助 --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/help > 显示此帮助"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > 显示地图名"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > 显示在线用户数"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > 自我介绍"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > 清除此窗口"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > 发送私人信息给用户"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > msg的别名"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > msg的别名"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > 为和其他用户之间的私密信息开启一个新的标签页"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q > query的别名"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > 显示所有公共频道"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/join > 加入或者创建一个新的频道"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > 创建一个新的帮会"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "邀请一个用户加入队伍"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/record > 开始记录聊天至外部文件"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > 确定<回车>键是否切换聊天日志"
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr "/present > 获取列席的玩家列表(若开启logging,则发送到聊天日志)"
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > 全局通告(限GM使用)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "输入 /help <命令>,获取更多信息。"
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "命令: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "该命令可显示所有可用命令。"
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "命令: /help <命令>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "该命令显现<命令>的帮助信息"
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "命令: /announce <信息>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** 只有GM可用 ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "该命令会发送<信息>给所有在线用户。"
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "命令: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "该命令可清除历史聊天记录。"
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "命令:/item <策略>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "该条命令可显现当前在线用户总数。"
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "命令:/join <频道>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "该命令让您进入<频道>。"
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "如果<频道>不存在,自动创建。"
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "命令:/list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "改命令列出所有频道列表。"
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "命令:/me <信息>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr "该命令告诉别人你正在(做)<信息>。"
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "命令:/msg <昵称><信息>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "命令:/whisper <昵称><信息>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "命令:/w <昵称><信息>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "该命令发送文本<信息>给<昵称>。"
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "如果<昵称>之间有空格,用双引号(\")括起来。"
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "命令:/query <昵称>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "命令:/q <昵称>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr "该命令尝试为您和<昵称>之间的密语开启一个新的标签。"
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "命令:/create <帮会名>"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "这些命令创建一个被称为<帮会名>的新帮会。"
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "命令:/party <昵称>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr "该命令邀请<昵称>和你聚会。"
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "命令: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr "该命令得到列席的玩家名单并传送到记录日志如果记录,否则聊天记录。"
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "命令: /record <文件名>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr "该命令开始记录聊天日志至文件<文件名>。"
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "命令: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr "此命令结束将此会话记录"
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr "命令: /toggle <状态>"
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr "该命令设置回车键是否切换聊天日志,或者聊天日志功能是否自动关闭。"
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr "<状态> 可用“1”、“yes”、“true”来开启,或以“0”、“no”、“false”关闭。"
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr "命令: /toggle"
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr "该命令显示<回车>键切换状态"
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "命令:/item <策略>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "命令: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "该条命令显示当前地图名。"
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "命令: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "该条命令可显现当前在线用户总数。"
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "输入 /help 获取命令列表。"
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr "无法发送空白密语!"
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr "无法同 \"%s\" 建立一个私人谈话标签页!或者已经存在,或者那就是自己。"
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "请求加入频道%s。"
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr "帮会名称缺失。"
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr "讯息关闭聊天。"
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr "<回车>键现在切换聊天。"
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr "讯息现在关闭聊天。"
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+#, fuzzy
+msgid "Player successfully ignored!"
+msgstr "帮会创建成功。"
+
+#: src/commandhandler.cpp:486
+#, fuzzy
+msgid "Player could not be ignored!"
+msgstr "密语无法发送,你已被用户忽略。"
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "密语无法发送,你已被用户忽略。"
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr "/%s的选项是\"yes\",\"no\",\"true\",\"false\",\"1\",\"0\"。"
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "常规"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "屏幕快照保存至 ~/"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "保存屏幕快照失败!"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "与服务器连接丢失,程序将会退出."
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "网络错误"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr "忽略新进的交易请求"
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "接受传入的交易请求"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "无法加载地图"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "加载%s时出现错误"
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "帮会(%s)"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "购买"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "价格:%s / 总价:%s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "退出"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "最大"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "商店"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "出售"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "取消"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "更换Email地址"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "帐号:%s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "输入新Email地址两次:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "用户名至少需要%d个字符。"
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "用户名不能少于%d个字符"
+
+#: src/gui/changeemaildialog.cpp:141
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "新电子邮件地址已经存在。"
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "更换密码"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "密码:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "输入新密码两次:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "密码需要至少%d个字符"
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "密码不能少于%d个字符。"
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "创建角色"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "姓名"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "发色:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "发型:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "建立"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "帅哥"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "美女"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "请分发%d点数"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "你的名字需要至少4个字符"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "角色状态可以"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "请删除%d点数"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "确认删除角色"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "你确定想删除这个角色?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "帐号和角色管理"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "注销"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "更换Email地址"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "删除"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "关闭"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "聊天"
+
+#: src/gui/chat.cpp:287
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d 玩家出席。"
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "对%s密语到:%s"
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "是"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "否"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, fuzzy, c-format
+msgid "Music: %s"
+msgstr "主题:%s"
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "姓名:%s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "小地图"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "粒子效果"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "纹理细节"
+
+#: src/gui/debugwindow.cpp:121
+#, fuzzy, c-format
+msgid "Ambient FX: %s"
+msgstr "环境音效"
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "装备"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "卸下装备"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "帮助"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "关闭"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "物品栏"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "装备"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "使用"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "丢弃"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "分离"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr "槽:"
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "重量:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "丢弃"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "确定"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "全部"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "请选择交易的物品数量。"
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "请选择丢弃的物品数量。"
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr "请选择存储的物品数量。"
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr "请选择取回的物品数量。"
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "请选择你分离的物品的数量"
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "重量: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "登录"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "保存用户名"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "注册"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "服务器"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "地图"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "等待服务器中"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "下一个"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr "提交"
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "重置"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "下一个"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr "至:"
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "发送"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "发送信件失败或者信件无效。"
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "卸下装备"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "文本"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "文本阴影"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr "文本轮廓"
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr "进度条标签"
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "背景"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr "突出显示"
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr "标签加亮"
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "物品太昂贵"
+
+#: src/gui/palette.cpp:94
+#, fuzzy
+msgid "Item Is Equipped"
+msgstr "物品已装备"
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr "GM"
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "玩家"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr "密语"
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr "是"
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "帮会"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr "帮会"
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "服务器"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr "记录器"
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr "超链接"
+
+# need more contents!!!
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr "存在"
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "其他玩家名"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr "自己的名字"
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "GM名"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "NPCs"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "怪物"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr "未知物品类型"
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr "一般的"
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "帽子"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr "可用的"
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "衬衫"
+
+#: src/gui/palette.cpp:119
+#, fuzzy
+msgid "One Handed Weapons"
+msgstr "单手武器"
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "裤子"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "鞋子"
+
+#: src/gui/palette.cpp:122
+#, fuzzy
+msgid "Two Handed Weapons"
+msgstr "单手武器"
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "盾"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "指环"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "项链"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr "武器"
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "弹药"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr "粒子效果"
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr "拾起通知"
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr "到期通知"
+
+#: src/gui/palette.cpp:133
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "玩家攻击怪兽"
+
+#: src/gui/palette.cpp:135
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "怪兽击打玩家"
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr "会心一击"
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr "失误"
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr "HP条"
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr "3/4 HP条"
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr "1/2 HP条"
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr "1/4 HP条"
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "与%s交易中"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "攻击 %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "密语"
+
+#: src/gui/popupmenu.cpp:101
+#, fuzzy, c-format
+msgid "Befriend %s"
+msgstr "@@friend|和%s成为朋友@@"
+
+#: src/gui/popupmenu.cpp:106
+#, fuzzy, c-format
+msgid "Disregard %s"
+msgstr "被忽视的"
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "忽略"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, fuzzy, c-format
+msgid "Completely ignore %s"
+msgstr "@@ignore|完全忽略%s@@"
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, fuzzy, c-format
+msgid "Invite %s to join your guild"
+msgstr "@@guild|邀请%s加入你的工会@@"
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "@@party|邀请%s加入你的帮会@@"
+
+#: src/gui/popupmenu.cpp:144
+#, fuzzy
+msgid "Kick player"
+msgstr "踢出失败!"
+
+#: src/gui/popupmenu.cpp:153
+#, fuzzy, c-format
+msgid "Talk to %s"
+msgstr "@@talk|和%s交谈@@"
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "@@admin-kick|踢掉怪物@@"
+
+#: src/gui/popupmenu.cpp:174
+#, fuzzy
+msgid "Add name to chat"
+msgstr "@@name|添加姓名至聊天@@"
+
+#: src/gui/popupmenu.cpp:191
+#, fuzzy, c-format
+msgid "Pick up %s"
+msgstr "捡起"
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|添加到聊天@@"
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr "存储"
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr "取回"
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "交换服务器"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "交换角色"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr "结束录制。"
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr "不在当前录制中。"
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr "已经录制中。"
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr "开始录制……"
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr "开始录制失败。"
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr "录制中……"
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr "停止录制"
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "确认:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "电子邮件"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "用户名至少需要%d个字符。"
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "用户名不能少于%d个字符"
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "密码需要至少%d个字符"
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "密码不能少于%d个字符。"
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "密码不一致."
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "选择你的服务器"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "服务器:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "端口:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "服务器:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "连接中..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "自定义鼠标"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "请输入服务器的IP地址和端口"
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "等待服务器中"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "声音"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "音频"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "音效声量"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "音乐声量"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "无文本"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr "这就是该色彩看起来的样子"
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "颜色"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "类型: "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr "静止的"
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "脉冲"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "彩虹"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "色谱"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "显示: "
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "红: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "绿: "
+
+#: src/gui/setup_colors.cpp:137
+#, fuzzy
+msgid "Blue:"
+msgstr "蓝: "
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "应用"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "重置窗口"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "按下开始校准按钮"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "校准"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "启用游戏杆"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "游戏杆"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "停止"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "旋转手柄"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "键盘"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "分配"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "预设"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr "检测到按键冲突。"
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "姓名"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr "关系"
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "中立"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "好友"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr "被忽视的"
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "忽略"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "允许交易"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr "允许密语"
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr "将所有密语放于标签夜"
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "显示姓名"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "玩家"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr "当忽略时:"
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr "微小"
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "小"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "中等"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "大"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "无文本"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr "气泡,无名"
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr "有名气泡"
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "关闭"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "低"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "高"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "中"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "最大"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "全屏"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "自定义鼠标"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr "可见姓名"
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr "粒子效果"
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "显示姓名"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr "显示拾起通知"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr "聊天中"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr "作为发射武器"
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS限制:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "视频"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "显示姓名"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr "头顶文字"
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "Gui 透明度"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr "环境音效"
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "纹理细节"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "字体大小"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "否"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "切换到全屏"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "重启生效"
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "改变成OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "运用改变为OpenGL需要重新开始"
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "分辨率已变更"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr "重启您的游戏客户端以使变更生效。"
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "粒子效果设置已变更。"
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr "变更会在地图更换时生效。"
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "技能"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "升级"
+
+#: src/gui/skilldialog.cpp:262
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "技能点数:%d"
+
+#: src/gui/skilldialog.cpp:314
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "技能点数:%d"
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "技能"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "等级:%d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "等级:%d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "帮会已创建"
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "创建帮会"
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "确定退出游戏?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "邀请一个用户加入队伍"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "邀请一个用户加入队伍"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "确定退出游戏?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr "创建帮会"
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "创建角色"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "邀请用户"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "大"
+
+#: src/gui/socialwindow.cpp:394
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "接受%s的邀请。"
+
+#: src/gui/socialwindow.cpp:400
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "拒绝%s的邀请。"
+
+#: src/gui/socialwindow.cpp:413
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "接受%s的邀请。"
+
+#: src/gui/socialwindow.cpp:419
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "拒绝%s的邀请。"
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "帮会"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "选择你的服务器"
+
+#: src/gui/socialwindow.cpp:497
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "接受到一个已经存在的帮会邀请。"
+
+#: src/gui/socialwindow.cpp:502
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s已经邀请你加入帮会%s。"
+
+#: src/gui/socialwindow.cpp:507
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "接受帮会邀请"
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr "接受到一个已经存在的帮会邀请。"
+
+#: src/gui/socialwindow.cpp:529
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s已经邀请你加入他们的帮会。"
+
+#: src/gui/socialwindow.cpp:533
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s已经邀请你加入帮会%s。"
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s已经邀请你加入他们的帮会。"
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s已经邀请你加入帮会%s。"
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr "接受帮会邀请"
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "帮会"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "选择你的服务器"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "等级:%d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "金币: %s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr "经验:"
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr "职业:%d"
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr "职业:"
+
+#: src/gui/statuswindow.cpp:194
+#, fuzzy
+msgid "HP"
+msgstr "HP:"
+
+#: src/gui/statuswindow.cpp:200
+#, fuzzy
+msgid "MP"
+msgstr "MP:"
+
+#: src/gui/statuswindow.cpp:206
+#, fuzzy
+msgid "Exp"
+msgstr "经验:"
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "金钱:%d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "职业:"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "角色状态可以"
+
+#: src/gui/statuswindow.cpp:235
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "技能点数:%d"
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "等级:%d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr "仓库"
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "打算交易"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr "已确认。等待中……"
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr "同意交易"
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr "已同意。等待中……"
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr "交易:你"
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "交易"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "添加"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "你得到%s。"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "你给予:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "改变"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr "添加物品失败。你不能覆盖窗口中的该类物品。"
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "你没有足够的钱币."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "姓名:%s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "更新..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "连接中..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr "开始"
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr "##1 更新过程不完整。"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr "##1 强烈建议"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 您稍候再次尝试"
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "已完成"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/usr > 列出当前频道的用户"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > 设置当前聊天频道的主题"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > 离开频道"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > 使用户称为频道管理员"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > 把用户踢出频道"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "命令:/users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "该命令显示当前频道的用户"
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "命令:/topic <讯息>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "该命令设置主题为<讯息>"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "命令:/quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "该命令离开当前频道"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "如果你是该频道的最后成员,离开后该频道将被删除。"
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "命令:/op <昵称>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "该命令使<昵称>成为频道管理员。"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr "频道管理员可以踢出或者op频道内的其他用户"
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "命令:/kick <昵称>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "该命令致使<昵称>离开频道。"
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "需要一个用户来操作"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "踢人时需要指定用户!"
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "全局公告:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "%s 全局公告:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s悄悄的对您说: "
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr "无法发送空白信息!"
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr "/close > 关闭密语标签页"
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr "命令: /close"
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr "该命令关闭当前密语标签页。"
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "命令:/item"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "该条命令可显现当前在线用户总数。"
+
+#: src/gui/widgets/whispertab.cpp:94
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "该命令开始记录聊天日志至文件<文件名>。"
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "状态"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "快捷键"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "选择OK"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "改变"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "选择你的服务器"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr "向上移动"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr "向下移动"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr "向左移动"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr "向右移动"
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr "攻击"
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr "对准并攻击"
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr "笑脸"
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr "说话"
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr "停止攻击"
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "对准最近目标"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr "目标NPC"
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr "目标玩家"
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr "捡起"
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr "隐藏窗口"
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr "坐下"
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "屏幕快照"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr "开启/关闭交易"
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "物品快捷 %d"
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr "帮助窗口"
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr "状态窗口"
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr "物品栏窗口"
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr "装备窗口"
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr "技能窗口"
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr "小地图窗口"
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr "聊天窗口"
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr "物品快捷窗口"
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr "设置窗口"
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr "Debug窗口"
+
+#: src/keyboardconfig.cpp:80
+#, fuzzy
+msgid "Social Window"
+msgstr "技能窗口"
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr "表情快捷窗口"
+
+#: src/keyboardconfig.cpp:82
+#, fuzzy
+msgid "Outfits Window"
+msgstr "状态窗口"
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "表情快捷键为 %d"
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr "切换聊天"
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr "向上滚动聊天记录"
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr "向下滚动聊天记录"
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr "上一个聊天窗口标签页"
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr "下一个聊天窗口标签页"
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr "选择OK"
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr "忽略输入1"
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr "忽略输入2"
+
+#: src/keyboardconfig.cpp:178
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "解决按键冲突,否者游戏过程中可能发生奇怪行为。"
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr "无法拾取物品。"
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "你捡起%s [@@%d|%s@@]。"
+msgstr[1] "你捡起%s [@@%d|%s@@]。"
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr "选项:"
+
+#: src/main.cpp:45
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version\t:显示版本号"
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help\t: 显示该帮助"
+
+#: src/main.cpp:47
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file\t: 使用的配置文件"
+
+#: src/main.cpp:48
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U --username\t:以该用户名登录游戏"
+
+#: src/main.cpp:49
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password\t: 以该密码登录"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character\t: 以该角色登录"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server\t: 登录服务器名或IP"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port\t: 登录服务器端口"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host\t: 使用该更新主机"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default\t: 选择某人角色服务器和角色"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update\t:跳过下载更新"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d --data\t: 从此目录加载游戏数据"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir\t: 用该目录作为家目录"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir\t: 用该目录作为家目录"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl\t:为该次会话关闭OpenGL"
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr "踢出失败!"
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr "成功踢出!"
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr "无物可供出售。"
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr "谢谢你的购买。"
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr "无法购买。"
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr "感谢您的出售。"
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr "无法出售."
+
+#: src/net/ea/charserverhandler.cpp:103
+#, fuzzy
+msgid "Access denied."
+msgstr "访问被拒绝"
+
+#: src/net/ea/charserverhandler.cpp:106
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "不能使用该ID"
+
+#: src/net/ea/charserverhandler.cpp:109
+#, fuzzy
+msgid "Unknown failure to select character."
+msgstr "选择人物时遇到未知错误"
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "创建角色失败。很可能名称已被占用。"
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr "信息"
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr "角色已删除。"
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr "删除角色失败。"
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "力量:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "敏捷:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "生命:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "智力:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "灵巧:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr "幸运:"
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr "密语无法发送,用户已离线。"
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr "密语无法发送,你已被用户忽略。"
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "玩家"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr "聊天频道不被支持!"
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "姓名"
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "请求交易"
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr "力量 %+d"
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr "敏捷 %+d"
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr "生命 %+d"
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr "智慧 %+d"
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr "敏捷 %+d"
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr "幸运 %+d"
+
+#: src/net/ea/generalhandler.cpp:130
+#, fuzzy
+msgid "Authentication failed."
+msgstr "验证失败"
+
+#: src/net/ea/generalhandler.cpp:133
+#, fuzzy
+msgid "No servers available."
+msgstr "无可用服务器"
+
+#: src/net/ea/generalhandler.cpp:137
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "某人正在尝试使用该帐号"
+
+#: src/net/ea/generalhandler.cpp:140
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "该帐号已经登录"
+
+#: src/net/ea/generalhandler.cpp:143
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "检测到调速作弊"
+
+#: src/net/ea/generalhandler.cpp:146
+#, fuzzy
+msgid "Duplicated login."
+msgstr "重复登录"
+
+#: src/net/ea/generalhandler.cpp:149
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "未知连接错误"
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr "和服务器失去连接"
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "力量"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "敏捷"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "生命"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "智慧"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "敏捷"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "幸运"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "防御:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "魔攻:"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "魔防:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Ac精确度:"
+
+#: src/net/ea/generalhandler.cpp:228
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% E回避率:"
+
+#: src/net/ea/generalhandler.cpp:229
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "会心一击"
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr "/help > 显示该帮助信息。"
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > 邀请某一玩家加入您的帮会"
+
+#: src/net/ea/gui/guildtab.cpp:63
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > 离开你所在的帮会"
+
+#: src/net/ea/gui/guildtab.cpp:64
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > 把某人踢出你所在的帮会"
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr "命令:/invite <昵称>"
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "该命令邀请<昵称>和你聚会。"
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr "命令:/leave"
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "该命令致使玩家离开帮会"
+
+#: src/net/ea/gui/guildtab.cpp:89
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "帮会名称缺失。"
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s现在是你帮会中的成员了。"
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "未知邀请应答%s。"
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > 邀请某一玩家加入您的帮会"
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > 离开你所在的帮会"
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > 把某人踢出你所在的帮会"
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > 显示/改变帮会项目共享选项"
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > 显示/改变帮会经验共享选项"
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr "该命令致使玩家离开帮会"
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr "命令:/item <策略>"
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr "改命令改变帮会的物品共享策略。"
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<策略>可以为“1”,“yes”,“true”其中之一以开启物品共享,或者 是\"0\",\"no\","
+"\"false\"用来禁止物品共享。"
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr "命令:/item"
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr "该命令显示帮会现有的物品共享策略。"
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr "命令:/exp <策略>"
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr "该命令改变帮会的经验共享策略。"
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<策略>可以为“1”,“yes”,“true”其中之一以开启经验共享,或者 是\"0\",\"no\","
+"\"false\"用来关闭经验共享。"
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr "命令:/exp"
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr "该命令显示帮会现有的经验共享策略。"
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr "物品共享开启。"
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr "物品共享关闭。"
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr "物品共享不可能。"
+
+#: src/net/ea/gui/partytab.cpp:141
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "物品共享开启。"
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr "经验共享开启。"
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr "经验共享关闭。"
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr "经验共享不可能。"
+
+#: src/net/ea/gui/partytab.cpp:176
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "经验共享开启。"
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr "使用物品失败。"
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr "无法装备。"
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr "无法卸载装备。"
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr "帐号不存在。请重新登录。"
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "原密码错误"
+
+#: src/net/ea/loginhandler.cpp:85
+#, fuzzy
+msgid "New password too short."
+msgstr "新密码太短"
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "未明错误"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "未注册ID"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "错误的密码"
+
+#: src/net/ea/loginhandler.cpp:155
+#, fuzzy
+msgid "Account expired."
+msgstr "帐号期满"
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "登录请求被拒绝"
+
+#: src/net/ea/loginhandler.cpp:161
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "你已被永久性禁止游戏。请联系GM团队。"
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"你被暂时禁止进入游戏直到%s.\n"
+"请通过论坛联系GM组"
+
+#: src/net/ea/loginhandler.cpp:172
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "该用户名已被使用"
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "无法出售."
+
+#: src/net/ea/network.cpp:414
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "正在连接 地图 服务器..."
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr "无法创建帮会。"
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr "帮会创建成功。"
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s已经是你的帮会成员了。"
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s拒绝了您的邀请。"
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s现在是你帮会中的成员了。"
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr "未知邀请应答%s。"
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr "你以退出帮会"
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr "%s已经离开你的帮会。"
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "一未知成员尝试说:%s"
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr "这种方式的邀请暂时不支持。"
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s不在你的帮会中!"
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr "你已玩完了。"
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "很遗憾的告诉您,您的角色在战斗中死亡了"
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr "你再也不是那样的生机勃勃了。"
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr "游戏结束!"
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr "投入游戏币继续。"
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr "不,孩子。你的角色没有真正死亡。他……呃……不过是去了一个更好的地方而已。"
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr "被消灭了。"
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr "你还没死,你只是在休息"
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+"<策略>可以为“1”,“yes”,“true”其中之一以开启物品共享,或者 是\"0\",\"no\","
+"\"false\"用来禁止物品共享。"
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr "讯息"
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "你已携带超过半数负重。无法回复健康(体力)"
+
+#: src/net/ea/playerhandler.cpp:333
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "你捡起 "
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr "请先装备弓箭。"
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr "交易失败!"
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr "发送表情失败!"
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr "原地休息失败!"
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr "聊天创建失败!"
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr "不能加入工会!"
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr "无法呼喊!"
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr "你还没有达到足够的等级!"
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr "HP不足!"
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr "SP不足!"
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr "没有备忘录"
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr "你无法办到!"
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr "看起来需要更多金币…… ;-)"
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "此武器无法用来使用此项技能!"
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr "你需要另一颗红宝石!"
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr "你需要另一颗蓝宝石!"
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr "你已负重太多,无法办到!"
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr "啊?那是什么?"
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr "传送失败..."
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr "无法偷取任何物品..."
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr "毒药无效..."
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr "请求交易"
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s想和您进行交易,是否接受?"
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "交易不可能进行。与交易伙伴太过太过遥远"
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "交易不可能进行。角色不存在。"
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr "交易取消因不明原因。"
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr "交易:您和%s"
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "与%s的交易被取消。"
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr "未处理的交易取消分组。"
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "添加项目失败。交易伙伴已经负重太多。"
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "添加项目失败。交易伙伴无空闲槽存放物品。"
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr "添加项目失败,原因未知。"
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr "交易取消。"
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr "交易完成。"
+
+#: src/net/manaserv/beinghandler.cpp:324
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " 按OK重新开始"
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "你完蛋了"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+#, fuzzy
+msgid "Not logged in."
+msgstr "已经登录"
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "用户名已存在"
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "角色状态可以"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "角色状态可以"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+#, fuzzy
+msgid "Player deleted."
+msgstr "角色已删除。"
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "请选择交易的物品数量。"
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "未明错误"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr "无 游戏服务器 可用。"
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "意志力:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr "主题:%s"
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "玩家攻击怪兽"
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "命令:/join <频道>"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Listing channels."
+msgstr "请求加入频道%s。"
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s加入了帮会。"
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "未知命令。"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr "意志力 %+d"
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "意志力:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr "帮会已创建"
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr "邀请已发送。"
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr "会员晋升成功。"
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr "晋升会员失败。"
+
+#: src/net/manaserv/loginhandler.cpp:87
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "错误的 magic_token"
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+#, fuzzy
+msgid "Already logged in."
+msgstr "已经登录"
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+#, fuzzy
+msgid "Server is full."
+msgstr "服务器满载"
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "新密码错误"
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr "账户未连接。请先登录。"
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "新电子邮件地址不正确"
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "原电子邮件地址不正确"
+
+#: src/net/manaserv/loginhandler.cpp:158
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "新电子邮件地址已经存在。"
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+#, fuzzy
+msgid "Client version is too old."
+msgstr "客户端版本太旧"
+
+#: src/net/manaserv/loginhandler.cpp:266
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "错误的用户名或密码"
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "错误的用户名,密码或者电子邮件地址"
+
+#: src/net/manaserv/loginhandler.cpp:306
+#, fuzzy
+msgid "Username already exists."
+msgstr "用户名已存在"
+
+#: src/net/manaserv/loginhandler.cpp:309
+#, fuzzy
+msgid "Email address already exists."
+msgstr "电子邮件地址已存在"
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr "加入了帮会。"
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr "%s加入了帮会。"
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s拒绝了您的邀请。"
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr "正在接受交易请求"
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr "忽略交易请求"
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr "与%s交易中"
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|完全忽略%s@@"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "攻击 %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "防护 %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr "未知物品"
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr "未知怪兽"
+
+#~ msgid "no"
+#~ msgstr "不"
+
+#~ msgid "Buddy"
+#~ msgstr "好友"
+
+#~ msgid "Buddy List"
+#~ msgstr "好友列表"
+
+#~ msgid "Description: %s"
+#~ msgstr "描述:%s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "效果:%s"
+
+#~ msgid "Previous"
+#~ msgstr "上一个"
+
+#~ msgid "New"
+#~ msgstr "新建"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "职业等级:%d"
+
+#~ msgid "Present: "
+#~ msgstr "出席: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "退出帮会"
+
+#~ msgid "Ok"
+#~ msgstr "确定"
+
+#~ msgid "Recent:"
+#~ msgstr "最近的"
+
+#~ msgid "Magic"
+#~ msgstr "魔法"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "释放测试符咒1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "释放测试符咒2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "释放测试符咒3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "双手武器"
+
+#~ msgid "@@trade|Trade With %s@@"
+#~ msgstr "@@trade|与%s交易@@"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@attack|攻击%s@@"
+
+#~ msgid "@@disregard|Disregard %s@@"
+#~ msgstr "@@disregard|忽视%s@@"
+
+#~ msgid "@@ignore|Ignore %s@@"
+#~ msgstr "@@ignore|忽略%s@@"
+
+#~ msgid "@@unignore|Un-Ignore %s@@"
+#~ msgstr "@@unignore|Un-Ignore %s@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@cancel|取消@@"
+
+#~ msgid "@@pickup|Pick up %s@@"
+#~ msgstr "@@pickup|捡起%s@@"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@use|卸载@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@use|装备@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@use|使用@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@drop|丢弃@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@split|分离@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|存贮@@"
+
+#~ msgid "Select Server"
+#~ msgstr "选择服务器"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "切换到此时失败: "
+
+#~ msgid "windowed"
+#~ msgstr "窗口化"
+
+#~ msgid "fullscreen"
+#~ msgstr "全屏"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "神秘技能"
+
+#~ msgid "Weapons"
+#~ msgstr "武器"
+
+#~ msgid "Crafts"
+#~ msgstr "技艺"
+
+#~ msgid "Stats"
+#~ msgstr "状态"
+
+#~ msgid "Total"
+#~ msgstr "总计"
+
+#~ msgid "Cost"
+#~ msgstr "花费"
+
+#~ msgid "Attack:"
+#~ msgstr "攻击:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% 伤害反射:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "剩余状态点数:%d"
+
+#~ msgid "Max level"
+#~ msgstr "最大等级"
+
+#~ msgid "curl error "
+#~ msgstr "curl错误 "
+
+#~ msgid " host: "
+#~ msgstr " 主机: "
+
+#~ msgid "Guilds"
+#~ msgstr "工会"
+
+#~ msgid "Buddys"
+#~ msgstr "好友"
+
+#~ msgid "Party Window"
+#~ msgstr "帮会窗口"
+
+#~ msgid "Unarmed"
+#~ msgstr "徒手的"
+
+#~ msgid "Knife"
+#~ msgstr "匕首"
+
+#~ msgid "Sword"
+#~ msgstr "剑"
+
+# 长斧?
+#~ msgid "Polearm"
+#~ msgstr "戟"
+
+#~ msgid "Staff"
+#~ msgstr "工作人员"
+
+#~ msgid "Whip"
+#~ msgstr "抖动"
+
+#~ msgid "Bow"
+#~ msgstr "弓"
+
+#~ msgid "Shooting"
+#~ msgstr "射击"
+
+#~ msgid "Mace"
+#~ msgstr "狼牙棒"
+
+#~ msgid "Axe"
+#~ msgstr "斧头"
+
+#~ msgid "Thrown"
+#~ msgstr "投掷"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "未知技能"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " 不能被创建,不存在!退出中。"
+
+#~ msgid "Couldn't set "
+#~ msgstr "无法设置 "
+
+#~ msgid " video mode: "
+#~ msgstr " 视频模式: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "正在连接 角色 服务器..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "正在连接 帐号 服务器..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > create之别名"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "命令: /new <帮会名>"
+
+#~ msgid "a"
+#~ msgstr "一个"
+
+#~ msgid "Unnamed"
+#~ msgstr "未知物品"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@捡起|捡起%s@@"
+
+#~ msgid "Save player list"
+#~ msgstr "保存玩家列表"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "Scroll laziness"
+
+#~ msgid "Scroll radius"
+#~ msgstr "滑动半径"
diff --git a/po/zh_HK.po b/po/zh_HK.po
new file mode 100644
index 000000000..abeee5078
--- /dev/null
+++ b/po/zh_HK.po
@@ -0,0 +1,3696 @@
+# Traditional Chinese translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+# SECOND AUTHOR <NETWAREBOSS>,2009
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2009-06-08 22:11+0000\n"
+"Last-Translator: lok0919 <lok0919@gmail.com>\n"
+"Language-Team: Traditional Chinese <themanaworld-devel@lists.sourceforge."
+"net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+"X-Poedit-Country: China\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "設定"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "正在連接到地圖伺服器..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "登入"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "選擇角色"
+
+#: src/client.cpp:768
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "正在連接到地圖伺服器..."
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "錯誤"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "密碼:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "更改"
+
+#: src/client.cpp:863
+msgid "Email changed successfully!"
+msgstr ""
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "註冊"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, c-format
+msgid "Invalid update host: %s"
+msgstr ""
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr ""
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "不明指令"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- 說明 --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr ""
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > 顯示地圖名稱"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > 顯示線上人數"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > 告訴一些有關你的事"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > 清除此窗口"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > 發送私人訊息給玩家"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > 等同msg"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > 等同msg"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr ""
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q > 等同query"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > 顯示所有公共頻道"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/join > 加入/建立一個頻道"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/party > 邀請玩家加入隊伍"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "/party > 邀請玩家加入隊伍"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/record > 開始錄製聊天至外部文件"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr ""
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr "/present > 獲取現在的玩家名單(如果錄製聊天中,會發送到聊天記錄)"
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > 公告 (GM only)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr ""
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "指令: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "該指令可顯示所有可用指令。"
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "指令: /help <指令>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "該指令會顯示<指令>的幫助訊息"
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "指令: /announce <信息>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** 只有GM可用 ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "該指令會發送<信息>給所有線上用戶。"
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "指令: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "該指令可以清除聊天紀錄。"
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "/join <頻道>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "這調指令可顯示目前線上人數。"
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "/join <頻道>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "這個指令令你進入 <頻道>."
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "如果<頻道>不存在,將會被建立"
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr ""
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "這個指令會列出所有頻道"
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "/me <信息>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr "這個指令會告訴其他人你正在 <信息>."
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr ""
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "如果<暱稱>之間有空格,用雙引號(\")括起來。"
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr ""
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "指令: /clear"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "這個指令令你進入 <頻道>."
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr ""
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr ""
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr ""
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr ""
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr ""
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr ""
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr ""
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr ""
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr ""
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr ""
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr ""
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "指令: /announce <信息>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "指令: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "這個指令顯示目前地圖名。"
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "指令: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "這調指令可顯示目前線上人數。"
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "輸入 /help 獲取指令列表。"
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr ""
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr ""
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr ""
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr ""
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr ""
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr ""
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+msgid "Player successfully ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:486
+msgid "Player could not be ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+msgid "Player could not be unignored!"
+msgstr ""
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr ""
+
+#: src/game.cpp:172
+msgid "General"
+msgstr ""
+
+#: src/game.cpp:326
+msgid "Screenshot saved as "
+msgstr ""
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr ""
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "正在連接角色伺服器..."
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr ""
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr ""
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "不能加入隊伍!"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr ""
+
+#: src/gui/beingpopup.cpp:75
+#, c-format
+msgid "Party: %s"
+msgstr ""
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "購買"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr ""
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "離開"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr ""
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "商店"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "出售"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "取消"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:51
+msgid "Type new email address twice:"
+msgstr ""
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "用戶名稱至少需要%d個字元。"
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "用戶名稱不能少於%d個字元"
+
+#: src/gui/changeemaildialog.cpp:141
+msgid "The email address entries mismatch."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "密碼:"
+
+#: src/gui/changepassworddialog.cpp:63
+msgid "Type new password twice:"
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "密碼至少需要%d個字元"
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "密碼不能少於%d個字元。"
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "新增角色"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "名字:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "灰色:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "髮型:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "創造"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "男生"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "女生"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "請分配%d點數"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "你的名字至少需要4個字元"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "角色狀態確定"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "請移除%d點數"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "確認刪除角色"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "你確定想刪除這個角色?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "註冊"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "更改"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "刪除"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "關閉"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr ""
+
+#: src/gui/chat.cpp:287
+#, c-format
+msgid "Present: %s; %d players are present."
+msgstr ""
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr ""
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "對%s竊竊私語:%s"
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "是"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "否"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, c-format
+msgid "Music: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "名字:%s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, c-format
+msgid "Minimap: %s"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "紋理細節"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "紋理細節"
+
+#: src/gui/debugwindow.cpp:121
+#, c-format
+msgid "Ambient FX: %s"
+msgstr ""
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "裝備"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "卸下裝備"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "說明"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "關閉"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "物品攔"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "裝備"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "使用"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "丟棄"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "分開"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "丟棄"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "確定"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr ""
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "請選擇交易的物品數量"
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "請選擇丟棄的物品數量"
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr ""
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr ""
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "請選擇你要分離的物品數量"
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "效果:%s"
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "登入"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "保存用戶名"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "註冊"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "更改"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "下一個"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr ""
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr ""
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "下一個"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr ""
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, c-format
+msgid "Outfit: %d"
+msgstr ""
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "卸下裝備"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr ""
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr ""
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr ""
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr ""
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr ""
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr ""
+
+#: src/gui/palette.cpp:93
+msgid "Item Too Expensive"
+msgstr ""
+
+#: src/gui/palette.cpp:94
+msgid "Item Is Equipped"
+msgstr ""
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr ""
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr ""
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr ""
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr ""
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr ""
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr ""
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr ""
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr ""
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr ""
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr ""
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr ""
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr ""
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr ""
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr ""
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr ""
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr ""
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr ""
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr ""
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr ""
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr ""
+
+#: src/gui/palette.cpp:119
+msgid "One Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr ""
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr ""
+
+#: src/gui/palette.cpp:122
+msgid "Two Handed Weapons"
+msgstr ""
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr ""
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr ""
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr ""
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr ""
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr ""
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr ""
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr ""
+
+#: src/gui/palette.cpp:133
+msgid "Player Hits Monster"
+msgstr ""
+
+#: src/gui/palette.cpp:135
+msgid "Monster Hits Player"
+msgstr ""
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr ""
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr ""
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr ""
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "@@交易|與%s交易@@"
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "攻擊:"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "對%s竊竊私語:%s"
+
+#: src/gui/popupmenu.cpp:101
+#, c-format
+msgid "Befriend %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:106
+#, c-format
+msgid "Disregard %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "忽略"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, c-format
+msgid "Completely ignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, c-format
+msgid "Invite %s to join your guild"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:137
+#, c-format
+msgid "Invite %s to join your party"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:144
+msgid "Kick player"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:153
+#, c-format
+msgid "Talk to %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:166
+msgid "Kick monster"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:174
+msgid "Add name to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:191
+#, c-format
+msgid "Pick up %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+msgid "Add to chat"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr ""
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "交換伺服器"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "交換角色"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr ""
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr ""
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr ""
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr ""
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr ""
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "確認:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "電子郵件"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "用戶名稱至少需要%d個字元。"
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "用戶名稱不能少於%d個字元"
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "密碼至少需要%d個字元"
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "密碼不能少於%d個字元。"
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "密碼不一樣."
+
+#: src/gui/serverdialog.cpp:134
+msgid "Choose Your Server"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "伺服器:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "Port:"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "伺服器:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "連線中..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "自訂滑鼠標"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "請輸入伺服氣得IP地址和Port"
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "正在連接到地圖伺服器..."
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "聲音"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "音效"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "音效音量"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "音樂音量"
+
+#: src/gui/setup_audio.cpp:94
+msgid "Notice"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:70
+msgid "Type:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "開始"
+
+#: src/gui/setup_colors.cpp:107
+msgid "Red:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:122
+msgid "Green:"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:137
+msgid "Blue:"
+msgstr ""
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "確定"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "重置視窗"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "按下按鈕開始矯正"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "矯正"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "啟用搖桿"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "搖桿"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "停止"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "旋轉手柄"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "鍵盤"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "分配"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "預設"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr "檢測到按鍵衝突。"
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "名字"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr "關係"
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "中立"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "好友"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr ""
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "忽略"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr ""
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "允許交易"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr "允許密語"
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr ""
+
+#: src/gui/setup_players.cpp:234
+msgid "Show gender"
+msgstr ""
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "玩家"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr "當忽略時:"
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr ""
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr ""
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr ""
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr ""
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "關閉"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "低"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "高"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "中"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "最大"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "全螢幕"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "自訂滑鼠標"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr ""
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr ""
+
+#: src/gui/setup_video.cpp:204
+msgid "Show own name"
+msgstr ""
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr ""
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr ""
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS限制:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "顯示"
+
+#: src/gui/setup_video.cpp:227
+msgid "Show monster damage"
+msgstr ""
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr ""
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "Gui 透明度"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr ""
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "紋理細節"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr ""
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "否"
+
+#: src/gui/setup_video.cpp:381
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:387
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr ""
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "切換全螢幕"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "請重新啟動"
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "切換為OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "確認切換OpenGL需要重新開始"
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+msgid "Screen Resolution Changed"
+msgstr ""
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr ""
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+msgid "Particle Effect Settings Changed."
+msgstr ""
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr ""
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "技能"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "升級"
+
+#: src/gui/skilldialog.cpp:262
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "技能點數:%d"
+
+#: src/gui/skilldialog.cpp:314
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "技能點數:%d"
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "技能"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "等級:%d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "等級:%d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, c-format
+msgid "Guild %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+msgid "Leave Guild?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "你確定想刪除這個角色?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > 邀請玩家加入隊伍"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > 邀請玩家加入隊伍"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "你確定想刪除這個角色?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "新增角色"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+msgid "Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:298
+msgid "Leave"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:394
+#, c-format
+msgid "Accepted party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:400
+#, c-format
+msgid "Rejected party invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:413
+#, c-format
+msgid "Accepted guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:419
+#, c-format
+msgid "Rejected guild invite from %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:463
+#, c-format
+msgid "Creating guild called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+msgid "Guild Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:485
+msgid "Choose your guild's name."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:497
+msgid "Received guild request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:502
+#, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:507
+msgid "Accept Guild Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:529
+msgid "You have been invited you to join a party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:533
+#, c-format
+msgid "You have been invited to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+msgid "Party Name"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:571
+msgid "Choose your party's name."
+msgstr ""
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "等級:%d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr "職業:%d"
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:194
+msgid "HP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:200
+msgid "MP"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:206
+msgid "Exp"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "金錢:%d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "職業:%d"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "角色狀態確定"
+
+#: src/gui/statuswindow.cpp:235
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "技能點數:%d"
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "等級:%d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr ""
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "是否交易"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr ""
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr ""
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr ""
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "交易"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "增加"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "你付出:"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "你付出:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "更改"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr "增加物品失敗。你不能覆蓋視窗中的該類物品能。"
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr ""
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "名字:%s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "更新中..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "連線中..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr "開始"
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr ""
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr ""
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+msgid "##1 you try again later."
+msgstr ""
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "已完成"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr ""
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr ""
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "主要公告:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "%s 主要公告:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "對%s竊竊私語:%s"
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "指令: /where"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "這調指令可顯示目前線上人數。"
+
+#: src/gui/widgets/whispertab.cpp:94
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr ""
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "狀態"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "快捷鍵"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "選擇伺服器"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "更改"
+
+#: src/gui/worldselectdialog.cpp:77
+msgid "Choose World"
+msgstr ""
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr ""
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr ""
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr ""
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr ""
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr ""
+
+#: src/keyboardconfig.cpp:49
+msgid "Target Monster"
+msgstr ""
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr ""
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr ""
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr ""
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr ""
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr ""
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr ""
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr ""
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:80
+msgid "Social Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:82
+msgid "Outfits Window"
+msgstr ""
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr ""
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr ""
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr ""
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr ""
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr ""
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr ""
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr ""
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr ""
+
+#: src/keyboardconfig.cpp:178
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "解決按鍵衝突,否則遊戲中可能遇到奇怪行為。"
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr ""
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr ""
+
+#: src/main.cpp:45
+msgid " -v --version : Display the version"
+msgstr ""
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr "/help > 顯示幫助"
+
+#: src/main.cpp:47
+msgid " -C --config-dir : Configuration directory to use"
+msgstr ""
+
+#: src/main.cpp:48
+msgid " -U --username : Login with this username"
+msgstr ""
+
+#: src/main.cpp:49
+msgid " -P --password : Login with this password"
+msgstr ""
+
+#: src/main.cpp:50
+msgid " -c --character : Login with this character"
+msgstr ""
+
+#: src/main.cpp:51
+msgid " -s --server : Login server name or IP"
+msgstr ""
+
+#: src/main.cpp:52
+msgid " -p --port : Login server port"
+msgstr ""
+
+#: src/main.cpp:53
+msgid " --update-host : Use this update host"
+msgstr ""
+
+#: src/main.cpp:54
+msgid " -D --default : Choose default character server and character"
+msgstr ""
+
+#: src/main.cpp:56
+msgid " -u --skip-update : Skip the update downloads"
+msgstr ""
+
+#: src/main.cpp:57
+msgid " -d --data : Directory to load game data from"
+msgstr ""
+
+#: src/main.cpp:58
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr ""
+
+#: src/main.cpp:59
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr ""
+
+#: src/main.cpp:61
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr ""
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr ""
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:103
+msgid "Access denied."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:106
+msgid "Cannot use this ID."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:109
+msgid "Unknown failure to select character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr ""
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr ""
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "玩家"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "名字"
+
+#: src/net/ea/gamehandler.cpp:100
+msgid "Request to quit denied!"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:130
+#, fuzzy
+msgid "Authentication failed."
+msgstr "聊天新增失敗!"
+
+#: src/net/ea/generalhandler.cpp:133
+msgid "No servers available."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:137
+msgid "Someone else is trying to use this account."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:140
+msgid "This account is already logged in."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:143
+msgid "Speed hack detected."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:146
+msgid "Duplicated login."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:149
+msgid "Unknown connection error."
+msgstr ""
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr "和伺服器失去連線"
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "力量"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "敏捷"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "體力"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "智力"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "閃躲"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "幸運"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "防禦:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "摩攻:"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "魔防:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Ac準確度:"
+
+#: src/net/ea/generalhandler.cpp:228
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% E迴避率:"
+
+#: src/net/ea/generalhandler.cpp:229
+#, c-format
+msgid "% Critical"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr "/help > 顯示幫助"
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/party > 邀請玩家加入隊伍"
+
+#: src/net/ea/gui/guildtab.cpp:63
+msgid "/leave > Leave the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:64
+msgid "/kick > Kick some one from the guild you are in"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "這個指令會告訴其他人你正在 <信息>."
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr ""
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "這個指令顯示目前地圖名。"
+
+#: src/net/ea/gui/guildtab.cpp:89
+msgid "Guild name is missing."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+msgid "User is now part of your guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+msgid "Unknown guild invite response."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:141
+msgid "Item sharing unknown."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:176
+msgid "Experience sharing unknown."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr ""
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+msgid "Old password incorrect."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:85
+msgid "New password too short."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "不明指令"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "註冊"
+
+#: src/net/ea/loginhandler.cpp:152
+msgid "Wrong password."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:155
+msgid "Account expired."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "和伺服器失去連線"
+
+#: src/net/ea/loginhandler.cpp:161
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+
+#: src/net/ea/loginhandler.cpp:172
+msgid "This user name is already taken."
+msgstr ""
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+msgid "Unable to resolve host \""
+msgstr ""
+
+#: src/net/ea/network.cpp:414
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "正在連接到地圖伺服器..."
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:333
+#, c-format
+msgid "You picked up %s."
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr "交易失敗!"
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr "顯示表情失敗!"
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr "坐下休息失敗!"
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr "聊天新增失敗!"
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr "不能加入隊伍!"
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr "無法大叫!"
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr "你還沒達到足夠等級!"
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr "HP不夠!"
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr "SP不夠!"
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr "沒有備忘錄"
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr ""
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "此武器無法使用此技能!"
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr "你需要再一顆紅寶石!"
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr "你需要再一棵藍寶石!"
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr "你已負重太多,不能再多!"
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr "阿?那是甚麼?"
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr "傳送失敗..."
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr "無法偷取任何物品..."
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr "藥水無效..."
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:324
+msgid "Press OK to respawn."
+msgstr ""
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "你付出:"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+msgid "Not logged in."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+msgid "Character's name already exists."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "角色狀態確定"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "角色狀態確定"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+msgid "Player deleted."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "請選擇交易的物品數量"
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "不明指令"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "意志力:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+msgid "Players in this channel:"
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "/join <頻道>"
+
+#: src/net/manaserv/chathandler.cpp:207
+msgid "Listing channels."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, c-format
+msgid "%s entered the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "不明指令"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr ""
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "意志力:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr ""
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:87
+msgid "Wrong magic_token."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+msgid "Already logged in."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+msgid "Server is full."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:118
+msgid "New password incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:149
+msgid "New email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:152
+msgid "Old email address incorrect."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:158
+msgid "The new email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+msgid "Client version is too old."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:266
+msgid "Wrong username or password."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+msgid "Wrong username, password or email address."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:306
+msgid "Username already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:309
+msgid "Email address already exists."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, c-format
+msgid "%s rejected your invite."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr ""
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr ""
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "已完成"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr ""
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "HP %+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "MP %+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr ""
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr ""
+
+#~ msgid "Description: %s"
+#~ msgstr "說明:%s"
+
+#~ msgid "Previous"
+#~ msgstr "上一個"
+
+#~ msgid "New"
+#~ msgstr "新增"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "職業等級:%d"
+
+#~ msgid "Ok"
+#~ msgstr "確認"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@攻擊|攻擊%s@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@取消|取消@@"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@使用|卸下@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@使用|裝備@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@使用|使用@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@丟棄|丟棄@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@分離|分離@@"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "神秘技能"
+
+#~ msgid "Stats"
+#~ msgstr "狀態"
+
+#~ msgid "Total"
+#~ msgstr "總共"
+
+#~ msgid "Cost"
+#~ msgstr "需求"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% 傷害反射:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "剩餘狀態點數:%d"
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "正在連接帳號伺服器..."
+
+#~ msgid "Unnamed"
+#~ msgstr "未知物品"
+
+#~ msgid "Save player list"
+#~ msgstr "保存玩家列表"
+
+#~ msgid "Scroll radius"
+#~ msgstr "捲動半徑"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "捲動延遲"
diff --git a/po/zh_TW.po b/po/zh_TW.po
new file mode 100644
index 000000000..884a9b948
--- /dev/null
+++ b/po/zh_TW.po
@@ -0,0 +1,4177 @@
+# Traditional Chinese translation for mana
+# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
+# This file is distributed under the same license as the mana package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
+# SECOND AUTHOR <NETWAREBOSS>,2009
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mana\n"
+"Report-Msgid-Bugs-To: dev@manasource.org\n"
+"POT-Creation-Date: 2010-03-05 21:52+0100\n"
+"PO-Revision-Date: 2010-01-23 17:23+0000\n"
+"Last-Translator: Peierh <Unknown>\n"
+"Language-Team: Traditional Chinese <themanaworld-devel@lists.sourceforge."
+"net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Launchpad-Export-Date: 2010-03-05 19:28+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+"X-Poedit-Country: China\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: src/client.cpp:553 src/gui/setup.cpp:43 src/gui/windowmenu.cpp:62
+msgid "Setup"
+msgstr "設定"
+
+#: src/client.cpp:623
+#, fuzzy
+msgid "Connecting to server"
+msgstr "正在連接到地圖伺服器..."
+
+#: src/client.cpp:650
+#, fuzzy
+msgid "Logging in"
+msgstr "登入"
+
+#: src/client.cpp:683
+msgid "Entering game world"
+msgstr ""
+
+#: src/client.cpp:739
+#, fuzzy
+msgid "Requesting characters"
+msgstr "選擇角色"
+
+#: src/client.cpp:768
+#, fuzzy
+msgid "Connecting to the game server"
+msgstr "正在連接到地圖伺服器..."
+
+#: src/client.cpp:799 src/client.cpp:806 src/client.cpp:940
+#: src/gui/changeemaildialog.cpp:156 src/gui/changepassworddialog.cpp:149
+#: src/gui/charcreatedialog.cpp:177 src/gui/register.cpp:218
+#: src/gui/serverdialog.cpp:261 src/gui/unregisterdialog.cpp:133
+#: src/net/ea/charserverhandler.cpp:135 src/net/ea/charserverhandler.cpp:152
+#: src/net/manaserv/charhandler.cpp:161 src/net/manaserv/charhandler.cpp:204
+msgid "Error"
+msgstr "錯誤"
+
+#: src/client.cpp:815
+msgid "Requesting registration details"
+msgstr ""
+
+#: src/client.cpp:842
+#, fuzzy
+msgid "Password Change"
+msgstr "密碼:"
+
+#: src/client.cpp:843
+msgid "Password changed successfully!"
+msgstr ""
+
+#: src/client.cpp:862
+#, fuzzy
+msgid "Email Change"
+msgstr "更改"
+
+#: src/client.cpp:863
+#, fuzzy
+msgid "Email changed successfully!"
+msgstr "成功提升會員."
+
+#: src/client.cpp:883
+#, fuzzy
+msgid "Unregister Successful"
+msgstr "取消註冊"
+
+#: src/client.cpp:884
+msgid "Farewell, come back any time..."
+msgstr ""
+
+#: src/client.cpp:1007 src/client.cpp:1030
+#, c-format
+msgid "%s doesn't exist and can't be created! Exiting."
+msgstr ""
+
+#: src/client.cpp:1119
+#, fuzzy, c-format
+msgid "Invalid update host: %s"
+msgstr "無效的更新主機: "
+
+#: src/client.cpp:1153 src/client.cpp:1159
+msgid "Error creating updates directory!"
+msgstr "建立更新目錄失敗!"
+
+#: src/commandhandler.cpp:127 src/commandhandler.cpp:308
+msgid "Unknown command."
+msgstr "不明指令"
+
+#: src/commandhandler.cpp:156
+msgid "-- Help --"
+msgstr "-- 說明 --"
+
+#: src/commandhandler.cpp:157
+msgid "/help > Display this help"
+msgstr "/help >顯示指令說明"
+
+#: src/commandhandler.cpp:159
+msgid "/where > Display map name"
+msgstr "/where > 顯示地圖名稱"
+
+#: src/commandhandler.cpp:160
+msgid "/who > Display number of online users"
+msgstr "/who > 顯示線上使用者的數量"
+
+#: src/commandhandler.cpp:161
+msgid "/me > Tell something about yourself"
+msgstr "/me > 顯示關於自己的資訊"
+
+#: src/commandhandler.cpp:163
+msgid "/clear > Clears this window"
+msgstr "/clear > 清除這個視窗"
+
+#: src/commandhandler.cpp:165
+msgid "/msg > Send a private message to a user"
+msgstr "/msg > 傳送私人訊息給某使用者"
+
+#: src/commandhandler.cpp:166
+msgid "/whisper > Alias of msg"
+msgstr "/whisper > 效果同 msg"
+
+#: src/commandhandler.cpp:167
+msgid "/w > Alias of msg"
+msgstr "/w > 效果同 msg"
+
+#: src/commandhandler.cpp:168
+msgid "/query > Makes a tab for private messages with another user"
+msgstr "/query > 建立與另一個使用者的私人訊息分頁"
+
+#: src/commandhandler.cpp:169
+msgid "/q > Alias of query"
+msgstr "/q > 效果同 query"
+
+#: src/commandhandler.cpp:171
+msgid "/ignore > ignore a player"
+msgstr ""
+
+#: src/commandhandler.cpp:172
+msgid "/unignore > stop ignoring a player"
+msgstr ""
+
+#: src/commandhandler.cpp:174
+msgid "/list > Display all public channels"
+msgstr "/list > 顯示所有公開頻道"
+
+#: src/commandhandler.cpp:175
+msgid "/join > Join or create a channel"
+msgstr "/join > 加入或建立頻道"
+
+#: src/commandhandler.cpp:177
+#, fuzzy
+msgid "/createparty > Create a new party"
+msgstr "/create > 建立新的隊伍"
+
+#: src/commandhandler.cpp:178
+msgid "/party > Invite a user to party"
+msgstr "/party > 邀請使用者組隊"
+
+#: src/commandhandler.cpp:180
+msgid "/record > Start recording the chat to an external file"
+msgstr "/record > 開始紀錄對話內容到外部檔案"
+
+#: src/commandhandler.cpp:181
+msgid "/toggle > Determine whether <return> toggles the chat log"
+msgstr "/toggle > 是否切換回聊天視窗"
+
+#: src/commandhandler.cpp:182
+msgid "/present > Get list of players present (sent to chat log, if logging)"
+msgstr "/present > 取得上線玩家的清單(如果開啟記錄,傳送到聊天紀錄)"
+
+#: src/commandhandler.cpp:184
+msgid "/announce > Global announcement (GM only)"
+msgstr "/announce > 全域廣播 (GM 專用)"
+
+#: src/commandhandler.cpp:188
+msgid "For more information, type /help <command>."
+msgstr "查看更多資訊, 輸入 /help <指令>."
+
+#: src/commandhandler.cpp:192
+msgid "Command: /help"
+msgstr "指令: /help"
+
+#: src/commandhandler.cpp:193
+msgid "This command displays a list of all commands available."
+msgstr "該指令可顯示所有可用指令。"
+
+#: src/commandhandler.cpp:194
+msgid "Command: /help <command>"
+msgstr "指令: /help <指令>"
+
+#: src/commandhandler.cpp:195
+msgid "This command displays help on <command>."
+msgstr "該指令會顯示<指令>的幫助訊息"
+
+#: src/commandhandler.cpp:203
+msgid "Command: /announce <msg>"
+msgstr "指令: /announce <信息>"
+
+#: src/commandhandler.cpp:204
+msgid "*** only available to a GM ***"
+msgstr "*** 只有GM可用 ***"
+
+#: src/commandhandler.cpp:205
+msgid "This command sends the message <msg> to all players currently online."
+msgstr "該指令會發送<信息>給所有線上用戶。"
+
+#: src/commandhandler.cpp:210
+msgid "Command: /clear"
+msgstr "指令: /clear"
+
+#: src/commandhandler.cpp:211
+msgid "This command clears the chat log of previous chat."
+msgstr "該指令可以清除聊天紀錄。"
+
+#: src/commandhandler.cpp:215
+#, fuzzy
+msgid "Command: /ignore <player>"
+msgstr "/item <政策>"
+
+#: src/commandhandler.cpp:216
+#, fuzzy
+msgid "This command ignores the given player regardless of current relations."
+msgstr "這調指令可顯示目前線上人數。"
+
+#: src/commandhandler.cpp:221
+msgid "Command: /join <channel>"
+msgstr "指令: /join <頻道名稱>"
+
+#: src/commandhandler.cpp:222
+msgid "This command makes you enter <channel>."
+msgstr "這個指令可以讓你輸入 <頻道名稱>."
+
+#: src/commandhandler.cpp:223
+msgid "If <channel> doesn't exist, it's created."
+msgstr "假如 <頻道名稱> 不存在,那就建立."
+
+#: src/commandhandler.cpp:227
+msgid "Command: /list"
+msgstr "指令: /list"
+
+#: src/commandhandler.cpp:228
+msgid "This command shows a list of all channels."
+msgstr "這個指令會顯示所有頻道的清單。"
+
+#: src/commandhandler.cpp:232
+msgid "Command: /me <message>"
+msgstr "指令: /me <message>"
+
+#: src/commandhandler.cpp:233
+msgid "This command tell others you are (doing) <msg>."
+msgstr "這個指令會告訴其他人您正在做 <msg> 的事。"
+
+#: src/commandhandler.cpp:237
+msgid "Command: /msg <nick> <message>"
+msgstr "指令: /msg <nick> <message>"
+
+#: src/commandhandler.cpp:238
+msgid "Command: /whisper <nick> <message>"
+msgstr "指令: /whisper <nick> <message>"
+
+#: src/commandhandler.cpp:239
+msgid "Command: /w <nick> <message>"
+msgstr "指令: /w <nick> <message>"
+
+#: src/commandhandler.cpp:240
+msgid "This command sends the text <message> to <nick>."
+msgstr "這個指令會傳送 <message> 的文字給 <nick>。"
+
+#: src/commandhandler.cpp:241 src/commandhandler.cpp:260
+#: src/gui/widgets/channeltab.cpp:82 src/gui/widgets/channeltab.cpp:91
+#: src/net/ea/gui/guildtab.cpp:75 src/net/ea/gui/partytab.cpp:75
+msgid "If the <nick> has spaces in it, enclose it in double quotes (\")."
+msgstr "如果<暱稱>之間有空格,用雙引號(\")括起來。"
+
+#: src/commandhandler.cpp:246
+msgid "Command: /query <nick>"
+msgstr "指令: /query <nick>"
+
+#: src/commandhandler.cpp:247
+msgid "Command: /q <nick>"
+msgstr "指令: /q <nick>"
+
+#: src/commandhandler.cpp:248
+msgid "This command tries to make a tab for whispers betweenyou and <nick>."
+msgstr "這個指令會嘗試建立您和 <nick> 之間的悄悄話分頁。"
+
+#: src/commandhandler.cpp:253
+#, fuzzy
+msgid "Command: /createparty <name>"
+msgstr "指令: /create <隊伍名稱>"
+
+#: src/commandhandler.cpp:254
+#, fuzzy
+msgid "This command creates a new party called <name>."
+msgstr "這些指令會建立叫做 <隊伍名稱> 的新隊伍。"
+
+#: src/commandhandler.cpp:258
+msgid "Command: /party <nick>"
+msgstr "指令: /party <nick>"
+
+#: src/commandhandler.cpp:259 src/net/ea/gui/partytab.cpp:74
+msgid "This command invites <nick> to party with you."
+msgstr "這個指令會邀請 <nick> 跟您組隊。"
+
+#: src/commandhandler.cpp:265
+msgid "Command: /present"
+msgstr "指令: /present"
+
+#: src/commandhandler.cpp:266
+msgid ""
+"This command gets a list of players within hearing and sends it to either "
+"the record log if recording, or the chat log otherwise."
+msgstr ""
+"該指令顯示玩家有聽到並傳送到任何日誌記錄,如果記錄,聊天記錄或其他方式。"
+
+#: src/commandhandler.cpp:272
+msgid "Command: /record <filename>"
+msgstr "指令: /record <filename>"
+
+#: src/commandhandler.cpp:273
+msgid "This command starts recording the chat log to the file <filename>."
+msgstr "這個指令會開始將聊天紀錄錄製為檔案 <filename>。"
+
+#: src/commandhandler.cpp:275
+msgid "Command: /record"
+msgstr "指令: /record"
+
+#: src/commandhandler.cpp:276
+msgid "This command finishes a recording session."
+msgstr "這個指令會結束錄製的作業階段。"
+
+#: src/commandhandler.cpp:280
+msgid "Command: /toggle <state>"
+msgstr "指令: /toggle <state>"
+
+#: src/commandhandler.cpp:281
+msgid ""
+"This command sets whether the return key should toggle the chat log, or "
+"whether the chat log turns off automatically."
+msgstr "這指令用來設定\"enter\"鍵是否切換聊天記錄,或者自動關閉記錄"
+
+#: src/commandhandler.cpp:283
+msgid ""
+"<state> can be one of \"1\", \"yes\", \"true\" to turn the toggle on, or \"0"
+"\", \"no\", \"false\" to turn the toggle off."
+msgstr ""
+"可以是 \"1\"、\"yes\"、\"true\" 其中之一來代表切換為開,或是 \"0\"、\"no\"、"
+"\"false\" 來代表切換為關閉."
+
+#: src/commandhandler.cpp:286
+msgid "Command: /toggle"
+msgstr "指令: /toggle"
+
+#: src/commandhandler.cpp:287
+msgid "This command displays the return toggle status."
+msgstr "這個指令顯示輸入切換狀態"
+
+#: src/commandhandler.cpp:291 src/gui/widgets/whispertab.cpp:93
+#, fuzzy
+msgid "Command: /unignore <player>"
+msgstr "/item <政策>"
+
+#: src/commandhandler.cpp:292
+msgid "This command stops ignoring the given player if they are being ignored"
+msgstr ""
+
+#: src/commandhandler.cpp:297
+msgid "Command: /where"
+msgstr "指令: /where"
+
+#: src/commandhandler.cpp:298
+msgid "This command displays the name of the current map."
+msgstr "這個指令顯示目前地圖名。"
+
+#: src/commandhandler.cpp:302
+msgid "Command: /who"
+msgstr "指令: /who"
+
+#: src/commandhandler.cpp:303
+msgid "This command displays the number of players currently online."
+msgstr "這調指令可顯示目前線上人數。"
+
+#: src/commandhandler.cpp:309
+msgid "Type /help for a list of commands."
+msgstr "輸入 /help 獲取指令列表。"
+
+#: src/commandhandler.cpp:375
+msgid "Cannot send empty whispers!"
+msgstr "傳送密語失敗"
+
+#: src/commandhandler.cpp:383
+#, c-format
+msgid ""
+"Cannot create a whisper tab for nick \"%s\"! It either already exists, or is "
+"you."
+msgstr "不能以名稱 \"%s\" 創建一個密語標籤! 該名稱已存在或對方是你."
+
+#: src/commandhandler.cpp:397
+#, c-format
+msgid "Requesting to join channel %s."
+msgstr "要求參加頻道 %s"
+
+#: src/commandhandler.cpp:410 src/net/ea/gui/partytab.cpp:109
+msgid "Party name is missing."
+msgstr "漏掉隊伍名稱。"
+
+#: src/commandhandler.cpp:423 src/commandhandler.cpp:471
+#: src/commandhandler.cpp:493
+msgid "Please specify a name."
+msgstr ""
+
+#: src/commandhandler.cpp:441
+msgid "Return toggles chat."
+msgstr "\"ENTER\"切換聊天"
+
+#: src/commandhandler.cpp:441
+msgid "Message closes chat."
+msgstr "關閉密語"
+
+#: src/commandhandler.cpp:450
+msgid "Return now toggles chat."
+msgstr "\"ENTER\"切換聊天"
+
+#: src/commandhandler.cpp:454
+msgid "Message now closes chat."
+msgstr "切換聊天"
+
+#: src/commandhandler.cpp:477
+msgid "Player already ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:484
+#, fuzzy
+msgid "Player successfully ignored!"
+msgstr "隊伍已成功的建立。"
+
+#: src/commandhandler.cpp:486
+#, fuzzy
+msgid "Player could not be ignored!"
+msgstr "該玩家拒絕你的密語"
+
+#: src/commandhandler.cpp:501
+msgid "Player wasn't ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:506
+msgid "Player no longer ignored!"
+msgstr ""
+
+#: src/commandhandler.cpp:508
+#, fuzzy
+msgid "Player could not be unignored!"
+msgstr "該玩家拒絕你的密語"
+
+#: src/commandhandler.h:31
+#, c-format
+msgid "Options to /%s are \"yes\", \"no\", \"true\", \"false\", \"1\", \"0\"."
+msgstr "/%s 的選項可以是 \"yes\"、\"no\"、\"true\"、\"false\"、\"1\"、\"0\"。"
+
+#: src/game.cpp:172
+msgid "General"
+msgstr "一般"
+
+#: src/game.cpp:326
+#, fuzzy
+msgid "Screenshot saved as "
+msgstr "抓圖存到 ~/"
+
+#: src/game.cpp:331
+msgid "Saving screenshot failed!"
+msgstr "儲存抓圖失敗!"
+
+#: src/game.cpp:355
+#, fuzzy
+msgid "The connection to the server was lost."
+msgstr "已中斷連線到伺服器,程式將要離開"
+
+#: src/game.cpp:360
+msgid "Network Error"
+msgstr "網路錯誤"
+
+#: src/game.cpp:705
+msgid "Ignoring incoming trade requests"
+msgstr "忽略收到的交易要求"
+
+#: src/game.cpp:712
+msgid "Accepting incoming trade requests"
+msgstr "接受收到的交易要求"
+
+#: src/game.cpp:946
+#, fuzzy
+msgid "Could Not Load Map"
+msgstr "無法載入地圖"
+
+#: src/game.cpp:947
+#, c-format
+msgid "Error while loading %s"
+msgstr "載入 %s 時發生錯誤"
+
+#: src/gui/beingpopup.cpp:75
+#, fuzzy, c-format
+msgid "Party: %s"
+msgstr "隊伍(%s)"
+
+#: src/gui/buy.cpp:49 src/gui/buy.cpp:78 src/gui/buysell.cpp:47
+msgid "Buy"
+msgstr "購買"
+
+#: src/gui/buy.cpp:69 src/gui/buy.cpp:256 src/gui/sell.cpp:71
+#: src/gui/sell.cpp:276
+#, c-format
+msgid "Price: %s / Total: %s"
+msgstr "價格: %s / 總共: %s"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:74 src/gui/itemamount.cpp:99 src/gui/npcdialog.cpp:100
+#: src/gui/sell.cpp:74 src/gui/statuswindow.cpp:479
+msgid "+"
+msgstr "增加"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+#. You may change this symbol if your language uses another.
+#: src/gui/buy.cpp:77 src/gui/itemamount.cpp:98 src/gui/npcdialog.cpp:101
+#: src/gui/sell.cpp:75 src/gui/statuswindow.cpp:491
+msgid "-"
+msgstr "減少"
+
+#: src/gui/buy.cpp:79 src/gui/quitdialog.cpp:40 src/gui/quitdialog.cpp:42
+#: src/gui/quitdialog.cpp:43 src/gui/sell.cpp:77 src/gui/serverdialog.cpp:182
+#: src/keyboardconfig.cpp:103
+msgid "Quit"
+msgstr "離開"
+
+#: src/gui/buy.cpp:80 src/gui/sell.cpp:78 src/gui/statuswindow.cpp:408
+#: src/gui/statuswindow.cpp:478 src/gui/statuswindow.cpp:512
+msgid "Max"
+msgstr "最大"
+
+#: src/gui/buysell.cpp:38
+msgid "Shop"
+msgstr "商店"
+
+#: src/gui/buysell.cpp:47 src/gui/sell.cpp:49 src/gui/sell.cpp:76
+msgid "Sell"
+msgstr "出售"
+
+#: src/gui/buysell.cpp:47 src/gui/changeemaildialog.cpp:55
+#: src/gui/changepassworddialog.cpp:58 src/gui/charcreatedialog.cpp:79
+#: src/gui/connectiondialog.cpp:44 src/gui/itemamount.cpp:101
+#: src/gui/npcpostdialog.cpp:57 src/gui/popupmenu.cpp:178
+#: src/gui/popupmenu.cpp:197 src/gui/popupmenu.cpp:402
+#: src/gui/quitdialog.cpp:47 src/gui/register.cpp:74 src/gui/setup.cpp:51
+#: src/gui/socialwindow.cpp:242 src/gui/textdialog.cpp:39
+#: src/gui/unregisterdialog.cpp:56 src/gui/updatewindow.cpp:144
+msgid "Cancel"
+msgstr "取消"
+
+#: src/gui/changeemaildialog.cpp:45 src/gui/changeemaildialog.cpp:54
+msgid "Change Email Address"
+msgstr "變更郵件地址"
+
+#: src/gui/changeemaildialog.cpp:49 src/gui/changepassworddialog.cpp:52
+#, c-format
+msgid "Account: %s"
+msgstr "帳號: %s"
+
+#: src/gui/changeemaildialog.cpp:51
+#, fuzzy
+msgid "Type new email address twice:"
+msgstr "輸入新的電子郵件地址兩次:"
+
+#: src/gui/changeemaildialog.cpp:127
+#, fuzzy, c-format
+msgid "The new email address needs to be at least %d characters long."
+msgstr "用戶名稱至少需要%d個字元。"
+
+#: src/gui/changeemaildialog.cpp:134
+#, fuzzy, c-format
+msgid "The new email address needs to be less than %d characters long."
+msgstr "用戶名稱不能少於%d個字元"
+
+#: src/gui/changeemaildialog.cpp:141
+#, fuzzy
+msgid "The email address entries mismatch."
+msgstr "電子郵件已經被註冊"
+
+#: src/gui/changepassworddialog.cpp:47 src/gui/changepassworddialog.cpp:56
+#: src/gui/charselectdialog.cpp:128
+msgid "Change Password"
+msgstr "變更密碼"
+
+#: src/gui/changepassworddialog.cpp:61 src/gui/login.cpp:53
+#: src/gui/register.cpp:68 src/gui/unregisterdialog.cpp:53
+msgid "Password:"
+msgstr "密碼:"
+
+#: src/gui/changepassworddialog.cpp:63
+#, fuzzy
+msgid "Type new password twice:"
+msgstr "輸入新密碼兩次:"
+
+#: src/gui/changepassworddialog.cpp:110
+msgid "Enter the old password first."
+msgstr ""
+
+#: src/gui/changepassworddialog.cpp:116
+#, fuzzy, c-format
+msgid "The new password needs to be at least %d characters long."
+msgstr "密碼至少需要%d個字元"
+
+#: src/gui/changepassworddialog.cpp:123
+#, fuzzy, c-format
+msgid "The new password needs to be less than %d characters long."
+msgstr "密碼不能少於%d個字元。"
+
+#: src/gui/changepassworddialog.cpp:130
+msgid "The new password entries mismatch."
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:53
+msgid "Create Character"
+msgstr "新增角色"
+
+#: src/gui/charcreatedialog.cpp:67 src/gui/login.cpp:52
+#: src/gui/register.cpp:67
+msgid "Name:"
+msgstr "名字:"
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'next'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:70 src/gui/charcreatedialog.cpp:75
+#: src/gui/outfitwindow.cpp:67
+msgid ">"
+msgstr ""
+
+#. TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+#. You may change this symbol if your language uses another.
+#: src/gui/charcreatedialog.cpp:73 src/gui/charcreatedialog.cpp:76
+#: src/gui/outfitwindow.cpp:66
+msgid "<"
+msgstr ""
+
+#: src/gui/charcreatedialog.cpp:74
+#, fuzzy
+msgid "Hair color:"
+msgstr "髮色:"
+
+#: src/gui/charcreatedialog.cpp:77
+#, fuzzy
+msgid "Hair style:"
+msgstr "髮型:"
+
+#: src/gui/charcreatedialog.cpp:78 src/gui/charselectdialog.cpp:397
+#: src/gui/socialwindow.cpp:296
+msgid "Create"
+msgstr "創造"
+
+#: src/gui/charcreatedialog.cpp:80 src/gui/register.cpp:90
+msgid "Male"
+msgstr "男生"
+
+#: src/gui/charcreatedialog.cpp:81 src/gui/register.cpp:91
+msgid "Female"
+msgstr "女生"
+
+#: src/gui/charcreatedialog.cpp:99 src/gui/charcreatedialog.cpp:251
+#, c-format
+msgid "Please distribute %d points"
+msgstr "請分配%d點數"
+
+#: src/gui/charcreatedialog.cpp:178
+msgid "Your name needs to be at least 4 characters."
+msgstr "你的名字至少需要4個字元"
+
+#: src/gui/charcreatedialog.cpp:242
+msgid "Character stats OK"
+msgstr "角色狀態確定"
+
+#: src/gui/charcreatedialog.cpp:256
+#, c-format
+msgid "Please remove %d points"
+msgstr "請移除%d點數"
+
+#: src/gui/charselectdialog.cpp:69
+msgid "Confirm Character Delete"
+msgstr "確認刪除角色"
+
+#: src/gui/charselectdialog.cpp:70
+msgid "Are you sure you want to delete this character?"
+msgstr "你確定想刪除這個角色?"
+
+#: src/gui/charselectdialog.cpp:117
+msgid "Account and Character Management"
+msgstr "帳號與角色管理"
+
+#: src/gui/charselectdialog.cpp:127
+msgid "Switch Login"
+msgstr ""
+
+#: src/gui/charselectdialog.cpp:141 src/gui/unregisterdialog.cpp:47
+#: src/gui/unregisterdialog.cpp:55
+msgid "Unregister"
+msgstr "取消註冊"
+
+#: src/gui/charselectdialog.cpp:150
+#, fuzzy
+msgid "Change Email"
+msgstr "變更郵件地址"
+
+#: src/gui/charselectdialog.cpp:335 src/gui/serverdialog.cpp:185
+#: src/gui/setup_players.cpp:230
+msgid "Delete"
+msgstr "刪除"
+
+#: src/gui/charselectdialog.cpp:387
+#, fuzzy
+msgid "Choose"
+msgstr "關閉"
+
+#: src/gui/charselectdialog.cpp:399 src/gui/charselectdialog.cpp:400
+msgid "(empty)"
+msgstr ""
+
+#: src/gui/chat.cpp:77 src/gui/palette.cpp:96
+msgid "Chat"
+msgstr "聊天"
+
+#: src/gui/chat.cpp:287
+#, fuzzy, c-format
+msgid "Present: %s; %d players are present."
+msgstr "%d 位玩家的清單"
+
+#: src/gui/chat.cpp:305
+msgid "Attendance written to record log."
+msgstr "將上線訊息寫入錄製紀錄。"
+
+#: src/gui/chat.cpp:469
+#, c-format
+msgid "Whispering to %s: %s"
+msgstr "對%s竊竊私語:%s"
+
+#: src/gui/confirmdialog.cpp:42
+msgid "Yes"
+msgstr "是"
+
+#: src/gui/confirmdialog.cpp:43
+msgid "No"
+msgstr "否"
+
+#: src/gui/debugwindow.cpp:43
+msgid "Debug"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:56
+#, c-format
+msgid "%d FPS (OpenGL)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:61 src/gui/debugwindow.cpp:64
+#, c-format
+msgid "%d FPS"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:65 src/gui/debugwindow.cpp:104
+#, fuzzy, c-format
+msgid "Music: %s"
+msgstr "主題: %s"
+
+#: src/gui/debugwindow.cpp:66 src/gui/debugwindow.cpp:108
+#, fuzzy, c-format
+msgid "Map: %s"
+msgstr "名字:%s"
+
+#: src/gui/debugwindow.cpp:67 src/gui/debugwindow.cpp:106
+#, fuzzy, c-format
+msgid "Minimap: %s"
+msgstr "小地圖"
+
+#: src/gui/debugwindow.cpp:68 src/gui/debugwindow.cpp:99
+#, c-format
+msgid "Cursor: (%d, %d)"
+msgstr ""
+
+#: src/gui/debugwindow.cpp:69 src/gui/debugwindow.cpp:111
+#, fuzzy, c-format
+msgid "Particle count: %d"
+msgstr "粒子效果"
+
+#: src/gui/debugwindow.cpp:116
+#, fuzzy, c-format
+msgid "Particle detail: %s"
+msgstr "紋理細節"
+
+#: src/gui/debugwindow.cpp:121
+#, fuzzy, c-format
+msgid "Ambient FX: %s"
+msgstr "環境效果"
+
+#: src/gui/equipmentwindow.cpp:69 src/gui/windowmenu.cpp:56
+msgid "Equipment"
+msgstr "裝備"
+
+#: src/gui/equipmentwindow.cpp:87 src/gui/inventorywindow.cpp:77
+#: src/gui/inventorywindow.cpp:79 src/gui/inventorywindow.cpp:298
+#: src/gui/popupmenu.cpp:372
+msgid "Unequip"
+msgstr "卸下裝備"
+
+#: src/gui/help.cpp:36
+msgid "Help"
+msgstr "說明"
+
+#: src/gui/help.cpp:50 src/gui/npcdialog.cpp:46 src/gui/storagewindow.cpp:73
+msgid "Close"
+msgstr "關閉"
+
+#: src/gui/inventorywindow.cpp:56 src/gui/windowmenu.cpp:57
+msgid "Inventory"
+msgstr "物品攔"
+
+#: src/gui/inventorywindow.cpp:72 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:300 src/gui/popupmenu.cpp:374
+msgid "Equip"
+msgstr "裝備"
+
+#: src/gui/inventorywindow.cpp:73 src/gui/inventorywindow.cpp:74
+#: src/gui/inventorywindow.cpp:304 src/gui/popupmenu.cpp:377
+msgid "Use"
+msgstr "使用"
+
+#: src/gui/inventorywindow.cpp:83 src/gui/inventorywindow.cpp:308
+#: src/gui/popupmenu.cpp:380
+#, fuzzy
+msgid "Drop..."
+msgstr "丟棄"
+
+#: src/gui/inventorywindow.cpp:84 src/gui/popupmenu.cpp:386
+msgid "Split"
+msgstr "分開"
+
+#: src/gui/inventorywindow.cpp:85 src/gui/outfitwindow.cpp:51
+msgid "Outfits"
+msgstr ""
+
+#: src/gui/inventorywindow.cpp:96 src/gui/storagewindow.cpp:83
+msgid "Slots:"
+msgstr "欄位:"
+
+#: src/gui/inventorywindow.cpp:97
+msgid "Weight:"
+msgstr "重量:"
+
+#: src/gui/inventorywindow.cpp:310 src/gui/popupmenu.cpp:382
+msgid "Drop"
+msgstr "丟棄"
+
+#: src/gui/itemamount.cpp:100 src/gui/okdialog.cpp:42
+#: src/gui/quitdialog.cpp:46 src/gui/textdialog.cpp:38 src/gui/trade.cpp:73
+#: src/gui/trade.cpp:75
+msgid "OK"
+msgstr "確定"
+
+#: src/gui/itemamount.cpp:102
+msgid "All"
+msgstr "全部"
+
+#: src/gui/itemamount.cpp:128
+msgid "Select amount of items to trade."
+msgstr "請選擇交易的物品數量"
+
+#: src/gui/itemamount.cpp:131
+msgid "Select amount of items to drop."
+msgstr "請選擇丟棄的物品數量"
+
+#: src/gui/itemamount.cpp:134
+msgid "Select amount of items to store."
+msgstr "選擇要儲存的物品數量。"
+
+#: src/gui/itemamount.cpp:137
+msgid "Select amount of items to retrieve."
+msgstr "選擇要取回的物品數量。"
+
+#: src/gui/itemamount.cpp:140
+msgid "Select amount of items to split."
+msgstr "請選擇你要分離的物品數量"
+
+#: src/gui/itempopup.cpp:92
+#, fuzzy, c-format
+msgid "Weight: %s"
+msgstr "重量: "
+
+#: src/gui/login.cpp:49 src/gui/login.cpp:61
+msgid "Login"
+msgstr "登入"
+
+#: src/gui/login.cpp:58
+#, fuzzy
+msgid "Remember username"
+msgstr "保存用戶名"
+
+#: src/gui/login.cpp:59 src/gui/register.cpp:58 src/gui/register.cpp:73
+msgid "Register"
+msgstr "註冊"
+
+#: src/gui/login.cpp:60
+#, fuzzy
+msgid "Change Server"
+msgstr "伺服器"
+
+#: src/gui/minimap.cpp:46 src/gui/minimap.cpp:87
+msgid "Map"
+msgstr "地圖"
+
+#: src/gui/npcdialog.cpp:44
+msgid "Waiting for server"
+msgstr "等待伺服器中"
+
+#: src/gui/npcdialog.cpp:45
+msgid "Next"
+msgstr "下一個"
+
+#: src/gui/npcdialog.cpp:47
+msgid "Submit"
+msgstr "確認"
+
+#: src/gui/npcdialog.cpp:52 src/gui/npcpostdialog.cpp:41
+msgid "NPC"
+msgstr "NPC"
+
+#: src/gui/npcdialog.cpp:110
+msgid "Reset"
+msgstr "重設"
+
+#. TRANSLATORS: Please leave the \n sequences intact.
+#: src/gui/npcdialog.cpp:171
+#, fuzzy
+msgid ""
+"\n"
+"> Next\n"
+msgstr "下一個"
+
+#: src/gui/npcpostdialog.cpp:47
+msgid "To:"
+msgstr "存至:"
+
+#: src/gui/npcpostdialog.cpp:54
+msgid "Send"
+msgstr "傳送"
+
+#: src/gui/npcpostdialog.cpp:96
+msgid "Failed to send as sender or letter invalid."
+msgstr "無法傳送的發件人或信息無效。"
+
+#: src/gui/outfitwindow.cpp:68 src/gui/outfitwindow.cpp:141
+#: src/gui/outfitwindow.cpp:154
+#, fuzzy, c-format
+msgid "Outfit: %d"
+msgstr "體力: %d"
+
+#: src/gui/outfitwindow.cpp:70
+#, fuzzy
+msgid "Unequip first"
+msgstr "卸下裝備"
+
+#: src/gui/palette.cpp:81 src/gui/setup_video.cpp:143
+msgid "Text"
+msgstr "文字"
+
+#: src/gui/palette.cpp:82
+msgid "Text Shadow"
+msgstr "文字陰影"
+
+#: src/gui/palette.cpp:83
+msgid "Text Outline"
+msgstr "文字輪廓"
+
+#: src/gui/palette.cpp:84
+msgid "Progress Bar Labels"
+msgstr "進度列標籤"
+
+#: src/gui/palette.cpp:85
+msgid "Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:86
+msgid "Disabled Buttons"
+msgstr ""
+
+#: src/gui/palette.cpp:87
+msgid "Tabs"
+msgstr ""
+
+#: src/gui/palette.cpp:89
+msgid "Background"
+msgstr "背景"
+
+#: src/gui/palette.cpp:91
+msgid "Highlight"
+msgstr "突顯"
+
+#: src/gui/palette.cpp:92
+msgid "Tab Highlight"
+msgstr "分頁突顯"
+
+#: src/gui/palette.cpp:93
+#, fuzzy
+msgid "Item Too Expensive"
+msgstr "物品太貴"
+
+#: src/gui/palette.cpp:94
+#, fuzzy
+msgid "Item Is Equipped"
+msgstr "物品已裝備"
+
+#: src/gui/palette.cpp:97
+msgid "GM"
+msgstr "遊戲管理者"
+
+#: src/gui/palette.cpp:98
+msgid "Player"
+msgstr "玩家"
+
+#: src/gui/palette.cpp:99
+msgid "Whisper"
+msgstr "悄悄話"
+
+#: src/gui/palette.cpp:100
+msgid "Is"
+msgstr "是"
+
+#: src/gui/palette.cpp:101 src/net/ea/gui/partytab.cpp:43
+msgid "Party"
+msgstr "隊伍"
+
+#: src/gui/palette.cpp:102 src/net/ea/gui/guildtab.cpp:45
+msgid "Guild"
+msgstr "公會"
+
+#: src/gui/palette.cpp:103
+msgid "Server"
+msgstr "伺服器"
+
+#: src/gui/palette.cpp:104
+msgid "Logger"
+msgstr "記錄器"
+
+#: src/gui/palette.cpp:105
+msgid "Hyperlink"
+msgstr "超連結"
+
+#: src/gui/palette.cpp:107
+msgid "Being"
+msgstr "物件"
+
+#: src/gui/palette.cpp:108
+msgid "Other Players' Names"
+msgstr "其他使用者名字"
+
+#: src/gui/palette.cpp:109
+msgid "Own Name"
+msgstr "我的名字"
+
+#: src/gui/palette.cpp:110
+msgid "GM Names"
+msgstr "遊戲管理者名字"
+
+#: src/gui/palette.cpp:111
+msgid "NPCs"
+msgstr "電腦"
+
+#: src/gui/palette.cpp:112
+msgid "Monsters"
+msgstr "怪物"
+
+#: src/gui/palette.cpp:114
+msgid "Unknown Item Type"
+msgstr "不明物品類型"
+
+#: src/gui/palette.cpp:115
+msgid "Generics"
+msgstr "一般"
+
+#: src/gui/palette.cpp:116
+msgid "Hats"
+msgstr "帽子"
+
+#: src/gui/palette.cpp:117
+msgid "Usables"
+msgstr "可使用的"
+
+#: src/gui/palette.cpp:118
+msgid "Shirts"
+msgstr "內衣"
+
+#: src/gui/palette.cpp:119
+#, fuzzy
+msgid "One Handed Weapons"
+msgstr "單手武器"
+
+#: src/gui/palette.cpp:120
+msgid "Pants"
+msgstr "褲子"
+
+#: src/gui/palette.cpp:121
+msgid "Shoes"
+msgstr "鞋子"
+
+#: src/gui/palette.cpp:122
+#, fuzzy
+msgid "Two Handed Weapons"
+msgstr "單手武器"
+
+#: src/gui/palette.cpp:123
+msgid "Shields"
+msgstr "盾牌"
+
+#: src/gui/palette.cpp:124
+msgid "Rings"
+msgstr "戒指"
+
+#: src/gui/palette.cpp:125
+msgid "Necklaces"
+msgstr "腕甲"
+
+#: src/gui/palette.cpp:126
+msgid "Arms"
+msgstr "武器"
+
+#: src/gui/palette.cpp:127
+msgid "Ammo"
+msgstr "箭"
+
+#: src/gui/palette.cpp:129
+msgid "Particle Effects"
+msgstr "粒子效果"
+
+#: src/gui/palette.cpp:130
+msgid "Pickup Notification"
+msgstr "撿拾通知"
+
+#: src/gui/palette.cpp:131
+msgid "Exp Notification"
+msgstr "經驗值通知"
+
+#: src/gui/palette.cpp:133
+#, fuzzy
+msgid "Player Hits Monster"
+msgstr "玩家攻擊怪物"
+
+#: src/gui/palette.cpp:135
+#, fuzzy
+msgid "Monster Hits Player"
+msgstr "怪物攻擊玩家"
+
+#: src/gui/palette.cpp:136
+msgid "Critical Hit"
+msgstr "致命一擊"
+
+#: src/gui/palette.cpp:137
+msgid "Misses"
+msgstr "失誤"
+
+#: src/gui/palette.cpp:139
+msgid "HP Bar"
+msgstr "血量"
+
+#: src/gui/palette.cpp:140
+msgid "3/4 HP Bar"
+msgstr "3/4 血量"
+
+#: src/gui/palette.cpp:141
+msgid "1/2 HP Bar"
+msgstr "1/2 血量"
+
+#: src/gui/palette.cpp:142
+msgid "1/4 HP Bar"
+msgstr "1/4 血量"
+
+#: src/gui/popupmenu.cpp:84
+#, fuzzy, c-format
+msgid "Trade with %s..."
+msgstr "與 %s 交易."
+
+#: src/gui/popupmenu.cpp:88 src/gui/popupmenu.cpp:161
+#, fuzzy, c-format
+msgid "Attack %s"
+msgstr "攻擊 %+d"
+
+#: src/gui/popupmenu.cpp:92
+#, fuzzy, c-format
+msgid "Whisper %s"
+msgstr "悄悄話"
+
+#: src/gui/popupmenu.cpp:101
+#, fuzzy, c-format
+msgid "Befriend %s"
+msgstr "@@friend|與%s交朋友@@"
+
+#: src/gui/popupmenu.cpp:106
+#, fuzzy, c-format
+msgid "Disregard %s"
+msgstr "不理"
+
+#: src/gui/popupmenu.cpp:109
+#, fuzzy, c-format
+msgid "Ignore %s"
+msgstr "忽略"
+
+#: src/gui/popupmenu.cpp:115 src/gui/popupmenu.cpp:124
+#, c-format
+msgid "Unignore %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:118
+#, fuzzy, c-format
+msgid "Completely ignore %s"
+msgstr "@@ignore|完全忽視 %s@@"
+
+#: src/gui/popupmenu.cpp:130
+#, c-format
+msgid "Follow %s"
+msgstr ""
+
+#: src/gui/popupmenu.cpp:133
+#, fuzzy, c-format
+msgid "Invite %s to join your guild"
+msgstr "@@guild|邀請 %s 加入你的公會@@"
+
+#: src/gui/popupmenu.cpp:137
+#, fuzzy, c-format
+msgid "Invite %s to join your party"
+msgstr "@@party|邀請 %s 加入你的隊伍@@"
+
+#: src/gui/popupmenu.cpp:144
+#, fuzzy
+msgid "Kick player"
+msgstr "踢人失敗!"
+
+#: src/gui/popupmenu.cpp:153
+#, fuzzy, c-format
+msgid "Talk to %s"
+msgstr "@@對話|與 %s 對話@@"
+
+#: src/gui/popupmenu.cpp:166
+#, fuzzy
+msgid "Kick monster"
+msgstr "@@admin-kick|移除怪物@@"
+
+#: src/gui/popupmenu.cpp:174
+#, fuzzy
+msgid "Add name to chat"
+msgstr "@@name|增加聊天名單@@"
+
+#: src/gui/popupmenu.cpp:191
+#, fuzzy, c-format
+msgid "Pick up %s"
+msgstr "撿拾"
+
+#: src/gui/popupmenu.cpp:193 src/gui/popupmenu.cpp:400
+#, fuzzy
+msgid "Add to chat"
+msgstr "@@chat|加入聊天@@"
+
+#: src/gui/popupmenu.cpp:391 src/gui/storagewindow.cpp:70
+msgid "Store"
+msgstr "寄放"
+
+#: src/gui/popupmenu.cpp:398 src/gui/storagewindow.cpp:71
+msgid "Retrieve"
+msgstr "取回"
+
+#: src/gui/quitdialog.cpp:44
+msgid "Switch server"
+msgstr "交換伺服器"
+
+#: src/gui/quitdialog.cpp:45
+msgid "Switch character"
+msgstr "交換角色"
+
+#: src/gui/recorder.cpp:87
+msgid "Finishing recording."
+msgstr "結束紀錄"
+
+#: src/gui/recorder.cpp:91
+msgid "Not currently recording."
+msgstr "沒有目前的紀錄"
+
+#: src/gui/recorder.cpp:96
+msgid "Already recording."
+msgstr "已經錄製。"
+
+#: src/gui/recorder.cpp:104
+msgid "Starting to record..."
+msgstr "開始錄製..."
+
+#: src/gui/recorder.cpp:112
+msgid "Failed to start recording."
+msgstr "開始錄製失敗。"
+
+#: src/gui/recorder.h:38
+msgid "Recording..."
+msgstr "正在錄製..."
+
+#: src/gui/recorder.h:39
+msgid "Stop recording"
+msgstr "停止錄製"
+
+#: src/gui/register.cpp:69
+msgid "Confirm:"
+msgstr "確認:"
+
+#: src/gui/register.cpp:100
+msgid "Email:"
+msgstr "電子郵件"
+
+#: src/gui/register.cpp:166
+#, c-format
+msgid "The username needs to be at least %d characters long."
+msgstr "用戶名稱至少需要%d個字元。"
+
+#: src/gui/register.cpp:174
+#, c-format
+msgid "The username needs to be less than %d characters long."
+msgstr "用戶名稱不能少於%d個字元"
+
+#: src/gui/register.cpp:182 src/gui/unregisterdialog.cpp:117
+#, c-format
+msgid "The password needs to be at least %d characters long."
+msgstr "密碼至少需要%d個字元"
+
+#: src/gui/register.cpp:190 src/gui/unregisterdialog.cpp:124
+#, c-format
+msgid "The password needs to be less than %d characters long."
+msgstr "密碼不能少於%d個字元。"
+
+#: src/gui/register.cpp:197
+msgid "Passwords do not match."
+msgstr "密碼不一樣."
+
+#: src/gui/serverdialog.cpp:134
+#, fuzzy
+msgid "Choose Your Server"
+msgstr "選擇您的伺服器"
+
+#: src/gui/serverdialog.cpp:141 src/gui/widgets/chattab.cpp:139
+msgid "Server:"
+msgstr "伺服器:"
+
+#: src/gui/serverdialog.cpp:142
+msgid "Port:"
+msgstr "端口(port):"
+
+#: src/gui/serverdialog.cpp:143
+#, fuzzy
+msgid "Server type:"
+msgstr "伺服器:"
+
+#: src/gui/serverdialog.cpp:183
+#, fuzzy
+msgid "Connect"
+msgstr "連線中..."
+
+#: src/gui/serverdialog.cpp:184
+#, fuzzy
+msgid "Custom Server"
+msgstr "自訂滑鼠標"
+
+#: src/gui/serverdialog.cpp:262
+msgid "Please type both the address and the port of a server."
+msgstr "請輸入伺服氣得IP地址和Port"
+
+#: src/gui/serverdialog.cpp:411
+#, c-format
+msgid "Downloading server list...%2.2f%%"
+msgstr ""
+
+#: src/gui/serverdialog.cpp:417
+#, fuzzy
+msgid "Waiting for server..."
+msgstr "等待伺服器中"
+
+#: src/gui/serverdialog.cpp:421
+msgid "Preparing download"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:42
+msgid "Sound"
+msgstr "聲音"
+
+#: src/gui/setup_audio.cpp:43
+msgid "Download music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:47
+msgid "Audio"
+msgstr "音效"
+
+#: src/gui/setup_audio.cpp:50
+msgid "Sfx volume"
+msgstr "音效音量"
+
+#: src/gui/setup_audio.cpp:51
+msgid "Music volume"
+msgstr "音樂音量"
+
+#: src/gui/setup_audio.cpp:94
+#, fuzzy
+msgid "Notice"
+msgstr "沒有文字"
+
+#: src/gui/setup_audio.cpp:94
+msgid "You may have to restart your client if you want to download new music"
+msgstr ""
+
+#: src/gui/setup_audio.cpp:106
+msgid "Sound Engine"
+msgstr ""
+
+#: src/gui/setup_colors.cpp:44
+msgid "This is what the color looks like"
+msgstr "這是顏色看起來的樣子"
+
+#: src/gui/setup_colors.cpp:49
+msgid "Colors"
+msgstr "顏色"
+
+#: src/gui/setup_colors.cpp:70
+#, fuzzy
+msgid "Type:"
+msgstr "類型: "
+
+#: src/gui/setup_colors.cpp:81 src/gui/setup_colors.cpp:433
+msgid "Static"
+msgstr "狀態"
+
+#: src/gui/setup_colors.cpp:83 src/gui/setup_colors.cpp:84
+#: src/gui/setup_colors.cpp:434
+msgid "Pulse"
+msgstr "暫停"
+
+#: src/gui/setup_colors.cpp:85 src/gui/setup_colors.cpp:86
+#: src/gui/setup_colors.cpp:435
+msgid "Rainbow"
+msgstr "彩虹"
+
+#: src/gui/setup_colors.cpp:87 src/gui/setup_colors.cpp:88
+#: src/gui/setup_colors.cpp:435
+msgid "Spectrum"
+msgstr "光譜"
+
+#: src/gui/setup_colors.cpp:92
+#, fuzzy
+msgid "Delay:"
+msgstr "延遲: "
+
+#: src/gui/setup_colors.cpp:107
+#, fuzzy
+msgid "Red:"
+msgstr "紅: "
+
+#: src/gui/setup_colors.cpp:122
+#, fuzzy
+msgid "Green:"
+msgstr "綠: "
+
+#: src/gui/setup_colors.cpp:137
+#, fuzzy
+msgid "Blue:"
+msgstr "藍: "
+
+#: src/gui/setup.cpp:51
+msgid "Apply"
+msgstr "確定"
+
+#: src/gui/setup.cpp:51
+msgid "Reset Windows"
+msgstr "重置視窗"
+
+#: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78
+msgid "Press the button to start calibration"
+msgstr "按下按鈕開始矯正"
+
+#: src/gui/setup_joystick.cpp:38 src/gui/setup_joystick.cpp:76
+msgid "Calibrate"
+msgstr "矯正"
+
+#: src/gui/setup_joystick.cpp:39
+msgid "Enable joystick"
+msgstr "啟用搖桿"
+
+#: src/gui/setup_joystick.cpp:41
+msgid "Joystick"
+msgstr "搖桿"
+
+#: src/gui/setup_joystick.cpp:83
+msgid "Stop"
+msgstr "停止"
+
+#: src/gui/setup_joystick.cpp:84
+msgid "Rotate the stick"
+msgstr "旋轉手柄"
+
+#: src/gui/setup_keyboard.cpp:77
+msgid "Keyboard"
+msgstr "鍵盤"
+
+#: src/gui/setup_keyboard.cpp:86
+msgid "Assign"
+msgstr "分配"
+
+#: src/gui/setup_keyboard.cpp:90
+msgid "Default"
+msgstr "預設"
+
+#: src/gui/setup_keyboard.cpp:119
+msgid "Key Conflict(s) Detected."
+msgstr "檢測到按鍵衝突。"
+
+#: src/gui/setup_players.cpp:57
+msgid "Name"
+msgstr "名字"
+
+#: src/gui/setup_players.cpp:58
+msgid "Relation"
+msgstr "關係"
+
+#: src/gui/setup_players.cpp:63
+msgid "Neutral"
+msgstr "中立"
+
+#: src/gui/setup_players.cpp:64
+msgid "Friend"
+msgstr "好友"
+
+#: src/gui/setup_players.cpp:65
+msgid "Disregarded"
+msgstr "不理"
+
+#: src/gui/setup_players.cpp:66
+msgid "Ignored"
+msgstr "忽略"
+
+#: src/gui/setup_players.cpp:208 src/gui/setup_video.cpp:132
+msgid "???"
+msgstr "???"
+
+#: src/gui/setup_players.cpp:226
+msgid "Allow trading"
+msgstr "允許交易"
+
+#: src/gui/setup_players.cpp:228
+msgid "Allow whispers"
+msgstr "允許密語"
+
+#: src/gui/setup_players.cpp:232
+msgid "Put all whispers in tabs"
+msgstr "將所有的悄悄話放到分頁中"
+
+#: src/gui/setup_players.cpp:234
+#, fuzzy
+msgid "Show gender"
+msgstr "顯示名稱"
+
+#: src/gui/setup_players.cpp:236
+msgid "Players"
+msgstr "玩家"
+
+#: src/gui/setup_players.cpp:261
+msgid "When ignoring:"
+msgstr "當忽略時:"
+
+#: src/gui/setup_video.cpp:113
+msgid "Tiny"
+msgstr "小"
+
+#: src/gui/setup_video.cpp:114
+msgid "Small"
+msgstr "小型"
+
+#: src/gui/setup_video.cpp:115
+msgid "Medium"
+msgstr "中型"
+
+#: src/gui/setup_video.cpp:116
+msgid "Large"
+msgstr "大型"
+
+#: src/gui/setup_video.cpp:142
+msgid "No text"
+msgstr "沒有文字"
+
+#: src/gui/setup_video.cpp:144
+msgid "Bubbles, no names"
+msgstr "有聊天泡泡,沒名字"
+
+#: src/gui/setup_video.cpp:145
+msgid "Bubbles with names"
+msgstr "聊天泡泡加名字"
+
+#: src/gui/setup_video.cpp:157
+msgid "off"
+msgstr "關閉"
+
+#: src/gui/setup_video.cpp:158 src/gui/setup_video.cpp:171
+msgid "low"
+msgstr "低"
+
+#: src/gui/setup_video.cpp:159 src/gui/setup_video.cpp:173
+msgid "high"
+msgstr "高"
+
+#: src/gui/setup_video.cpp:172
+msgid "medium"
+msgstr "中"
+
+#: src/gui/setup_video.cpp:174
+msgid "max"
+msgstr "最大"
+
+#: src/gui/setup_video.cpp:196
+msgid "Full screen"
+msgstr "全螢幕"
+
+#: src/gui/setup_video.cpp:197
+msgid "OpenGL"
+msgstr "OpenGL"
+
+#: src/gui/setup_video.cpp:198
+msgid "Custom cursor"
+msgstr "自訂滑鼠標"
+
+#: src/gui/setup_video.cpp:200
+msgid "Visible names"
+msgstr "可見的名稱"
+
+#: src/gui/setup_video.cpp:202
+msgid "Particle effects"
+msgstr "粒子效果"
+
+#: src/gui/setup_video.cpp:204
+#, fuzzy
+msgid "Show own name"
+msgstr "顯示名稱"
+
+#: src/gui/setup_video.cpp:205
+msgid "Show pickup notification"
+msgstr "顯示撿拾通知"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:207
+msgid "in chat"
+msgstr "聊天中"
+
+#. TRANSLATORS: Refers to "Show own name"
+#: src/gui/setup_video.cpp:209
+msgid "as particle"
+msgstr "同粒子設定"
+
+#: src/gui/setup_video.cpp:214
+#, fuzzy
+msgid "FPS limit:"
+msgstr "FPS限制:"
+
+#: src/gui/setup_video.cpp:225
+msgid "Video"
+msgstr "顯示"
+
+#: src/gui/setup_video.cpp:227
+#, fuzzy
+msgid "Show monster damage"
+msgstr "顯示名稱"
+
+#: src/gui/setup_video.cpp:233
+msgid "Overhead text"
+msgstr "置頂文字"
+
+#: src/gui/setup_video.cpp:234
+msgid "Gui opacity"
+msgstr "Gui 透明度"
+
+#: src/gui/setup_video.cpp:235
+msgid "Ambient FX"
+msgstr "環境效果"
+
+#: src/gui/setup_video.cpp:236
+#, fuzzy
+msgid "Particle detail"
+msgstr "紋理細節"
+
+#: src/gui/setup_video.cpp:237
+msgid "Font size"
+msgstr "字型大小"
+
+#: src/gui/setup_video.cpp:251 src/gui/setup_video.cpp:454
+#: src/gui/setup_video.cpp:568
+#, fuzzy
+msgid "None"
+msgstr "否"
+
+#: src/gui/setup_video.cpp:381
+#, fuzzy
+msgid ""
+"Failed to switch to windowed mode and restoration of old mode also failed!"
+msgstr "模式和恢復舊模式也沒有!"
+
+#: src/gui/setup_video.cpp:387
+#, fuzzy
+msgid ""
+"Failed to switch to fullscreen mode and restoration of old mode also failed!"
+msgstr "模式和恢復舊模式也沒有!"
+
+#: src/gui/setup_video.cpp:398
+#, fuzzy
+msgid "Switching to Full Screen"
+msgstr "切換全螢幕"
+
+#: src/gui/setup_video.cpp:399
+msgid "Restart needed for changes to take effect."
+msgstr "請重新啟動"
+
+#: src/gui/setup_video.cpp:411
+#, fuzzy
+msgid "Changing to OpenGL"
+msgstr "切換為OpenGL"
+
+#: src/gui/setup_video.cpp:412
+msgid "Applying change to OpenGL requires restart."
+msgstr "確認切換OpenGL需要重新開始"
+
+#: src/gui/setup_video.cpp:486 src/gui/setup_video.cpp:491
+#, fuzzy
+msgid "Screen Resolution Changed"
+msgstr "螢幕解析度已變更"
+
+#: src/gui/setup_video.cpp:487 src/gui/setup_video.cpp:492
+msgid "Restart your client for the change to take effect."
+msgstr "請重新啟動您的客戶端讓變更生效。"
+
+#: src/gui/setup_video.cpp:489
+msgid "Some windows may be moved to fit the lowered resolution."
+msgstr ""
+
+#: src/gui/setup_video.cpp:522
+#, fuzzy
+msgid "Particle Effect Settings Changed."
+msgstr "粒子效果設定值已變更。"
+
+#: src/gui/setup_video.cpp:523
+msgid "Changes will take effect on map change."
+msgstr "變更會在地圖改變後生效。"
+
+#: src/gui/skilldialog.cpp:197 src/gui/windowmenu.cpp:58
+msgid "Skills"
+msgstr "技能"
+
+#: src/gui/skilldialog.cpp:208
+msgid "Up"
+msgstr "升級"
+
+#: src/gui/skilldialog.cpp:262
+#, fuzzy, c-format
+msgid "Skill points available: %d"
+msgstr "技能點數:%d"
+
+#: src/gui/skilldialog.cpp:314
+#, fuzzy, c-format
+msgid "Skill Set %d"
+msgstr "技能點數:%d"
+
+#: src/gui/skilldialog.cpp:323
+#, fuzzy, c-format
+msgid "Skill %d"
+msgstr "技能"
+
+#: src/gui/skilldialog.cpp:405
+#, fuzzy, c-format
+msgid "Lvl: %d (%+d)"
+msgstr "等級:%d"
+
+#: src/gui/skilldialog.cpp:416
+#, fuzzy, c-format
+msgid "Lvl: %d"
+msgstr "等級:%d"
+
+#: src/gui/socialwindow.cpp:117
+#, c-format
+msgid "Invited user %s to guild %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:126
+#, fuzzy, c-format
+msgid "Guild %s quit requested."
+msgstr "公會已成立."
+
+#: src/gui/socialwindow.cpp:136
+msgid "Member Invite to Guild"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:137
+#, c-format
+msgid "Who would you like to invite to guild %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:146
+#, fuzzy
+msgid "Leave Guild?"
+msgstr "建立公會"
+
+#: src/gui/socialwindow.cpp:147
+#, fuzzy, c-format
+msgid "Are you sure you want to leave guild %s?"
+msgstr "您確定要離開?"
+
+#: src/gui/socialwindow.cpp:182
+#, fuzzy, c-format
+msgid "Invited user %s to party."
+msgstr "/party > 邀請使用者組隊"
+
+#: src/gui/socialwindow.cpp:189
+#, c-format
+msgid "Party %s quit requested."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:199
+#, fuzzy
+msgid "Member Invite to Party"
+msgstr "/party > 邀請使用者組隊"
+
+#: src/gui/socialwindow.cpp:200
+#, c-format
+msgid "Who would you like to invite to party %s?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:209
+msgid "Leave Party?"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:210
+#, fuzzy, c-format
+msgid "Are you sure you want to leave party %s?"
+msgstr "您確定要離開?"
+
+#: src/gui/socialwindow.cpp:239
+msgid "Create Guild"
+msgstr "建立公會"
+
+#: src/gui/socialwindow.cpp:240 src/gui/socialwindow.cpp:564
+#, fuzzy
+msgid "Create Party"
+msgstr "新增角色"
+
+#: src/gui/socialwindow.cpp:279 src/gui/windowmenu.cpp:60
+msgid "Social"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:297
+#, fuzzy
+msgid "Invite"
+msgstr "邀請使用者"
+
+#: src/gui/socialwindow.cpp:298
+#, fuzzy
+msgid "Leave"
+msgstr "大型"
+
+#: src/gui/socialwindow.cpp:394
+#, fuzzy, c-format
+msgid "Accepted party invite from %s."
+msgstr "接受 %s 的派對邀請."
+
+#: src/gui/socialwindow.cpp:400
+#, fuzzy, c-format
+msgid "Rejected party invite from %s."
+msgstr "拒絕 %s 的派對邀請"
+
+#: src/gui/socialwindow.cpp:413
+#, fuzzy, c-format
+msgid "Accepted guild invite from %s."
+msgstr "接受 %s 的派對邀請."
+
+#: src/gui/socialwindow.cpp:419
+#, fuzzy, c-format
+msgid "Rejected guild invite from %s."
+msgstr "拒絕 %s 的派對邀請"
+
+#: src/gui/socialwindow.cpp:463
+#, fuzzy, c-format
+msgid "Creating guild called %s."
+msgstr "創建公會時發生錯誤."
+
+#: src/gui/socialwindow.cpp:477
+#, c-format
+msgid "Creating party called %s."
+msgstr ""
+
+#: src/gui/socialwindow.cpp:484
+#, fuzzy
+msgid "Guild Name"
+msgstr "公會"
+
+#: src/gui/socialwindow.cpp:485
+#, fuzzy
+msgid "Choose your guild's name."
+msgstr "選擇您的伺服器"
+
+#: src/gui/socialwindow.cpp:497
+#, fuzzy
+msgid "Received guild request, but one already exists."
+msgstr "收到派對邀請,但而有另一個存在."
+
+#: src/gui/socialwindow.cpp:502
+#, fuzzy, c-format
+msgid "%s has invited you to join the guild %s."
+msgstr "%s 邀請你參加 %s 派對."
+
+#: src/gui/socialwindow.cpp:507
+#, fuzzy
+msgid "Accept Guild Invite"
+msgstr "接受派對邀請"
+
+#: src/gui/socialwindow.cpp:519
+msgid "Received party request, but one already exists."
+msgstr "收到派對邀請,但而有另一個存在."
+
+#: src/gui/socialwindow.cpp:529
+#, fuzzy
+msgid "You have been invited you to join a party."
+msgstr "%s 邀請你參加他們的派對."
+
+#: src/gui/socialwindow.cpp:533
+#, fuzzy, c-format
+msgid "You have been invited to join the %s party."
+msgstr "%s 邀請你參加 %s 派對."
+
+#: src/gui/socialwindow.cpp:541
+#, c-format
+msgid "%s has invited you to join their party."
+msgstr "%s 邀請你參加他們的派對."
+
+#: src/gui/socialwindow.cpp:546
+#, c-format
+msgid "%s has invited you to join the %s party."
+msgstr "%s 邀請你參加 %s 派對."
+
+#: src/gui/socialwindow.cpp:554
+msgid "Accept Party Invite"
+msgstr "接受派對邀請"
+
+#: src/gui/socialwindow.cpp:565
+msgid "Cannot create party. You are already in a party"
+msgstr ""
+
+#: src/gui/socialwindow.cpp:570
+#, fuzzy
+msgid "Party Name"
+msgstr "隊伍"
+
+#: src/gui/socialwindow.cpp:571
+#, fuzzy
+msgid "Choose your party's name."
+msgstr "選擇您的伺服器"
+
+#: src/gui/specialswindow.cpp:85 src/gui/windowmenu.cpp:59
+msgid "Specials"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:174
+#, c-format
+msgid "Specials Set %d"
+msgstr ""
+
+#: src/gui/specialswindow.cpp:191
+#, c-format
+msgid "Special %d"
+msgstr ""
+
+#: src/gui/statuswindow.cpp:99 src/gui/statuswindow.cpp:247
+#, c-format
+msgid "Level: %d"
+msgstr "等級:%d"
+
+#: src/gui/statuswindow.cpp:100 src/gui/statuswindow.cpp:211
+#, c-format
+msgid "Money: %s"
+msgstr "金錢: %s"
+
+#: src/gui/statuswindow.cpp:102
+msgid "HP:"
+msgstr "體力 :"
+
+#: src/gui/statuswindow.cpp:107
+msgid "Exp:"
+msgstr "經驗值:"
+
+#: src/gui/statuswindow.cpp:112
+msgid "MP:"
+msgstr "魔力:"
+
+#: src/gui/statuswindow.cpp:132 src/gui/statuswindow.cpp:219
+#, c-format
+msgid "Job: %d"
+msgstr "職業:%d"
+
+#: src/gui/statuswindow.cpp:133
+msgid "Job:"
+msgstr "職業:"
+
+#: src/gui/statuswindow.cpp:194
+#, fuzzy
+msgid "HP"
+msgstr "體力 :"
+
+#: src/gui/statuswindow.cpp:200
+#, fuzzy
+msgid "MP"
+msgstr "魔力:"
+
+#: src/gui/statuswindow.cpp:206
+#, fuzzy
+msgid "Exp"
+msgstr "經驗值:"
+
+#: src/gui/statuswindow.cpp:215
+#, fuzzy
+msgid "Money"
+msgstr "金錢:%d"
+
+#: src/gui/statuswindow.cpp:225
+#, fuzzy
+msgid "Job"
+msgstr "職業:"
+
+#: src/gui/statuswindow.cpp:229
+#, fuzzy, c-format
+msgid "Character points: %d"
+msgstr "角色狀態確定"
+
+#: src/gui/statuswindow.cpp:235
+#, fuzzy, c-format
+msgid "Correction points: %d"
+msgstr "技能點數:%d"
+
+#: src/gui/statuswindow.cpp:251
+#, fuzzy
+msgid "Level"
+msgstr "等級:%d"
+
+#: src/gui/storagewindow.cpp:58
+msgid "Storage"
+msgstr "貯藏庫"
+
+#: src/gui/trade.cpp:52
+msgid "Propose trade"
+msgstr "是否交易"
+
+#: src/gui/trade.cpp:53
+msgid "Confirmed. Waiting..."
+msgstr "已確認。請稍候..."
+
+#: src/gui/trade.cpp:54
+msgid "Agree trade"
+msgstr "同意交易"
+
+#: src/gui/trade.cpp:55
+msgid "Agreed. Waiting..."
+msgstr "已同意。請稍候..."
+
+#: src/gui/trade.cpp:58
+msgid "Trade: You"
+msgstr "交易:您"
+
+#: src/gui/trade.cpp:74 src/gui/trade.cpp:75
+msgid "Trade"
+msgstr "交易"
+
+#: src/gui/trade.cpp:77
+msgid "Add"
+msgstr "增加"
+
+#: src/gui/trade.cpp:99 src/gui/trade.cpp:135
+#, fuzzy, c-format
+msgid "You get %s"
+msgstr "您得到 %s。"
+
+#: src/gui/trade.cpp:100
+msgid "You give:"
+msgstr "你付出:"
+
+#: src/gui/trade.cpp:104
+msgid "Change"
+msgstr "更改"
+
+#: src/gui/trade.cpp:275
+msgid "Failed adding item. You can not overlap one kind of item on the window."
+msgstr "增加物品失敗。你不能覆蓋視窗中的該類物品能。"
+
+#: src/gui/trade.cpp:318
+msgid "You don't have enough money."
+msgstr "你沒有足夠的金錢."
+
+#: src/gui/unregisterdialog.cpp:51
+#, c-format
+msgid "Name: %s"
+msgstr "名字:%s"
+
+#: src/gui/updatewindow.cpp:124
+msgid "Updating..."
+msgstr "更新中..."
+
+#: src/gui/updatewindow.cpp:142
+msgid "Connecting..."
+msgstr "連線中..."
+
+#: src/gui/updatewindow.cpp:145
+msgid "Play"
+msgstr "開始"
+
+#: src/gui/updatewindow.cpp:405
+msgid "##1 The update process is incomplete."
+msgstr "##1 更新的程序不完整。"
+
+#. TRANSLATORS: Continues "you try again later.".
+#: src/gui/updatewindow.cpp:407
+msgid "##1 It is strongly recommended that"
+msgstr "##1 強烈建議"
+
+#. TRANSLATORS: Begins "It is strongly recommended that".
+#: src/gui/updatewindow.cpp:409
+#, fuzzy
+msgid "##1 you try again later."
+msgstr "##1 您稍後再試一次"
+
+#: src/gui/updatewindow.cpp:501
+msgid "Completed"
+msgstr "已完成"
+
+#: src/gui/widgets/channeltab.cpp:49
+msgid "/users > Lists the users in the current channel"
+msgstr "/users > 列出在目前頻道的使用者"
+
+#: src/gui/widgets/channeltab.cpp:50
+msgid "/topic > Set the topic of the current channel"
+msgstr "/topic > 設定目前頻道的主題"
+
+#: src/gui/widgets/channeltab.cpp:51
+msgid "/quit > Leave a channel"
+msgstr "/quit > 離開頻道"
+
+#: src/gui/widgets/channeltab.cpp:52
+msgid "/op > Make a user a channel operator"
+msgstr "/op > 讓使用者成為頻道操作者"
+
+#: src/gui/widgets/channeltab.cpp:53
+msgid "/kick > Kick a user from the channel"
+msgstr "/kick > 將使用者踢出此頻道"
+
+#: src/gui/widgets/channeltab.cpp:63
+msgid "Command: /users"
+msgstr "指令: /users"
+
+#: src/gui/widgets/channeltab.cpp:64
+msgid "This command shows the users in this channel."
+msgstr "這個指令會顯示在這個頻道中的使用者。"
+
+#: src/gui/widgets/channeltab.cpp:68
+msgid "Command: /topic <message>"
+msgstr "指令: /topic <message>"
+
+#: src/gui/widgets/channeltab.cpp:69
+msgid "This command sets the topic to <message>."
+msgstr "這個指令會將主題設定為 <message>。"
+
+#: src/gui/widgets/channeltab.cpp:73
+msgid "Command: /quit"
+msgstr "指令:/quit"
+
+#: src/gui/widgets/channeltab.cpp:74
+msgid "This command leaves the current channel."
+msgstr "這個指令會離開目前的頻道。"
+
+#: src/gui/widgets/channeltab.cpp:75
+msgid "If you're the last person in the channel, it will be deleted."
+msgstr "如果您是此頻道中的最後一個人,這個頻道就會被刪除。"
+
+#: src/gui/widgets/channeltab.cpp:80
+msgid "Command: /op <nick>"
+msgstr "指令: /op <nick>"
+
+#: src/gui/widgets/channeltab.cpp:81
+msgid "This command makes <nick> a channel operator."
+msgstr "這個指令會讓 <nick> 成為頻道操作者。"
+
+#: src/gui/widgets/channeltab.cpp:84
+msgid "Channel operators can kick and op other users from the channel."
+msgstr "頻道操作者可以對該頻道中的其他使用者進行 kick 或 op。"
+
+#: src/gui/widgets/channeltab.cpp:89
+msgid "Command: /kick <nick>"
+msgstr "指令: /kick <nick>"
+
+#: src/gui/widgets/channeltab.cpp:90
+msgid "This command makes <nick> leave the channel."
+msgstr "這個指令會讓 <nick> 離開此頻道。"
+
+#: src/gui/widgets/channeltab.cpp:119
+msgid "Need a user to op!"
+msgstr "需要指定要成為 op 的使用者!"
+
+#: src/gui/widgets/channeltab.cpp:126
+msgid "Need a user to kick!"
+msgstr "需要指定要踢掉的使用者!"
+
+#: src/gui/widgets/chattab.cpp:118
+msgid "Global announcement:"
+msgstr "主要公告:"
+
+#: src/gui/widgets/chattab.cpp:124
+#, c-format
+msgid "Global announcement from %s:"
+msgstr "%s 主要公告:"
+
+#: src/gui/widgets/chattab.cpp:150
+#, fuzzy, c-format
+msgid "%s whispers: %s"
+msgstr "%s 的悄悄話: "
+
+#: src/gui/widgets/whispertab.cpp:51
+msgid "Cannot send empty chat!"
+msgstr "不能傳送空的聊天訊息!"
+
+#: src/gui/widgets/whispertab.cpp:70
+msgid "/ignore > Ignore the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:71
+msgid "/unignore > Stop ignoring the other player"
+msgstr ""
+
+#: src/gui/widgets/whispertab.cpp:72
+msgid "/close > Close the whisper tab"
+msgstr "/close > 關閉悄悄話分頁"
+
+#: src/gui/widgets/whispertab.cpp:82
+msgid "Command: /close"
+msgstr "指令: /close"
+
+#: src/gui/widgets/whispertab.cpp:83
+msgid "This command closes the current whisper tab."
+msgstr "這個指令會關閉目前的悄悄話分頁。"
+
+#: src/gui/widgets/whispertab.cpp:87
+#, fuzzy
+msgid "Command: /ignore"
+msgstr "指令: /item"
+
+#: src/gui/widgets/whispertab.cpp:88
+#, fuzzy
+msgid "This command ignores the other player regardless of current relations."
+msgstr "這調指令可顯示目前線上人數。"
+
+#: src/gui/widgets/whispertab.cpp:94
+#, fuzzy
+msgid "This command stops ignoring the other player if they are being ignored."
+msgstr "這個指令會開始將聊天紀錄錄製為檔案 <filename>。"
+
+#: src/gui/windowmenu.cpp:55
+msgid "Status"
+msgstr "狀態"
+
+#: src/gui/windowmenu.cpp:61
+msgid "Shortcut"
+msgstr "快捷鍵"
+
+#: src/gui/worldselectdialog.cpp:71
+#, fuzzy
+msgid "Select World"
+msgstr "選擇確定"
+
+#: src/gui/worldselectdialog.cpp:76
+#, fuzzy
+msgid "Change Login"
+msgstr "更改"
+
+#: src/gui/worldselectdialog.cpp:77
+#, fuzzy
+msgid "Choose World"
+msgstr "選擇您的伺服器"
+
+#: src/keyboardconfig.cpp:40
+msgid "Move Up"
+msgstr "上移"
+
+#: src/keyboardconfig.cpp:41
+msgid "Move Down"
+msgstr "下移"
+
+#: src/keyboardconfig.cpp:42
+msgid "Move Left"
+msgstr "左移"
+
+#: src/keyboardconfig.cpp:43
+msgid "Move Right"
+msgstr "右移"
+
+#: src/keyboardconfig.cpp:44 src/net/ea/generalhandler.cpp:223
+msgid "Attack"
+msgstr "攻擊"
+
+#: src/keyboardconfig.cpp:45
+msgid "Target & Attack"
+msgstr "尋找目標攻擊"
+
+#: src/keyboardconfig.cpp:46
+msgid "Smilie"
+msgstr "史萊姆吃掉妳了~~"
+
+#: src/keyboardconfig.cpp:47
+msgid "Talk"
+msgstr "說話"
+
+#: src/keyboardconfig.cpp:48
+msgid "Stop Attack"
+msgstr "停止攻擊"
+
+#: src/keyboardconfig.cpp:49
+#, fuzzy
+msgid "Target Monster"
+msgstr "最接近的目標"
+
+#: src/keyboardconfig.cpp:50
+msgid "Target NPC"
+msgstr "以 NPC 為目標"
+
+#: src/keyboardconfig.cpp:51
+msgid "Target Player"
+msgstr "以玩家為目標"
+
+#: src/keyboardconfig.cpp:52
+msgid "Pickup"
+msgstr "撿拾"
+
+#: src/keyboardconfig.cpp:53
+msgid "Hide Windows"
+msgstr "隱藏視窗"
+
+#: src/keyboardconfig.cpp:54
+msgid "Sit"
+msgstr "坐下"
+
+#: src/keyboardconfig.cpp:55
+msgid "Screenshot"
+msgstr "螢幕快照"
+
+#: src/keyboardconfig.cpp:56
+msgid "Enable/Disable Trading"
+msgstr "啟用/停用交易"
+
+#: src/keyboardconfig.cpp:57
+msgid "Find Path to Mouse"
+msgstr "尋找至滑鼠的路徑"
+
+#: src/keyboardconfig.cpp:58 src/keyboardconfig.cpp:59
+#: src/keyboardconfig.cpp:60 src/keyboardconfig.cpp:61
+#: src/keyboardconfig.cpp:62 src/keyboardconfig.cpp:63
+#: src/keyboardconfig.cpp:64 src/keyboardconfig.cpp:65
+#: src/keyboardconfig.cpp:66 src/keyboardconfig.cpp:67
+#: src/keyboardconfig.cpp:68 src/keyboardconfig.cpp:69
+#, c-format
+msgid "Item Shortcut %d"
+msgstr "物品捷徑鍵 %d"
+
+#: src/keyboardconfig.cpp:70
+msgid "Help Window"
+msgstr "說明視窗"
+
+#: src/keyboardconfig.cpp:71
+msgid "Status Window"
+msgstr "狀態視窗"
+
+#: src/keyboardconfig.cpp:72
+msgid "Inventory Window"
+msgstr "物品欄視窗"
+
+#: src/keyboardconfig.cpp:73
+msgid "Equipment Window"
+msgstr "物品視窗"
+
+#: src/keyboardconfig.cpp:74
+msgid "Skill Window"
+msgstr "技能視窗"
+
+#: src/keyboardconfig.cpp:75
+msgid "Minimap Window"
+msgstr "迷你地圖視窗"
+
+#: src/keyboardconfig.cpp:76
+msgid "Chat Window"
+msgstr "聊天視窗"
+
+#: src/keyboardconfig.cpp:77
+msgid "Item Shortcut Window"
+msgstr "物品捷徑鍵視窗"
+
+#: src/keyboardconfig.cpp:78
+msgid "Setup Window"
+msgstr "設定視窗"
+
+#: src/keyboardconfig.cpp:79
+msgid "Debug Window"
+msgstr "程式除錯視窗"
+
+#: src/keyboardconfig.cpp:80
+#, fuzzy
+msgid "Social Window"
+msgstr "技能視窗"
+
+#: src/keyboardconfig.cpp:81
+msgid "Emote Shortcut Window"
+msgstr "表情捷徑鍵視窗"
+
+#: src/keyboardconfig.cpp:82
+#, fuzzy
+msgid "Outfits Window"
+msgstr "狀態視窗"
+
+#: src/keyboardconfig.cpp:83
+msgid "Wear Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:84
+msgid "Copy Outfit"
+msgstr ""
+
+#: src/keyboardconfig.cpp:85 src/keyboardconfig.cpp:86
+#: src/keyboardconfig.cpp:87 src/keyboardconfig.cpp:88
+#: src/keyboardconfig.cpp:89 src/keyboardconfig.cpp:90
+#: src/keyboardconfig.cpp:91 src/keyboardconfig.cpp:92
+#: src/keyboardconfig.cpp:93 src/keyboardconfig.cpp:94
+#: src/keyboardconfig.cpp:95 src/keyboardconfig.cpp:96
+#, c-format
+msgid "Emote Shortcut %d"
+msgstr "表情捷徑鍵 %d"
+
+#: src/keyboardconfig.cpp:97
+msgid "Toggle Chat"
+msgstr "切換聊天"
+
+#: src/keyboardconfig.cpp:98
+msgid "Scroll Chat Up"
+msgstr "將聊天向上捲動"
+
+#: src/keyboardconfig.cpp:99
+msgid "Scroll Chat Down"
+msgstr "將聊天向下捲動"
+
+#: src/keyboardconfig.cpp:100
+msgid "Previous Chat Tab"
+msgstr "前一個聊天分頁"
+
+#: src/keyboardconfig.cpp:101
+msgid "Next Chat Tab"
+msgstr "下一個聊天分頁"
+
+#: src/keyboardconfig.cpp:102
+msgid "Select OK"
+msgstr "選擇確定"
+
+#: src/keyboardconfig.cpp:104
+msgid "Ignore input 1"
+msgstr "忽略輸入 1"
+
+#: src/keyboardconfig.cpp:105
+msgid "Ignore input 2"
+msgstr "忽略輸入 2"
+
+#: src/keyboardconfig.cpp:178
+#, fuzzy, c-format
+msgid ""
+"Conflict \"%s\" and \"%s\" keys. Resolve them, or gameplay may result in "
+"strange behaviour."
+msgstr "解決按鍵衝突,否則遊戲中可能遇到奇怪行為。"
+
+#: src/localplayer.cpp:913
+msgid "Unable to pick up item."
+msgstr "不能拾取物品."
+
+#. TRANSLATORS: This sentence may be translated differently
+#. for different grammatical numbers (singular, plural, ...)
+#: src/localplayer.cpp:922
+#, fuzzy, c-format
+msgid "You picked up %d [@@%d|%s@@]."
+msgid_plural "You picked up %d [@@%d|%s@@]."
+msgstr[0] "你拾取了 %s [@@%d|%s@@]."
+msgstr[1] "你拾取了 %s [@@%d|%s@@]."
+
+#: src/main.cpp:43
+msgid "mana [options] [mana-file]"
+msgstr ""
+
+#: src/main.cpp:44
+msgid "Options:"
+msgstr "選項:"
+
+#: src/main.cpp:45
+#, fuzzy
+msgid " -v --version : Display the version"
+msgstr " -v --version : 顯示遊戲版本"
+
+#: src/main.cpp:46
+#, fuzzy
+msgid " -h --help : Display this help"
+msgstr " -h --help : 顯示求助說明"
+
+#: src/main.cpp:47
+#, fuzzy
+msgid " -C --config-dir : Configuration directory to use"
+msgstr " -C --config-file : 使用此設定檔"
+
+#: src/main.cpp:48
+#, fuzzy
+msgid " -U --username : Login with this username"
+msgstr " -U -username : 使用此帳號登入"
+
+#: src/main.cpp:49
+#, fuzzy
+msgid " -P --password : Login with this password"
+msgstr " -P --password : 用此密碼登入"
+
+#: src/main.cpp:50
+#, fuzzy
+msgid " -c --character : Login with this character"
+msgstr " -c --character : 用此帳號登入"
+
+#: src/main.cpp:51
+#, fuzzy
+msgid " -s --server : Login server name or IP"
+msgstr " -s --server : 登錄伺服器埠名稱或IP位址"
+
+#: src/main.cpp:52
+#, fuzzy
+msgid " -p --port : Login server port"
+msgstr " -p --port : 登錄伺服器埠"
+
+#: src/main.cpp:53
+#, fuzzy
+msgid " --update-host : Use this update host"
+msgstr " -H --update-host : 使用此更新伺服器"
+
+#: src/main.cpp:54
+#, fuzzy
+msgid " -D --default : Choose default character server and character"
+msgstr " -D --default : 選擇預設的角色伺服器及角色"
+
+#: src/main.cpp:56
+#, fuzzy
+msgid " -u --skip-update : Skip the update downloads"
+msgstr " -u --skip-update : 不使用更新"
+
+#: src/main.cpp:57
+#, fuzzy
+msgid " -d --data : Directory to load game data from"
+msgstr " -d -data : 指定遊戲資料所在的目錄"
+
+#: src/main.cpp:58
+#, fuzzy
+msgid " -L --localdata-dir : Directory to use as local data directory"
+msgstr " -S --home-dir : 設定此目錄為家目錄"
+
+#: src/main.cpp:59
+#, fuzzy
+msgid " --screenshot-dir : Directory to store screenshots"
+msgstr " -S --home-dir : 設定此目錄為家目錄"
+
+#: src/main.cpp:61
+#, fuzzy
+msgid " --no-opengl : Disable OpenGL for this session"
+msgstr " -O --no-opengl : 不使用OpenGL"
+
+#: src/net/ea/adminhandler.cpp:63
+msgid "Kick failed!"
+msgstr "踢人失敗!"
+
+#: src/net/ea/adminhandler.cpp:65
+msgid "Kick succeeded!"
+msgstr "踢人成功!"
+
+#: src/net/ea/buysellhandler.cpp:110
+msgid "Nothing to sell."
+msgstr "沒有任何物品可出售."
+
+#: src/net/ea/buysellhandler.cpp:117
+msgid "Thanks for buying."
+msgstr "謝謝光臨."
+
+#: src/net/ea/buysellhandler.cpp:124
+msgid "Unable to buy."
+msgstr "不能購買."
+
+#: src/net/ea/buysellhandler.cpp:130
+msgid "Thanks for selling."
+msgstr "謝謝你的出售."
+
+#: src/net/ea/buysellhandler.cpp:132
+msgid "Unable to sell."
+msgstr "不能出售."
+
+#: src/net/ea/charserverhandler.cpp:103
+#, fuzzy
+msgid "Access denied."
+msgstr "存取被拒"
+
+#: src/net/ea/charserverhandler.cpp:106
+#, fuzzy
+msgid "Cannot use this ID."
+msgstr "不能使用這個 ID"
+
+#: src/net/ea/charserverhandler.cpp:109
+#, fuzzy
+msgid "Unknown failure to select character."
+msgstr "選擇角色發生不明的失敗"
+
+#: src/net/ea/charserverhandler.cpp:135
+msgid "Failed to create character. Most likely the name is already taken."
+msgstr "建立角色失敗。最有可能的情形是該名稱已經被使用了。"
+
+#: src/net/ea/charserverhandler.cpp:147 src/net/manaserv/charhandler.cpp:187
+msgid "Info"
+msgstr "資訊"
+
+#: src/net/ea/charserverhandler.cpp:147
+msgid "Character deleted."
+msgstr "角色被刪除."
+
+#: src/net/ea/charserverhandler.cpp:152
+msgid "Failed to delete character."
+msgstr "刪除角色失敗。"
+
+#: src/net/ea/charserverhandler.cpp:237 src/net/manaserv/charhandler.cpp:263
+msgid "Strength:"
+msgstr "力量:"
+
+#: src/net/ea/charserverhandler.cpp:238 src/net/manaserv/charhandler.cpp:264
+msgid "Agility:"
+msgstr "敏捷:"
+
+#: src/net/ea/charserverhandler.cpp:239 src/net/manaserv/charhandler.cpp:266
+msgid "Vitality:"
+msgstr "體力:"
+
+#: src/net/ea/charserverhandler.cpp:240 src/net/manaserv/charhandler.cpp:267
+msgid "Intelligence:"
+msgstr "智力:"
+
+#: src/net/ea/charserverhandler.cpp:241 src/net/manaserv/charhandler.cpp:265
+msgid "Dexterity:"
+msgstr "閃躲:"
+
+#: src/net/ea/charserverhandler.cpp:242
+msgid "Luck:"
+msgstr "幸運:"
+
+#: src/net/ea/chathandler.cpp:80
+msgid "Whisper could not be sent, user is offline."
+msgstr "該玩家已離線,無法送出密語."
+
+#: src/net/ea/chathandler.cpp:84
+msgid "Whisper could not be sent, ignored by user."
+msgstr "該玩家拒絕你的密語"
+
+#: src/net/ea/chathandler.cpp:171
+#, fuzzy
+msgid "MVP player."
+msgstr "玩家"
+
+#: src/net/ea/chathandler.cpp:204 src/net/ea/chathandler.cpp:210
+#: src/net/ea/chathandler.cpp:215 src/net/ea/chathandler.cpp:220
+#: src/net/ea/chathandler.cpp:225 src/net/ea/chathandler.cpp:230
+#: src/net/ea/chathandler.cpp:235 src/net/ea/chathandler.cpp:240
+msgid "Channels are not supported!"
+msgstr "頻道不支援!"
+
+#: src/net/ea/gamehandler.cpp:86
+#, c-format
+msgid "Online users: %d"
+msgstr ""
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Game"
+msgstr "名字"
+
+#: src/net/ea/gamehandler.cpp:100
+#, fuzzy
+msgid "Request to quit denied!"
+msgstr "要求交易"
+
+#: src/net/ea/generalhandler.cpp:102 src/net/manaserv/generalhandler.cpp:95
+#, c-format
+msgid "Strength %+d"
+msgstr "力量 %+d"
+
+#: src/net/ea/generalhandler.cpp:103 src/net/manaserv/generalhandler.cpp:96
+#, c-format
+msgid "Agility %+d"
+msgstr "敏捷 %+d"
+
+#: src/net/ea/generalhandler.cpp:104 src/net/manaserv/generalhandler.cpp:98
+#, c-format
+msgid "Vitality %+d"
+msgstr "體力 %+d"
+
+#: src/net/ea/generalhandler.cpp:105 src/net/manaserv/generalhandler.cpp:99
+#, c-format
+msgid "Intelligence %+d"
+msgstr "智力 %+d"
+
+#: src/net/ea/generalhandler.cpp:106 src/net/manaserv/generalhandler.cpp:97
+#, c-format
+msgid "Dexterity %+d"
+msgstr "閃躲 %+d"
+
+#: src/net/ea/generalhandler.cpp:107
+#, c-format
+msgid "Luck %+d"
+msgstr "幸運 %+d"
+
+#: src/net/ea/generalhandler.cpp:130
+#, fuzzy
+msgid "Authentication failed."
+msgstr "驗證失敗"
+
+#: src/net/ea/generalhandler.cpp:133
+#, fuzzy
+msgid "No servers available."
+msgstr "沒有可用的伺服器"
+
+#: src/net/ea/generalhandler.cpp:137
+#, fuzzy
+msgid "Someone else is trying to use this account."
+msgstr "此帳號正在使用中"
+
+#: src/net/ea/generalhandler.cpp:140
+#, fuzzy
+msgid "This account is already logged in."
+msgstr "這個帳號已經登入"
+
+#: src/net/ea/generalhandler.cpp:143
+#, fuzzy
+msgid "Speed hack detected."
+msgstr "使用加速器"
+
+#: src/net/ea/generalhandler.cpp:146
+#, fuzzy
+msgid "Duplicated login."
+msgstr "重複登入"
+
+#: src/net/ea/generalhandler.cpp:149
+#, fuzzy
+msgid "Unknown connection error."
+msgstr "不明的連線錯誤"
+
+#: src/net/ea/generalhandler.cpp:205
+msgid "Got disconnected from server!"
+msgstr "和伺服器失去連線"
+
+#: src/net/ea/generalhandler.cpp:216 src/net/manaserv/generalhandler.cpp:166
+msgid "Strength"
+msgstr "力量"
+
+#: src/net/ea/generalhandler.cpp:217 src/net/manaserv/generalhandler.cpp:167
+msgid "Agility"
+msgstr "敏捷"
+
+#: src/net/ea/generalhandler.cpp:218 src/net/manaserv/generalhandler.cpp:169
+msgid "Vitality"
+msgstr "體力"
+
+#: src/net/ea/generalhandler.cpp:219 src/net/manaserv/generalhandler.cpp:170
+msgid "Intelligence"
+msgstr "智力"
+
+#: src/net/ea/generalhandler.cpp:220 src/net/manaserv/generalhandler.cpp:168
+msgid "Dexterity"
+msgstr "閃躲"
+
+#: src/net/ea/generalhandler.cpp:221
+msgid "Luck"
+msgstr "幸運"
+
+#: src/net/ea/generalhandler.cpp:224
+#, fuzzy
+msgid "Defense"
+msgstr "防禦:"
+
+#: src/net/ea/generalhandler.cpp:225
+#, fuzzy
+msgid "M.Attack"
+msgstr "摩攻:"
+
+#: src/net/ea/generalhandler.cpp:226
+#, fuzzy
+msgid "M.Defense"
+msgstr "魔防:"
+
+#: src/net/ea/generalhandler.cpp:227
+#, fuzzy, c-format
+msgid "% Accuracy"
+msgstr "% Ac準確度:"
+
+#: src/net/ea/generalhandler.cpp:228
+#, fuzzy, c-format
+msgid "% Evade"
+msgstr "% E迴避率:"
+
+#: src/net/ea/generalhandler.cpp:229
+#, fuzzy, c-format
+msgid "% Critical"
+msgstr "致命一擊"
+
+#: src/net/ea/gui/guildtab.cpp:61 src/net/ea/gui/partytab.cpp:59
+msgid "/help > Display this help."
+msgstr "/help > 顯示這個說明文件。"
+
+#: src/net/ea/gui/guildtab.cpp:62
+#, fuzzy
+msgid "/invite > Invite a player to your guild"
+msgstr "/invite > 邀請玩家加入您的隊伍"
+
+#: src/net/ea/gui/guildtab.cpp:63
+#, fuzzy
+msgid "/leave > Leave the guild you are in"
+msgstr "/leave > 離開您加入的隊伍"
+
+#: src/net/ea/gui/guildtab.cpp:64
+#, fuzzy
+msgid "/kick > Kick some one from the guild you are in"
+msgstr "/kick > 從您加入的隊伍中把某人踢出"
+
+#: src/net/ea/gui/guildtab.cpp:73 src/net/ea/gui/partytab.cpp:73
+msgid "Command: /invite <nick>"
+msgstr "/invite <暱稱>"
+
+#: src/net/ea/gui/guildtab.cpp:74
+#, fuzzy
+msgid "This command invites <nick> to the guild you're in."
+msgstr "這個指令會邀請 <nick> 跟您組隊。"
+
+#: src/net/ea/gui/guildtab.cpp:80 src/net/ea/gui/partytab.cpp:80
+msgid "Command: /leave"
+msgstr "指令: /leave"
+
+#: src/net/ea/gui/guildtab.cpp:81
+#, fuzzy
+msgid "This command causes the player to leave the guild."
+msgstr "這個指令會使玩家離開隊伍。"
+
+#: src/net/ea/gui/guildtab.cpp:89
+#, fuzzy
+msgid "Guild name is missing."
+msgstr "漏掉隊伍名稱。"
+
+#: src/net/ea/guildhandler.cpp:293
+msgid "Could not inivte user to guild."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:298
+msgid "User rejected guild invite."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:303
+#, fuzzy
+msgid "User is now part of your guild."
+msgstr "%s 現在已經是您隊伍的成員。"
+
+#: src/net/ea/guildhandler.cpp:308
+msgid "Your guild is full."
+msgstr ""
+
+#: src/net/ea/guildhandler.cpp:313
+#, fuzzy
+msgid "Unknown guild invite response."
+msgstr "給 %s 的不明邀請回應。"
+
+#: src/net/ea/guildhandler.cpp:390
+msgid "Guild creation isn't supported yet."
+msgstr ""
+
+#: src/net/ea/gui/partytab.cpp:60
+msgid "/invite > Invite a player to your party"
+msgstr "/invite > 邀請玩家加入您的隊伍"
+
+#: src/net/ea/gui/partytab.cpp:61
+msgid "/leave > Leave the party you are in"
+msgstr "/leave > 離開您加入的隊伍"
+
+#: src/net/ea/gui/partytab.cpp:62
+msgid "/kick > Kick some one from the party you are in"
+msgstr "/kick > 從您加入的隊伍中把某人踢出"
+
+#: src/net/ea/gui/partytab.cpp:63
+msgid "/item > Show/change party item sharing options"
+msgstr "/item > 顯示/改變隊伍道具分享選項"
+
+#: src/net/ea/gui/partytab.cpp:64
+msgid "/exp > Show/change party experience sharing options"
+msgstr "/exp > 顯示/改變隊伍經驗值分享選項"
+
+#: src/net/ea/gui/partytab.cpp:81
+msgid "This command causes the player to leave the party."
+msgstr "這個指令會使玩家離開隊伍。"
+
+#: src/net/ea/gui/partytab.cpp:85
+msgid "Command: /item <policy>"
+msgstr "/item <政策>"
+
+#: src/net/ea/gui/partytab.cpp:86
+msgid "This command changes the party's item sharing policy."
+msgstr "這個指令會改變隊伍的道具分享政策。"
+
+#: src/net/ea/gui/partytab.cpp:87
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable item sharing, or "
+"\"0\", \"no\", \"false\" to disable item sharing."
+msgstr ""
+"<policy> 可以是 \"1\"、\"yes\"、\"true\" 之一代表啟用道具分享,或是 \"0\"、"
+"\"no\"、\"false\" 來停用道具分享。"
+
+#: src/net/ea/gui/partytab.cpp:90
+msgid "Command: /item"
+msgstr "指令: /item"
+
+#: src/net/ea/gui/partytab.cpp:91
+msgid "This command displays the party's current item sharing policy."
+msgstr "這個指令會顯示此隊伍目前的道具分享政策。"
+
+#: src/net/ea/gui/partytab.cpp:95
+msgid "Command: /exp <policy>"
+msgstr "指令: /exp <政策>"
+
+#: src/net/ea/gui/partytab.cpp:96
+msgid "This command changes the party's experience sharing policy."
+msgstr "這個指令會改變此隊伍的經驗值分享政策。"
+
+#: src/net/ea/gui/partytab.cpp:97
+msgid ""
+"<policy> can be one of \"1\", \"yes\", \"true\" to enable experience "
+"sharing, or \"0\", \"no\", \"false\" to disable experience sharing."
+msgstr ""
+"<policy> 可以是 \"1\"、\"yes\"、\"true\" 之一代表啟用經驗值分享,或是 \"0\"、"
+"\"no\"、\"false\" 來停用經驗值分享。"
+
+#: src/net/ea/gui/partytab.cpp:100
+msgid "Command: /exp"
+msgstr "指令: /exp"
+
+#: src/net/ea/gui/partytab.cpp:101
+msgid "This command displays the party's current experience sharing policy."
+msgstr "這個指令會顯示此隊伍目前的經驗值分享政策。"
+
+#: src/net/ea/gui/partytab.cpp:132 src/net/ea/partyhandler.cpp:198
+msgid "Item sharing enabled."
+msgstr "物品分享已啟用。"
+
+#: src/net/ea/gui/partytab.cpp:135 src/net/ea/partyhandler.cpp:204
+msgid "Item sharing disabled."
+msgstr "物品分享已停用。"
+
+#: src/net/ea/gui/partytab.cpp:138 src/net/ea/partyhandler.cpp:210
+msgid "Item sharing not possible."
+msgstr "物品分享不可能。"
+
+#: src/net/ea/gui/partytab.cpp:141
+#, fuzzy
+msgid "Item sharing unknown."
+msgstr "物品分享已啟用。"
+
+#: src/net/ea/gui/partytab.cpp:167 src/net/ea/partyhandler.cpp:174
+msgid "Experience sharing enabled."
+msgstr "經驗值分享已啟用。"
+
+#: src/net/ea/gui/partytab.cpp:170 src/net/ea/partyhandler.cpp:180
+msgid "Experience sharing disabled."
+msgstr "經驗值分享已停用。"
+
+#: src/net/ea/gui/partytab.cpp:173 src/net/ea/partyhandler.cpp:186
+msgid "Experience sharing not possible."
+msgstr "經驗值分享不可能。"
+
+#: src/net/ea/gui/partytab.cpp:176
+#, fuzzy
+msgid "Experience sharing unknown."
+msgstr "經驗值分享已啟用。"
+
+#: src/net/ea/inventoryhandler.cpp:281
+msgid "Failed to use item."
+msgstr "不能使用該物品."
+
+#: src/net/ea/inventoryhandler.cpp:391
+msgid "Unable to equip."
+msgstr "無法裝備。"
+
+#: src/net/ea/inventoryhandler.cpp:402
+msgid "Unable to unequip."
+msgstr "無法卸下裝備。"
+
+#: src/net/ea/loginhandler.cpp:79
+msgid "Account was not found. Please re-login."
+msgstr "找不到該帳號,請重新登入."
+
+#: src/net/ea/loginhandler.cpp:82 src/net/manaserv/loginhandler.cpp:121
+#, fuzzy
+msgid "Old password incorrect."
+msgstr "舊密碼輸入錯誤"
+
+#: src/net/ea/loginhandler.cpp:85
+#, fuzzy
+msgid "New password too short."
+msgstr "新設定的密碼長度太短."
+
+#: src/net/ea/loginhandler.cpp:88 src/net/ea/loginhandler.cpp:175
+#: src/net/manaserv/charhandler.cpp:158 src/net/manaserv/loginhandler.cpp:96
+#: src/net/manaserv/loginhandler.cpp:127 src/net/manaserv/loginhandler.cpp:161
+#: src/net/manaserv/loginhandler.cpp:279 src/net/manaserv/loginhandler.cpp:316
+#, fuzzy
+msgid "Unknown error."
+msgstr "不明的錯誤"
+
+#: src/net/ea/loginhandler.cpp:149
+#, fuzzy
+msgid "Unregistered ID."
+msgstr "未註冊的 ID"
+
+#: src/net/ea/loginhandler.cpp:152
+#, fuzzy
+msgid "Wrong password."
+msgstr "錯誤的密碼"
+
+#: src/net/ea/loginhandler.cpp:155
+#, fuzzy
+msgid "Account expired."
+msgstr "帳號已過期"
+
+#: src/net/ea/loginhandler.cpp:158
+#, fuzzy
+msgid "Rejected from server."
+msgstr "被伺服器拒絕"
+
+#: src/net/ea/loginhandler.cpp:161
+#, fuzzy
+msgid ""
+"You have been permanently banned from the game. Please contact the GM team."
+msgstr "您已經被這個遊戲永遠列入黑名單。請連絡 GM 團隊。"
+
+#: src/net/ea/loginhandler.cpp:165
+#, c-format
+msgid ""
+"You have been temporarily banned from the game until %s.\n"
+"Please contact the GM team via the forums."
+msgstr ""
+"你的帳號已被暫時凍結直至 %s.\n"
+"請通過論壇聯絡GM."
+
+#: src/net/ea/loginhandler.cpp:172
+#, fuzzy
+msgid "This user name is already taken."
+msgstr "這個使用者名稱已經被使用了"
+
+#: src/net/ea/network.cpp:145
+msgid "Empty address given to Network::connect()!"
+msgstr ""
+
+#: src/net/ea/network.cpp:345
+#, fuzzy
+msgid "Unable to resolve host \""
+msgstr "不能出售."
+
+#: src/net/ea/network.cpp:414
+#, fuzzy
+msgid "Connection to server terminated. "
+msgstr "正在連接到地圖伺服器..."
+
+#: src/net/ea/partyhandler.cpp:81
+msgid "Could not create party."
+msgstr "無法建立隊伍。"
+
+#: src/net/ea/partyhandler.cpp:84
+msgid "Party successfully created."
+msgstr "隊伍已成功的建立。"
+
+#: src/net/ea/partyhandler.cpp:118
+#, c-format
+msgid "%s is already a member of a party."
+msgstr "%s 已經是隊伍的一員。"
+
+#: src/net/ea/partyhandler.cpp:122
+#, c-format
+msgid "%s refused your invitation."
+msgstr "%s 拒絕您的邀請。"
+
+#: src/net/ea/partyhandler.cpp:126
+#, c-format
+msgid "%s is now a member of your party."
+msgstr "%s 現在已經是您隊伍的成員。"
+
+#: src/net/ea/partyhandler.cpp:130
+#, c-format
+msgid "Unknown invite response for %s."
+msgstr "給 %s 的不明邀請回應。"
+
+#: src/net/ea/partyhandler.cpp:238
+msgid "You have left the party."
+msgstr "您已經離開此隊伍。"
+
+#: src/net/ea/partyhandler.cpp:249
+#, c-format
+msgid "%s has left your party."
+msgstr "%s 已經離開您的隊伍。"
+
+#: src/net/ea/partyhandler.cpp:301
+#, c-format
+msgid "An unknown member tried to say: %s"
+msgstr "不明的成員試著要說:%s"
+
+#: src/net/ea/partyhandler.cpp:329
+msgid "Inviting like this isn't supported at the moment."
+msgstr "此時無法支援邀請"
+
+#: src/net/ea/partyhandler.cpp:334
+msgid "You can only inivte when you are in a party!"
+msgstr ""
+
+#: src/net/ea/partyhandler.cpp:365
+#, c-format
+msgid "%s is not in your party!"
+msgstr "%s 不在您的隊伍中!"
+
+#: src/net/ea/playerhandler.cpp:99 src/net/manaserv/beinghandler.cpp:304
+msgid "You are dead."
+msgstr "您已經死亡。"
+
+#: src/net/ea/playerhandler.cpp:100 src/net/manaserv/beinghandler.cpp:305
+msgid "We regret to inform you that your character was killed in battle."
+msgstr "我們很遺憾的通知您,您的角色已經在戰鬥中被殺了。"
+
+#: src/net/ea/playerhandler.cpp:102 src/net/manaserv/beinghandler.cpp:307
+msgid "You are not that alive anymore."
+msgstr "您不再是那麼有活力。"
+
+#: src/net/ea/playerhandler.cpp:103 src/net/manaserv/beinghandler.cpp:308
+msgid "The cold hands of the grim reaper are grabbing for your soul."
+msgstr "殘酷的死神用冰冷的手正在抽出你的靈魂。"
+
+#: src/net/ea/playerhandler.cpp:104 src/net/manaserv/beinghandler.cpp:309
+msgid "Game Over!"
+msgstr "遊戲結束!"
+
+#: src/net/ea/playerhandler.cpp:105
+msgid "Insert coin to continue."
+msgstr "請投入金幣"
+
+#: src/net/ea/playerhandler.cpp:106 src/net/manaserv/beinghandler.cpp:310
+msgid ""
+"No, kids. Your character did not really die. It... err... went to a better "
+"place."
+msgstr "不,孩子。您的角色並沒有真的死掉。他...呃...去了更好的地方。"
+
+#: src/net/ea/playerhandler.cpp:108 src/net/manaserv/beinghandler.cpp:312
+msgid ""
+"Your plan of breaking your enemies weapon by bashing it with your throat "
+"failed."
+msgstr "您想讓敵人的武器插入您的喉嚨好折斷它的計畫失敗了。"
+
+#: src/net/ea/playerhandler.cpp:110 src/net/manaserv/beinghandler.cpp:314
+msgid "I guess this did not run too well."
+msgstr "我猜這並沒有跑得很好"
+
+#: src/net/ea/playerhandler.cpp:112 src/net/manaserv/beinghandler.cpp:315
+msgid "Do you want your possessions identified?"
+msgstr "您想要鑑定你的財產嗎?"
+
+#: src/net/ea/playerhandler.cpp:114 src/net/manaserv/beinghandler.cpp:316
+msgid "Sadly, no trace of you was ever found..."
+msgstr "很悲傷的,沒有人發現你的蹤跡..."
+
+#: src/net/ea/playerhandler.cpp:116 src/net/manaserv/beinghandler.cpp:317
+msgid "Annihilated."
+msgstr "灰飛煙滅了。"
+
+#: src/net/ea/playerhandler.cpp:118 src/net/manaserv/beinghandler.cpp:318
+msgid "Looks like you got your head handed to you."
+msgstr "看起來你把你的頭拿在手上。"
+
+#: src/net/ea/playerhandler.cpp:120 src/net/manaserv/beinghandler.cpp:319
+msgid ""
+"You screwed up again, dump your body down the tubes and get you another one."
+msgstr "你又被幹掉啦!!!躺在地上一次又一次!!"
+
+#: src/net/ea/playerhandler.cpp:123
+msgid "You're not dead yet. You're just resting."
+msgstr "您還沒有死。您現在只是在休息。"
+
+#: src/net/ea/playerhandler.cpp:124
+msgid "You are no more."
+msgstr "你已經沒有更多"
+
+#: src/net/ea/playerhandler.cpp:125
+msgid "You have ceased to be."
+msgstr "你已不再是."
+
+#: src/net/ea/playerhandler.cpp:126
+msgid "You've expired and gone to meet your maker."
+msgstr "你已經過期了,請求助管理員"
+
+#: src/net/ea/playerhandler.cpp:127
+msgid "You're a stiff."
+msgstr "身體僵硬"
+
+#: src/net/ea/playerhandler.cpp:128
+msgid "Bereft of life, you rest in peace."
+msgstr "失去了生命,您安詳的休息了。"
+
+#: src/net/ea/playerhandler.cpp:129
+msgid "If you weren't so animated, you'd be pushing up the daisies."
+msgstr "如果你沒有這樣做,你就不會上天堂了!!"
+
+#: src/net/ea/playerhandler.cpp:130
+msgid "Your metabolic processes are now history."
+msgstr "你的傳奇已經是過去式了!!"
+
+#: src/net/ea/playerhandler.cpp:131
+msgid "You're off the twig."
+msgstr "你折斷了樹枝"
+
+#: src/net/ea/playerhandler.cpp:132
+msgid "You've kicked the bucket."
+msgstr "你踢了水桶"
+
+#: src/net/ea/playerhandler.cpp:133
+msgid ""
+"You've shuffled off your mortal coil, run down the curtain and joined the "
+"bleedin' choir invisibile."
+msgstr "死掉了...."
+
+#: src/net/ea/playerhandler.cpp:135
+msgid "You are an ex-player."
+msgstr "您已是前-玩家。"
+
+#: src/net/ea/playerhandler.cpp:136
+msgid "You're pining for the fjords."
+msgstr "你正走向地獄!!"
+
+#: src/net/ea/playerhandler.cpp:249 src/net/ea/playerhandler.cpp:310
+msgid "Message"
+msgstr "訊息"
+
+#: src/net/ea/playerhandler.cpp:250
+msgid ""
+"You are carrying more than half your weight. You are unable to regain health."
+msgstr "您已經攜帶超過負重能力的一半。您將無法恢復生命。"
+
+#: src/net/ea/playerhandler.cpp:333
+#, fuzzy, c-format
+msgid "You picked up %s."
+msgstr "您已經撿起 "
+
+#: src/net/ea/playerhandler.cpp:369
+msgid "Cannot raise skill!"
+msgstr ""
+
+#: src/net/ea/playerhandler.cpp:532
+msgid "Equip arrows first."
+msgstr "先裝備箭."
+
+#: src/net/ea/specialhandler.cpp:147
+msgid "Trade failed!"
+msgstr "交易失敗!"
+
+#: src/net/ea/specialhandler.cpp:150
+msgid "Emote failed!"
+msgstr "顯示表情失敗!"
+
+#: src/net/ea/specialhandler.cpp:153
+msgid "Sit failed!"
+msgstr "坐下休息失敗!"
+
+#: src/net/ea/specialhandler.cpp:156
+msgid "Chat creating failed!"
+msgstr "聊天新增失敗!"
+
+#: src/net/ea/specialhandler.cpp:159
+msgid "Could not join party!"
+msgstr "不能加入隊伍!"
+
+#: src/net/ea/specialhandler.cpp:162
+msgid "Cannot shout!"
+msgstr "無法大叫!"
+
+#: src/net/ea/specialhandler.cpp:171
+msgid "You have not yet reached a high enough lvl!"
+msgstr "你還沒達到足夠等級!"
+
+#: src/net/ea/specialhandler.cpp:174
+msgid "Insufficient HP!"
+msgstr "HP不夠!"
+
+#: src/net/ea/specialhandler.cpp:177
+msgid "Insufficient SP!"
+msgstr "SP不夠!"
+
+#: src/net/ea/specialhandler.cpp:180
+msgid "You have no memos!"
+msgstr "沒有備忘錄"
+
+#: src/net/ea/specialhandler.cpp:183
+msgid "You cannot do that right now!"
+msgstr "您現在不能那麼做!"
+
+#: src/net/ea/specialhandler.cpp:186
+msgid "Seems you need more money... ;-)"
+msgstr "看來您需要更多錢... ;-)"
+
+#: src/net/ea/specialhandler.cpp:189
+msgid "You cannot use this skill with that kind of weapon!"
+msgstr "此武器無法使用此技能!"
+
+#: src/net/ea/specialhandler.cpp:192
+msgid "You need another red gem!"
+msgstr "你需要再一顆紅寶石!"
+
+#: src/net/ea/specialhandler.cpp:195
+msgid "You need another blue gem!"
+msgstr "你需要再一棵藍寶石!"
+
+#: src/net/ea/specialhandler.cpp:198
+msgid "You're carrying to much to do this!"
+msgstr "你已負重太多,不能再多!"
+
+#: src/net/ea/specialhandler.cpp:201
+msgid "Huh? What's that?"
+msgstr "阿?那是甚麼?"
+
+#: src/net/ea/specialhandler.cpp:210
+msgid "Warp failed..."
+msgstr "傳送失敗..."
+
+#: src/net/ea/specialhandler.cpp:213
+msgid "Could not steal anything..."
+msgstr "無法偷取任何物品..."
+
+#: src/net/ea/specialhandler.cpp:216
+msgid "Poison had no effect..."
+msgstr "藥水無效..."
+
+#: src/net/ea/tradehandler.cpp:107 src/net/manaserv/tradehandler.cpp:116
+msgid "Request for Trade"
+msgstr "要求交易"
+
+#: src/net/ea/tradehandler.cpp:108 src/net/manaserv/tradehandler.cpp:117
+#, c-format
+msgid "%s wants to trade with you, do you accept?"
+msgstr "%s 請求交易, 是否接受?"
+
+#: src/net/ea/tradehandler.cpp:124
+msgid "Trading isn't possible. Trade partner is too far away."
+msgstr "交易無法進行。交易對象太遠了。"
+
+#: src/net/ea/tradehandler.cpp:128
+msgid "Trading isn't possible. Character doesn't exist."
+msgstr "無法進行交易。該角色不存在。"
+
+#: src/net/ea/tradehandler.cpp:132
+msgid "Trade cancelled due to an unknown reason."
+msgstr "由於不明的原因已取消交易。"
+
+#: src/net/ea/tradehandler.cpp:137
+#, c-format
+msgid "Trade: You and %s"
+msgstr "交易: 你和 %s"
+
+#: src/net/ea/tradehandler.cpp:144
+#, c-format
+msgid "Trade with %s cancelled."
+msgstr "取消和 %s 的交易."
+
+#: src/net/ea/tradehandler.cpp:153
+msgid "Unhandled trade cancel packet."
+msgstr ""
+
+#: src/net/ea/tradehandler.cpp:202
+msgid "Failed adding item. Trade partner is over weighted."
+msgstr "加入物品失敗。交易的伙伴已經超重。"
+
+#: src/net/ea/tradehandler.cpp:207
+msgid "Failed adding item. Trade partner has no free slot."
+msgstr "加入物品失敗。交易對象沒有空的欄位。"
+
+#: src/net/ea/tradehandler.cpp:211
+msgid "Failed adding item for unknown reason."
+msgstr "由於不明的原因加入物品失敗。"
+
+#: src/net/ea/tradehandler.cpp:224 src/net/manaserv/tradehandler.cpp:149
+msgid "Trade canceled."
+msgstr "交易已取消。"
+
+#: src/net/ea/tradehandler.cpp:231 src/net/manaserv/tradehandler.cpp:156
+msgid "Trade completed."
+msgstr "交易已完成。"
+
+#: src/net/manaserv/beinghandler.cpp:324
+#, fuzzy
+msgid "Press OK to respawn."
+msgstr " 請按確認啟動"
+
+#: src/net/manaserv/beinghandler.cpp:325
+#, fuzzy
+msgid "You Died"
+msgstr "您已經死亡"
+
+#: src/net/manaserv/charhandler.cpp:128 src/net/manaserv/charhandler.cpp:196
+#, fuzzy
+msgid "Not logged in."
+msgstr "已經登入"
+
+#: src/net/manaserv/charhandler.cpp:131
+msgid "No empty slot."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:134
+msgid "Invalid name."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:137
+#, fuzzy
+msgid "Character's name already exists."
+msgstr "名字已經有人使用"
+
+#: src/net/manaserv/charhandler.cpp:140
+msgid "Invalid hairstyle."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:143
+msgid "Invalid hair color."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:146
+msgid "Invalid gender."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:149
+#, fuzzy
+msgid "Character's stats are too high."
+msgstr "角色狀態確定"
+
+#: src/net/manaserv/charhandler.cpp:152
+#, fuzzy
+msgid "Character's stats are too low."
+msgstr "角色狀態確定"
+
+#: src/net/manaserv/charhandler.cpp:155
+msgid "One stat is zero."
+msgstr ""
+
+#: src/net/manaserv/charhandler.cpp:187
+#, fuzzy
+msgid "Player deleted."
+msgstr "玩家已刪除"
+
+#: src/net/manaserv/charhandler.cpp:199
+#, fuzzy
+msgid "Selection out of range."
+msgstr "請選擇交易的物品數量"
+
+#: src/net/manaserv/charhandler.cpp:202
+#, fuzzy, c-format
+msgid "Unknown error (%d)."
+msgstr "不明的錯誤"
+
+#: src/net/manaserv/charhandler.cpp:242
+msgid "No gameservers are available."
+msgstr "沒有可用的遊戲伺服器。"
+
+#: src/net/manaserv/charhandler.cpp:268
+msgid "Willpower:"
+msgstr "意志力:"
+
+#: src/net/manaserv/chathandler.cpp:180 src/net/manaserv/chathandler.cpp:301
+#: src/net/manaserv/guildhandler.cpp:259
+#, c-format
+msgid "Topic: %s"
+msgstr "主題: %s"
+
+#: src/net/manaserv/chathandler.cpp:184 src/net/manaserv/chathandler.cpp:262
+#, fuzzy
+msgid "Players in this channel:"
+msgstr "玩家攻擊怪物"
+
+#: src/net/manaserv/chathandler.cpp:201
+#, fuzzy
+msgid "Error joining channel."
+msgstr "指令: /join <頻道名稱>"
+
+#: src/net/manaserv/chathandler.cpp:207
+#, fuzzy
+msgid "Listing channels."
+msgstr "要求參加頻道 %s"
+
+#: src/net/manaserv/chathandler.cpp:219
+msgid "End of channel list."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:291
+#, fuzzy, c-format
+msgid "%s entered the channel."
+msgstr "%s 參加了這個派對."
+
+#: src/net/manaserv/chathandler.cpp:296
+#, c-format
+msgid "%s left the channel."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:312
+#, c-format
+msgid "%s has set mode %s on user %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:322
+#, c-format
+msgid "%s has kicked %s."
+msgstr ""
+
+#: src/net/manaserv/chathandler.cpp:327
+#, fuzzy
+msgid "Unknown channel event."
+msgstr "不明指令"
+
+#: src/net/manaserv/generalhandler.cpp:100
+#, c-format
+msgid "Willpower %+d"
+msgstr "意志力 %+d"
+
+#: src/net/manaserv/generalhandler.cpp:171
+#, fuzzy
+msgid "Willpower"
+msgstr "意志力:"
+
+#: src/net/manaserv/guildhandler.cpp:81
+msgid "Guild created."
+msgstr "公會已成立."
+
+#: src/net/manaserv/guildhandler.cpp:86
+msgid "Error creating guild."
+msgstr "創建公會時發生錯誤."
+
+#: src/net/manaserv/guildhandler.cpp:96
+msgid "Invite sent."
+msgstr "發出邀請."
+
+#: src/net/manaserv/guildhandler.cpp:203
+msgid "Member was promoted successfully."
+msgstr "成功提升會員."
+
+#: src/net/manaserv/guildhandler.cpp:208
+msgid "Failed to promote member."
+msgstr "無法提升會員."
+
+#: src/net/manaserv/loginhandler.cpp:87
+#, fuzzy
+msgid "Wrong magic_token."
+msgstr "錯誤的魔法代號"
+
+#: src/net/manaserv/loginhandler.cpp:90 src/net/manaserv/loginhandler.cpp:269
+#, fuzzy
+msgid "Already logged in."
+msgstr "已經登入"
+
+#: src/net/manaserv/loginhandler.cpp:93 src/net/manaserv/loginhandler.cpp:272
+#, fuzzy
+msgid "Server is full."
+msgstr "伺服器人數已滿"
+
+#: src/net/manaserv/loginhandler.cpp:118
+#, fuzzy
+msgid "New password incorrect."
+msgstr "新密碼不正確"
+
+#: src/net/manaserv/loginhandler.cpp:124 src/net/manaserv/loginhandler.cpp:155
+msgid "Account not connected. Please login first."
+msgstr "帳號還沒連線,請先登入"
+
+#: src/net/manaserv/loginhandler.cpp:149
+#, fuzzy
+msgid "New email address incorrect."
+msgstr "新的郵件位址不正確"
+
+#: src/net/manaserv/loginhandler.cpp:152
+#, fuzzy
+msgid "Old email address incorrect."
+msgstr "舊得郵件位址不正確"
+
+#: src/net/manaserv/loginhandler.cpp:158
+#, fuzzy
+msgid "The new email address already exists."
+msgstr "電子郵件已經被註冊"
+
+#: src/net/manaserv/loginhandler.cpp:239
+msgid ""
+"Client registration is not allowed. Please contact server administration."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:263 src/net/manaserv/loginhandler.cpp:300
+#, fuzzy
+msgid "Client version is too old."
+msgstr "遊戲版本太老舊!!"
+
+#: src/net/manaserv/loginhandler.cpp:266
+#, fuzzy
+msgid "Wrong username or password."
+msgstr "錯誤的帳號或密碼"
+
+#: src/net/manaserv/loginhandler.cpp:275
+msgid "Login attempt too soon after previous attempt."
+msgstr ""
+
+#: src/net/manaserv/loginhandler.cpp:303
+#, fuzzy
+msgid "Wrong username, password or email address."
+msgstr "錯誤的帳號或密碼及電子郵件"
+
+#: src/net/manaserv/loginhandler.cpp:306
+#, fuzzy
+msgid "Username already exists."
+msgstr "名字已經有人使用"
+
+#: src/net/manaserv/loginhandler.cpp:309
+#, fuzzy
+msgid "Email address already exists."
+msgstr "電子郵件已經存在"
+
+#: src/net/manaserv/loginhandler.cpp:312
+msgid "You took too long with the captcha or your response was incorrect."
+msgstr ""
+
+#: src/net/manaserv/partyhandler.cpp:88
+msgid "Joined party."
+msgstr "參加派對."
+
+#: src/net/manaserv/partyhandler.cpp:106
+#, c-format
+msgid "%s joined the party."
+msgstr "%s 參加了這個派對."
+
+#: src/net/manaserv/partyhandler.cpp:123
+#, fuzzy, c-format
+msgid "%s rejected your invite."
+msgstr "%s 拒絕您的邀請。"
+
+#: src/net/manaserv/tradehandler.cpp:96
+msgid "Accepting incoming trade requests."
+msgstr "接受傳入的交易要求."
+
+#: src/net/manaserv/tradehandler.cpp:98
+msgid "Ignoring incoming trade requests."
+msgstr "拒絕傳入的交易要求."
+
+#: src/net/manaserv/tradehandler.cpp:135
+#, c-format
+msgid "Trading with %s"
+msgstr "與 %s 交易."
+
+#: src/playerrelations.cpp:304
+#, fuzzy
+msgid "Completely ignore"
+msgstr "@@ignore|完全忽視 %s@@"
+
+#: src/playerrelations.cpp:318
+msgid "Print '...'"
+msgstr ""
+
+#: src/playerrelations.cpp:334
+msgid "Blink name"
+msgstr ""
+
+#: src/playerrelations.cpp:371
+msgid "Floating '...' bubble"
+msgstr ""
+
+#: src/playerrelations.cpp:374
+msgid "Floating bubble"
+msgstr ""
+
+#: src/resources/itemdb.cpp:52
+#, c-format
+msgid "Attack %+d"
+msgstr "攻擊 %+d"
+
+#: src/resources/itemdb.cpp:53
+#, c-format
+msgid "Defense %+d"
+msgstr "防禦 %+d"
+
+#: src/resources/itemdb.cpp:54
+#, c-format
+msgid "HP %+d"
+msgstr "體力%+d"
+
+#: src/resources/itemdb.cpp:55
+#, c-format
+msgid "MP %+d"
+msgstr "魔力%+d"
+
+#: src/resources/itemdb.cpp:114
+msgid "Unknown item"
+msgstr "不明的物品"
+
+#: src/resources/itemdb.cpp:158 src/resources/monsterdb.cpp:45
+#: src/resources/monsterdb.cpp:67
+msgid "unnamed"
+msgstr "未知物品"
+
+#~ msgid "no"
+#~ msgstr "否"
+
+#~ msgid "Buddy"
+#~ msgstr "好友"
+
+#~ msgid "Buddy List"
+#~ msgstr "好友清單"
+
+#~ msgid "Description: %s"
+#~ msgstr "說明:%s"
+
+#~ msgid "Effect: %s"
+#~ msgstr "效果:%s"
+
+#~ msgid "Previous"
+#~ msgstr "上一個"
+
+#~ msgid "New"
+#~ msgstr "新增"
+
+#~ msgid "Job Level: %d"
+#~ msgstr "職業等級:%d"
+
+#~ msgid "Present: "
+#~ msgstr "上線: "
+
+#~ msgid "Quit Guild"
+#~ msgstr "離開公會"
+
+#~ msgid "Ok"
+#~ msgstr "確認"
+
+#~ msgid "Recent:"
+#~ msgstr "記錄的:"
+
+#~ msgid "Magic"
+#~ msgstr "魔法"
+
+#~ msgid "Cast Test Spell 1"
+#~ msgstr "施展測試咒文 1"
+
+#~ msgid "Cast Test Spell 2"
+#~ msgstr "施展測試咒文 2"
+
+#~ msgid "Cast Test Spell 3"
+#~ msgstr "施展測試咒文 3"
+
+#~ msgid "2 Handed Weapons"
+#~ msgstr "雙手武器"
+
+#~ msgid "@@trade|Trade With %s@@"
+#~ msgstr "@@交易|與%s交易@@"
+
+#~ msgid "@@attack|Attack %s@@"
+#~ msgstr "@@攻擊|攻擊%s@@"
+
+#~ msgid "@@disregard|Disregard %s@@"
+#~ msgstr "@@disregard|無視 %s@@"
+
+#~ msgid "@@ignore|Ignore %s@@"
+#~ msgstr "@@ignore| 忽視 %s@@"
+
+#~ msgid "@@unignore|Un-Ignore %s@@"
+#~ msgstr "@@unignore| 不忽視 %s@@"
+
+#~ msgid "@@admin-kick|Kick player@@"
+#~ msgstr "@@admin-kick|踢掉玩家@@"
+
+#~ msgid "@@cancel|Cancel@@"
+#~ msgstr "@@取消|取消@@"
+
+#~ msgid "@@pickup|Pick up %s@@"
+#~ msgstr "@@pickup|撿起 %s @@"
+
+#~ msgid "@@use|Unequip@@"
+#~ msgstr "@@使用|卸下@@"
+
+#~ msgid "@@use|Equip@@"
+#~ msgstr "@@使用|裝備@@"
+
+#~ msgid "@@use|Use@@"
+#~ msgstr "@@使用|使用@@"
+
+#~ msgid "@@drop|Drop@@"
+#~ msgstr "@@丟棄|丟棄@@"
+
+#~ msgid "@@split|Split@@"
+#~ msgstr "@@分離|分離@@"
+
+#~ msgid "@@store|Store@@"
+#~ msgstr "@@store|儲存@@"
+
+#~ msgid "@@retrieve|Retrieve@@"
+#~ msgstr "@@retrieve|檢索@@"
+
+#~ msgid "Select Server"
+#~ msgstr "選擇伺服器"
+
+#~ msgid "Failed to switch to "
+#~ msgstr "無法切換到 "
+
+#~ msgid "windowed"
+#~ msgstr "視窗化"
+
+#~ msgid "fullscreen"
+#~ msgstr "全螢幕"
+
+#~ msgid "Mystery Skill"
+#~ msgstr "神秘技能"
+
+#~ msgid "Weapons"
+#~ msgstr "武器"
+
+#~ msgid "Crafts"
+#~ msgstr "工藝品"
+
+#~ msgid "Stats"
+#~ msgstr "狀態"
+
+#~ msgid "Total"
+#~ msgstr "總共"
+
+#~ msgid "Cost"
+#~ msgstr "需求"
+
+#~ msgid "Attack:"
+#~ msgstr "攻擊:"
+
+#~ msgid "% Reflex:"
+#~ msgstr "% 傷害反射:"
+
+#~ msgid "Remaining Status Points: %d"
+#~ msgstr "剩餘狀態點數:%d"
+
+#~ msgid "Max level"
+#~ msgstr "最大等級"
+
+#~ msgid "curl error "
+#~ msgstr "curl 錯誤 "
+
+#~ msgid " host: "
+#~ msgstr " 主機: "
+
+#~ msgid "Guilds"
+#~ msgstr "公會"
+
+#~ msgid "Buddys"
+#~ msgstr "好友"
+
+#~ msgid "Party Window"
+#~ msgstr "隊伍視窗"
+
+#~ msgid "Unarmed"
+#~ msgstr "未命名"
+
+#~ msgid "Knife"
+#~ msgstr "小刀"
+
+#~ msgid "Sword"
+#~ msgstr "劍"
+
+#~ msgid "Polearm"
+#~ msgstr "長戰斧"
+
+#~ msgid "Staff"
+#~ msgstr "杖"
+
+#~ msgid "Whip"
+#~ msgstr "鞭子"
+
+#~ msgid "Bow"
+#~ msgstr "弓"
+
+#~ msgid "Shooting"
+#~ msgstr "射擊"
+
+#~ msgid "Mace"
+#~ msgstr "錘"
+
+#~ msgid "Axe"
+#~ msgstr "斧"
+
+#~ msgid "Thrown"
+#~ msgstr "投擲"
+
+#~ msgid "Craft"
+#~ msgstr "工藝品"
+
+#~ msgid "Unknown Skill"
+#~ msgstr "不明的技能"
+
+#~ msgid " can't be created, but it doesn't exist! Exiting."
+#~ msgstr " 不能建立,但是它也不存在!現在結束。"
+
+#~ msgid "Couldn't set "
+#~ msgstr "無法設定 "
+
+#~ msgid " video mode: "
+#~ msgstr " 視訊模式: "
+
+#~ msgid "mana"
+#~ msgstr "mana"
+
+#~ msgid "Connecting to character server..."
+#~ msgstr "正在連接角色伺服器..."
+
+#~ msgid "Connecting to account server..."
+#~ msgstr "正在連接帳號伺服器..."
+
+#~ msgid "/new > Alias of create"
+#~ msgstr "/new > 效果同 create 指令"
+
+#~ msgid "Command: /new <party-name>"
+#~ msgstr "指令: /new <隊伍名稱>"
+
+#~ msgid "a"
+#~ msgstr "一個"
+
+#~ msgid "Unnamed"
+#~ msgstr "未知物品"
+
+#~ msgid "Gold: %d"
+#~ msgstr "金幣:%d"
+
+#~ msgid "%s whispers:"
+#~ msgstr "%s悄悄密你說:"
+
+#~ msgid "Unknown command"
+#~ msgstr "不明指令"
+
+#~ msgid "Seems you need more Zeny... ;-)"
+#~ msgstr "你需要更多錢錢……;-)"
+
+#~ msgid "/announce: Global announcement (GM only)"
+#~ msgstr "/announce: 伺服公告(只有GM可使用)"
+
+#~ msgid "/clear: Clears this window"
+#~ msgstr "/clear: 清除視窗"
+
+#~ msgid "/help: Display this help"
+#~ msgstr "/help: 顯示幫助訊息"
+
+#~ msgid "/where: Display map name"
+#~ msgstr "/where: 顯示地圖名稱"
+
+#~ msgid "/whisper <nick> <message>: Sends a private <message> to <nick>"
+#~ msgstr "/whisper <暱稱> <密語>: 發送一條私密訊息 <訊息> 給 <暱稱>"
+
+#~ msgid "/w <nick> <message>: Short form for /whisper"
+#~ msgstr "/w <暱稱> <信息>: /whisper的縮寫形式"
+
+#~ msgid "/who: Display number of online users"
+#~ msgstr "/who: 顯示線上人數"
+
+#~ msgid "Command: /whisper <nick> <msg>"
+#~ msgstr "指令: /whisper <暱稱> <信息>"
+
+#~ msgid "Command: /w <nick> <msg>"
+#~ msgstr "指令: /w <暱稱> <信息>"
+
+#~ msgid "This command sends the message <msg> to <nick>."
+#~ msgstr "這個指令發送訊息 <msg> 給 <nick>"
+
+#~ msgid "Weight: %d / %d"
+#~ msgstr "負重:%d / %d"
+
+#~ msgid "Slots used: %d / %d"
+#~ msgstr "已使用攔: %d / %d"
+
+#~ msgid "@@pickup|Pick Up %s@@"
+#~ msgstr "@@撿起|撿起%s@@"
+
+#~ msgid "Save player list"
+#~ msgstr "保存玩家列表"
+
+#~ msgid "Scroll radius"
+#~ msgstr "捲動半徑"
+
+#~ msgid "Scroll laziness"
+#~ msgstr "捲動延遲"
+
+#~ msgid "Money: %d GP"
+#~ msgstr "金錢:%d 金錢"
+
+#~ msgid "Confirm"
+#~ msgstr "確認"
+
+#~ msgid "Charisma:"
+#~ msgstr "魅力:"
+
+#~ msgid "Total Weight: %d - Maximum Weight: %d"
+#~ msgstr "目前的負責:%d - 最大負重:%d"
+
+#~ msgid "Keep"
+#~ msgstr "保持"
+
+#~ msgid "monsters.xml"
+#~ msgstr "monsters.xml"
+
+#~ msgid "items.xml"
+#~ msgstr "items.xml"
+
+#~ msgid " cancelled"
+#~ msgstr " 已取消"
+
+#~ msgid "Emote"
+#~ msgstr "表情"
+
+#~ msgid ""
+#~ "\n"
+#~ "> Cancel\n"
+#~ msgstr ""
+#~ "\n"
+#~ "> 取消\n"
+
+#~ msgid "Other Player's Names"
+#~ msgstr "其他玩家的名字"
+
+#~ msgid "Shirt"
+#~ msgstr "襯衫"
+
+#~ msgid "Usable"
+#~ msgstr "可使用"
+
+#~ msgid "Hat"
+#~ msgstr "帽子"
+
+#~ msgid "Ring"
+#~ msgstr "指環"
+
+#~ msgid "Necklace"
+#~ msgstr "項鍊"
+
+#~ msgid "Shield"
+#~ msgstr "盾牌"
+
+#~ msgid "skills.xml"
+#~ msgstr "skills.xml"
+
+#~ msgid "use"
+#~ msgstr "使用"
+
+#~ msgid "%s: %s"
+#~ msgstr "%s: %s"
+
+#~ msgid "Emote Window"
+#~ msgstr "表情視窗"
+
+#~ msgid "Options: "
+#~ msgstr "選項: "
+
+#~ msgid " -h --help : Display this help"
+#~ msgstr " -h --help : 顯示這個說明"
+
+#~ msgid " -D --default : Bypass the login process with default settings"
+#~ msgstr " -D --default : 以預設的設定值跳過登入程序"
+
+#~ msgid " -d --data : Directory to load game data from"
+#~ msgstr " -d --data : 用來載入遊戲資料的目錄"
+
+#~ msgid " -C --configfile : Configuration file to use"
+#~ msgstr " -C --configfile : 要使用的組態檔案"
+
+#~ msgid " -u --skipupdate : Skip the update downloads"
+#~ msgstr " -u --skipupdate : 略過更新的下載"
+
+#~ msgid " -v --version : Display the version"
+#~ msgstr " -v --version : 顯示版本"
+
+#~ msgid " -o --port : Login Server Port"
+#~ msgstr " -o --port : 登入伺服器連接埠"
+
+#~ msgid " -c --character : Login with this character"
+#~ msgstr " -c --character : 以這個角色登入"
+
+#~ msgid " -s --server : Login Server name or IP"
+#~ msgstr " -s --server : 登入伺服器名稱或 IP"
+
+#~ msgid " -H --updatehost : Use this update host"
+#~ msgstr " -H --updatehost : 使用這個更新主機"
+
+#~ msgid " -S --homedir : Directory to use as home directory"
+#~ msgstr " -S --homedir : 做為家目錄的目錄"
+
+#~ msgid " -P --password : Login with this password"
+#~ msgstr " -P --password : 以這個密碼登入"
+
+#~ msgid " -U --username : Login with this username"
+#~ msgstr " -U --username : 以這個使用者名稱登入"
+
+#~ msgid "Luck: %d"
+#~ msgstr "幸運: %d"
+
+#~ msgid "Intelligence: %d"
+#~ msgstr "智力: %d"
+
+#~ msgid "Strength: %d"
+#~ msgstr "力量: %d"
+
+#~ msgid "You picked up %s [%s]"
+#~ msgstr "您已經撿起 %s [%s]"
+
+#~ msgid "NPC Text Request"
+#~ msgstr "NPC 文字要求"
+
+#~ msgid "Insert coin to continue"
+#~ msgstr "投入硬幣接關"
+
+#~ msgid "Willpower: %d"
+#~ msgstr "意志力: %d"
+
+#~ msgid "Cannont send empty whispers!"
+#~ msgstr "不能送出空的悄悄話!"
+
+#~ msgid ""
+#~ "Cannont create a whisper tab for nick '%s'!It either already exists, or "
+#~ "is you."
+#~ msgstr "不能建立 nick 「%s」的悄悄話分頁!它已經存在,或者對象是你自己。"
+
+#~ msgid "Generic"
+#~ msgstr "一般"
+
+#~ msgid "Slots: "
+#~ msgstr "欄位: "
+
+#~ msgid "Agility: %d"
+#~ msgstr "敏捷: %d"
+
+#~ msgid "Dexterity: %d"
+#~ msgstr "閃躲: %d"
+
+#~ msgid "Unable to load selection.png"
+#~ msgstr "無法讀取所選擇png圖檔"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 000000000..bb7b6e4b2
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,723 @@
+FIND_PACKAGE(SDL REQUIRED)
+FIND_PACKAGE(SDL_image REQUIRED)
+FIND_PACKAGE(SDL_mixer REQUIRED)
+FIND_PACKAGE(SDL_net REQUIRED)
+FIND_PACKAGE(SDL_ttf REQUIRED)
+FIND_PACKAGE(SDL_gfx REQUIRED)
+FIND_PACKAGE(CURL REQUIRED)
+FIND_PACKAGE(LibXml2 REQUIRED)
+FIND_PACKAGE(PhysFS REQUIRED)
+FIND_PACKAGE(PNG REQUIRED)
+FIND_PACKAGE(Gettext REQUIRED)
+
+IF (CMAKE_COMPILER_IS_GNUCXX)
+ # Help getting compilation warnings
+ SET(CMAKE_CXX_FLAGS "-Wall")
+ IF (WIN32)
+ # This includes enough debug information to get something useful
+ # from Dr. Mingw while keeping binary size down. Almost useless
+ # with gdb, though.
+ SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb0 -gstabs2")
+ ENDIF()
+ENDIF()
+
+IF (POLICY CMP0015)
+ CMAKE_POLICY(SET CMP0015 OLD)
+ENDIF()
+
+SET(FLAGS "-DPACKAGE_VERSION=\\\"${VERSION}\\\"")
+SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${PKG_DATADIR}/\\\"")
+SET(FLAGS "${FLAGS} -DLOCALEDIR=\\\"${LOCALEDIR}/\\\"")
+
+IF (ENABLE_NLS)
+ SET(FLAGS "${FLAGS} -DENABLE_NLS=1")
+ENDIF()
+
+IF (CMAKE_BUILD_TYPE)
+ STRING(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TOLOWER)
+ IF(CMAKE_BUILD_TYPE_TOLOWER MATCHES debug OR
+ CMAKE_BUILD_TYPE_TOLOWER MATCHES relwithdebinfo)
+ SET(FLAGS "${FLAGS} -DDEBUG")
+ ENDIF()
+ENDIF()
+
+IF (WIN32)
+ SET(EXTRA_LIBRARIES ws2_32 winmm)
+ FIND_PACKAGE(LibIntl REQUIRED)
+ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ FIND_PACKAGE(LibIntl REQUIRED)
+ELSEIF (CMAKE_SYSTEM_NAME STREQUAL SunOS)
+ # explicit linking to libintl is required on Solaris
+ SET(EXTRA_LIBRARIES intl)
+ENDIF()
+
+SET(GUICHAN_COMPONENTS "SDL")
+FIND_PACKAGE(Guichan REQUIRED ${GUICHAN_COMPONENTS})
+
+IF (WITH_OPENGL)
+ FIND_PACKAGE(OpenGL REQUIRED)
+ INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
+ SET(FLAGS "${FLAGS} -DUSE_OPENGL")
+ENDIF (WITH_OPENGL)
+
+IF (USE_X11)
+ FIND_PACKAGE(X11 REQUIRED)
+ INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
+ SET(FLAGS "${FLAGS} -DUSE_X11")
+ENDIF (USE_X11)
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${SDL_INCLUDE_DIR}
+ ${SDLIMAGE_INCLUDE_DIR}
+ ${SDLMIXER_INCLUDE_DIR}
+ ${SDLNET_INCLUDE_DIR}
+ ${SDLTTF_INCLUDE_DIR}
+ ${SDLGFX_INCLUDE_DIR}
+ ${PNG_INCLUDE_DIR}
+ ${PHYSFS_INCLUDE_DIR}
+ ${CURL_INCLUDE_DIR}
+ ${LIBXML2_INCLUDE_DIR}
+ ${GUICHAN_INCLUDE_DIR}
+ )
+
+# enable rc-handling with mingw
+# most likely this part can be kicked out with some later cmake version
+IF (MINGW)
+ FIND_PATH(MINGW_INCLUDE_DIR windows.h $ENV{INCLUDE})
+ IF (MINGW_INCLUDE_DIR)
+ MESSAGE(STATUS "Found mingw headers: ${MINGW_INCLUDE_DIR}")
+ INCLUDE_DIRECTORIES(${MINGW_INCLUDE_DIR})
+ ELSE()
+ MESSAGE(FATAL_ERROR "Unable to find mingw headers. Required for windres")
+ ENDIF()
+ SET(CMAKE_RC_COMPILER_INIT windres)
+ ENABLE_LANGUAGE(RC)
+ SET(CMAKE_RC_COMPILE_OBJECT
+ "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -O coff -o <OBJECT> <SOURCE>")
+ENDIF()
+
+# Fix some stuff that gets not hidden by mainline modules
+MARK_AS_ADVANCED(PHYSFS_INCLUDE_DIR)
+MARK_AS_ADVANCED(PHYSFS_LIBRARY)
+MARK_AS_ADVANCED(SDLIMAGE_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDLIMAGE_LIBRARY)
+MARK_AS_ADVANCED(SDLMAIN_LIBRARY)
+MARK_AS_ADVANCED(SDLMIXER_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDLMIXER_LIBRARY)
+MARK_AS_ADVANCED(SDLNET_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDLNET_LIBRARY)
+MARK_AS_ADVANCED(SDL_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDL_LIBRARY)
+
+SET(SRCS
+ enet/callbacks.c
+ enet/callbacks.h
+ enet/compress.c
+ enet/enet.h
+ enet/host.c
+ enet/list.c
+ enet/list.h
+ enet/packet.c
+ enet/peer.c
+ enet/protocol.c
+ enet/protocol.h
+ enet/time.h
+ enet/types.h
+ enet/unix.c
+ enet/unix.h
+ enet/utility.h
+ enet/win32.c
+ enet/win32.h
+ gui/widgets/avatarlistbox.cpp
+ gui/widgets/avatarlistbox.h
+ gui/widgets/battletab.cpp
+ gui/widgets/battletab.h
+ gui/widgets/browserbox.cpp
+ gui/widgets/browserbox.h
+ gui/widgets/button.cpp
+ gui/widgets/button.h
+ gui/widgets/channeltab.cpp
+ gui/widgets/channeltab.h
+ gui/widgets/chattab.cpp
+ gui/widgets/chattab.h
+ gui/widgets/checkbox.cpp
+ gui/widgets/checkbox.h
+ gui/widgets/container.cpp
+ gui/widgets/container.h
+ gui/widgets/desktop.cpp
+ gui/widgets/desktop.h
+ gui/widgets/dropdown.cpp
+ gui/widgets/dropdown.h
+ gui/widgets/emoteshortcutcontainer.cpp
+ gui/widgets/emoteshortcutcontainer.h
+ gui/widgets/flowcontainer.cpp
+ gui/widgets/flowcontainer.h
+ gui/widgets/icon.cpp
+ gui/widgets/icon.h
+ gui/widgets/inttextfield.cpp
+ gui/widgets/inttextfield.h
+ gui/widgets/itemcontainer.cpp
+ gui/widgets/itemcontainer.h
+ gui/widgets/itemlinkhandler.cpp
+ gui/widgets/itemlinkhandler.h
+ gui/widgets/dropshortcutcontainer.cpp
+ gui/widgets/dropshortcutcontainer.h
+ gui/widgets/itemshortcutcontainer.cpp
+ gui/widgets/itemshortcutcontainer.h
+ gui/widgets/spellshortcutcontainer.cpp
+ gui/widgets/spellshortcutcontainer.h
+ gui/widgets/label.cpp
+ gui/widgets/label.h
+ gui/widgets/layout.cpp
+ gui/widgets/layout.h
+ gui/widgets/layouthelper.cpp
+ gui/widgets/layouthelper.h
+ gui/widgets/linkhandler.h
+ gui/widgets/listbox.cpp
+ gui/widgets/listbox.h
+ gui/widgets/passwordfield.cpp
+ gui/widgets/passwordfield.h
+ gui/widgets/playerbox.cpp
+ gui/widgets/playerbox.h
+ gui/widgets/popup.cpp
+ gui/widgets/popup.h
+ gui/widgets/progressbar.cpp
+ gui/widgets/progressbar.h
+ gui/widgets/progressindicator.cpp
+ gui/widgets/progressindicator.h
+ gui/widgets/radiobutton.cpp
+ gui/widgets/radiobutton.h
+ gui/widgets/resizegrip.cpp
+ gui/widgets/resizegrip.h
+ gui/widgets/scrollarea.cpp
+ gui/widgets/scrollarea.h
+ gui/widgets/setuptab.cpp
+ gui/widgets/setuptab.h
+ gui/widgets/shopitems.cpp
+ gui/widgets/shopitems.h
+ gui/widgets/shoplistbox.cpp
+ gui/widgets/shoplistbox.h
+ gui/widgets/shortcutcontainer.cpp
+ gui/widgets/shortcutcontainer.h
+ gui/widgets/slider.cpp
+ gui/widgets/slider.h
+ gui/widgets/tab.cpp
+ gui/widgets/tab.h
+ gui/widgets/tabbedarea.cpp
+ gui/widgets/tabbedarea.h
+ gui/widgets/table.cpp
+ gui/widgets/table.h
+ gui/widgets/tablemodel.cpp
+ gui/widgets/tablemodel.h
+ gui/widgets/textbox.cpp
+ gui/widgets/textbox.h
+ gui/widgets/textfield.cpp
+ gui/widgets/textfield.h
+ gui/widgets/textpreview.cpp
+ gui/widgets/textpreview.h
+ gui/widgets/tradetab.cpp
+ gui/widgets/tradetab.h
+ gui/widgets/vertcontainer.cpp
+ gui/widgets/vertcontainer.h
+ gui/widgets/whispertab.cpp
+ gui/widgets/whispertab.h
+ gui/widgets/window.cpp
+ gui/widgets/window.h
+ gui/widgets/windowcontainer.cpp
+ gui/widgets/windowcontainer.h
+ gui/beingpopup.cpp
+ gui/beingpopup.h
+ gui/buy.cpp
+ gui/buy.h
+ gui/buysell.cpp
+ gui/buysell.h
+ gui/changeemaildialog.cpp
+ gui/changeemaildialog.h
+ gui/changepassworddialog.cpp
+ gui/changepassworddialog.h
+ gui/charselectdialog.cpp
+ gui/charselectdialog.h
+ gui/charcreatedialog.cpp
+ gui/charcreatedialog.h
+ gui/chat.cpp
+ gui/chat.h
+ gui/confirmdialog.cpp
+ gui/confirmdialog.h
+ gui/connectiondialog.cpp
+ gui/connectiondialog.h
+ gui/debugwindow.cpp
+ gui/debugwindow.h
+ gui/emotepopup.cpp
+ gui/emotepopup.h
+ gui/equipmentwindow.cpp
+ gui/equipmentwindow.h
+ gui/focushandler.cpp
+ gui/focushandler.h
+ gui/gui.cpp
+ gui/gui.h
+ gui/help.cpp
+ gui/help.h
+ gui/inventorywindow.cpp
+ gui/inventorywindow.h
+ gui/itempopup.cpp
+ gui/itempopup.h
+ gui/spellpopup.cpp
+ gui/spellpopup.h
+ gui/statuspopup.cpp
+ gui/statuspopup.h
+ gui/killstats.cpp
+ gui/killstats.h
+ gui/itemamount.cpp
+ gui/itemamount.h
+ gui/login.cpp
+ gui/login.h
+ gui/minimap.cpp
+ gui/minimap.h
+ gui/ministatus.cpp
+ gui/ministatus.h
+ gui/npcdialog.cpp
+ gui/npcdialog.h
+ gui/npcpostdialog.cpp
+ gui/npcpostdialog.h
+ gui/okdialog.cpp
+ gui/okdialog.h
+ gui/editdialog.cpp
+ gui/editdialog.h
+ gui/outfitwindow.cpp
+ gui/outfitwindow.h
+ gui/botcheckerwindow.cpp
+ gui/botcheckerwindow.h
+ gui/textcommandeditor.cpp
+ gui/textcommandeditor.h
+ gui/palette.cpp
+ gui/palette.h
+ gui/popupmenu.cpp
+ gui/popupmenu.h
+ gui/quitdialog.cpp
+ gui/quitdialog.h
+ gui/register.cpp
+ gui/register.h
+ gui/sdlinput.cpp
+ gui/sdlinput.h
+ gui/sell.cpp
+ gui/sell.h
+ gui/serverdialog.cpp
+ gui/serverdialog.h
+ gui/setup.cpp
+ gui/setup.h
+ gui/setup_audio.cpp
+ gui/setup_audio.h
+ gui/setup_colors.cpp
+ gui/setup_colors.h
+ gui/setup_joystick.cpp
+ gui/setup_joystick.h
+ gui/setup_other.cpp
+ gui/setup_other.h
+ gui/setup_theme.cpp
+ gui/setup_theme.h
+ gui/setup_chat.cpp
+ gui/setup_chat.h
+ gui/setup_keyboard.cpp
+ gui/setup_keyboard.h
+ gui/setup_players.cpp
+ gui/setup_players.h
+ gui/setup_video.cpp
+ gui/setup_video.h
+ gui/shopwindow.cpp
+ gui/shopwindow.h
+ gui/shortcutwindow.cpp
+ gui/shortcutwindow.h
+ gui/skilldialog.cpp
+ gui/skilldialog.h
+ gui/socialwindow.cpp
+ gui/socialwindow.h
+ gui/speechbubble.cpp
+ gui/speechbubble.h
+ gui/specialswindow.cpp
+ gui/specialswindow.h
+ gui/statuswindow.cpp
+ gui/statuswindow.h
+ gui/textdialog.cpp
+ gui/textdialog.h
+ gui/textpopup.cpp
+ gui/textpopup.h
+ gui/theme.cpp
+ gui/theme.h
+ gui/trade.cpp
+ gui/trade.h
+ gui/truetypefont.cpp
+ gui/truetypefont.h
+ gui/unregisterdialog.cpp
+ gui/unregisterdialog.h
+ gui/updatewindow.cpp
+ gui/updatewindow.h
+ gui/userpalette.cpp
+ gui/userpalette.h
+ gui/viewport.cpp
+ gui/viewport.h
+ gui/whoisonline.cpp
+ gui/whoisonline.h
+ gui/windowmenu.cpp
+ gui/windowmenu.h
+ gui/worldselectdialog.cpp
+ gui/worldselectdialog.h
+ net/adminhandler.h
+ net/charhandler.cpp
+ net/charhandler.h
+ net/chathandler.h
+ net/download.cpp
+ net/download.h
+ net/gamehandler.h
+ net/generalhandler.h
+ net/guildhandler.h
+ net/inventoryhandler.h
+ net/logindata.h
+ net/loginhandler.h
+ net/messagehandler.h
+ net/messagein.cpp
+ net/messagein.h
+ net/messageout.cpp
+ net/messageout.h
+ net/npchandler.h
+ net/net.cpp
+ net/net.h
+ net/partyhandler.h
+ net/playerhandler.h
+ net/serverinfo.h
+ net/specialhandler.h
+ net/tradehandler.h
+ net/worldinfo.h
+ net/packetcounters.cpp
+ net/packetcounters.h
+ resources/action.cpp
+ resources/action.h
+ resources/ambientlayer.cpp
+ resources/ambientlayer.h
+ resources/ambientoverlay.cpp
+ resources/ambientoverlay.h
+ resources/animation.cpp
+ resources/animation.h
+ resources/beinginfo.cpp
+ resources/beinginfo.h
+ resources/colordb.cpp
+ resources/colordb.h
+ resources/dye.cpp
+ resources/dye.h
+ resources/emotedb.cpp
+ resources/emotedb.h
+ resources/image.cpp
+ resources/image.h
+ resources/imageloader.cpp
+ resources/imageloader.h
+ resources/imageset.h
+ resources/imageset.cpp
+ resources/imagewriter.cpp
+ resources/imagewriter.h
+ resources/itemdb.cpp
+ resources/itemdb.h
+ resources/iteminfo.h
+ resources/iteminfo.cpp
+ resources/mapreader.cpp
+ resources/mapreader.h
+ resources/monsterdb.cpp
+ resources/monsterdb.h
+ resources/music.cpp
+ resources/music.h
+ resources/npcdb.cpp
+ resources/npcdb.h
+ resources/resource.cpp
+ resources/resource.h
+ resources/resourcemanager.cpp
+ resources/resourcemanager.h
+ resources/soundeffect.h
+ resources/soundeffect.cpp
+ resources/specialdb.cpp
+ resources/specialdb.h
+ resources/spritedef.h
+ resources/spritedef.cpp
+ resources/wallpaper.cpp
+ resources/wallpaper.h
+ utils/base64.cpp
+ utils/base64.h
+ utils/copynpaste.cpp
+ utils/copynpaste.h
+ utils/dtor.h
+ utils/gettext.h
+ utils/mathutils.h
+ utils/sha256.cpp
+ utils/sha256.h
+ utils/stringutils.cpp
+ utils/stringutils.h
+ utils/mutex.h
+ utils/mkdir.cpp
+ utils/mkdir.h
+ utils/xml.cpp
+ utils/xml.h
+ actor.cpp
+ actor.h
+ actorsprite.cpp
+ actorsprite.h
+ actorspritelistener.h
+ actorspritemanager.cpp
+ actorspritemanager.h
+ animatedsprite.cpp
+ animatedsprite.h
+ animationparticle.cpp
+ animationparticle.h
+ avatar.cpp
+ avatar.h
+ being.cpp
+ being.h
+ spellmanager.cpp
+ spellmanager.h
+ chatlog.cpp
+ chatlog.h
+ client.cpp
+ client.h
+ channel.cpp
+ channel.h
+ channelmanager.cpp
+ channelmanager.h
+ commandhandler.cpp
+ commandhandler.h
+ compoundsprite.cpp
+ compoundsprite.h
+ configlistener.h
+ configuration.cpp
+ configuration.h
+ defaults.cpp
+ defaults.h
+ effectmanager.cpp
+ effectmanager.h
+ emoteshortcut.cpp
+ emoteshortcut.h
+ equipment.h
+ event.cpp
+ event.h
+ flooritem.cpp
+ flooritem.h
+ game.cpp
+ game.h
+ graphics.cpp
+ graphics.h
+ guichanfwd.h
+ guild.cpp
+ guild.h
+ imageparticle.cpp
+ imageparticle.h
+ imagesprite.cpp
+ imagesprite.h
+ inventory.cpp
+ inventory.h
+ item.cpp
+ item.h
+ itemshortcut.cpp
+ itemshortcut.h
+ dropshortcut.cpp
+ dropshortcut.h
+ spellshortcut.cpp
+ spellshortcut.h
+ textcommand.cpp
+ textcommand.h
+ joystick.cpp
+ joystick.h
+ keyboardconfig.cpp
+ keyboardconfig.h
+ listener.cpp
+ listener.h
+ localplayer.cpp
+ localplayer.h
+ log.cpp
+ log.h
+ main.cpp
+ main.h
+ map.cpp
+ map.h
+ opengl1graphics.cpp
+ opengl1graphics.h
+ openglgraphics.cpp
+ openglgraphics.h
+ particle.cpp
+ particle.h
+ particlecontainer.cpp
+ particlecontainer.h
+ particleemitter.cpp
+ particleemitter.h
+ particleemitterprop.h
+ party.cpp
+ party.h
+ playerinfo.cpp
+ playerinfo.h
+ playerrelations.cpp
+ playerrelations.h
+ position.cpp
+ position.h
+ properties.h
+ rotationalparticle.cpp
+ rotationalparticle.h
+ shopitem.cpp
+ shopitem.h
+ simpleanimation.cpp
+ simpleanimation.h
+ sound.cpp
+ sound.h
+ sprite.h
+ statuseffect.cpp
+ statuseffect.h
+ text.cpp
+ text.h
+ textmanager.cpp
+ textmanager.h
+ textparticle.cpp
+ textparticle.h
+ textrenderer.h
+ tileset.h
+ units.cpp
+ units.h
+ variabledata.h
+ vector.cpp
+ vector.h
+ mumblemanager.cpp
+ mumblemanager.h
+ )
+
+SET(SRCS_TMWA
+ net/tmwa/gui/guildtab.cpp
+ net/tmwa/gui/guildtab.h
+ net/tmwa/gui/partytab.cpp
+ net/tmwa/gui/partytab.h
+ net/tmwa/adminhandler.cpp
+ net/tmwa/adminhandler.h
+ net/tmwa/beinghandler.cpp
+ net/tmwa/beinghandler.h
+ net/tmwa/buysellhandler.cpp
+ net/tmwa/buysellhandler.h
+ net/tmwa/charserverhandler.cpp
+ net/tmwa/charserverhandler.h
+ net/tmwa/chathandler.cpp
+ net/tmwa/chathandler.h
+ net/tmwa/gamehandler.cpp
+ net/tmwa/gamehandler.h
+ net/tmwa/generalhandler.cpp
+ net/tmwa/generalhandler.h
+ net/tmwa/guildhandler.cpp
+ net/tmwa/guildhandler.h
+ net/tmwa/inventoryhandler.cpp
+ net/tmwa/inventoryhandler.h
+ net/tmwa/itemhandler.cpp
+ net/tmwa/itemhandler.h
+ net/tmwa/loginhandler.cpp
+ net/tmwa/loginhandler.h
+ net/tmwa/messagehandler.cpp
+ net/tmwa/messagehandler.h
+ net/tmwa/messagein.cpp
+ net/tmwa/messagein.h
+ net/tmwa/messageout.cpp
+ net/tmwa/messageout.h
+ net/tmwa/network.cpp
+ net/tmwa/network.h
+ net/tmwa/npchandler.cpp
+ net/tmwa/npchandler.h
+ net/tmwa/partyhandler.cpp
+ net/tmwa/partyhandler.h
+ net/tmwa/playerhandler.cpp
+ net/tmwa/playerhandler.h
+ net/tmwa/protocol.h
+ net/tmwa/specialhandler.cpp
+ net/tmwa/specialhandler.h
+ net/tmwa/token.h
+ net/tmwa/tradehandler.cpp
+ net/tmwa/tradehandler.h
+ )
+
+SET(SRCS_MANAPLUS
+ net/manaserv/attributes.cpp
+ net/manaserv/attributes.h
+ net/manaserv/adminhandler.cpp
+ net/manaserv/adminhandler.h
+ net/manaserv/beinghandler.cpp
+ net/manaserv/beinghandler.h
+ net/manaserv/buysellhandler.cpp
+ net/manaserv/buysellhandler.h
+ net/manaserv/charhandler.cpp
+ net/manaserv/charhandler.h
+ net/manaserv/chathandler.cpp
+ net/manaserv/chathandler.h
+ net/manaserv/connection.cpp
+ net/manaserv/connection.h
+ net/manaserv/defines.h
+ net/manaserv/effecthandler.cpp
+ net/manaserv/effecthandler.h
+ net/manaserv/gamehandler.cpp
+ net/manaserv/gamehandler.h
+ net/manaserv/generalhandler.cpp
+ net/manaserv/generalhandler.h
+ net/manaserv/guildhandler.cpp
+ net/manaserv/guildhandler.h
+ net/manaserv/internal.cpp
+ net/manaserv/internal.h
+ net/manaserv/inventoryhandler.cpp
+ net/manaserv/inventoryhandler.h
+ net/manaserv/itemhandler.h
+ net/manaserv/itemhandler.cpp
+ net/manaserv/loginhandler.cpp
+ net/manaserv/loginhandler.h
+ net/manaserv/messagehandler.cpp
+ net/manaserv/messagehandler.h
+ net/manaserv/messagein.cpp
+ net/manaserv/messagein.h
+ net/manaserv/messageout.cpp
+ net/manaserv/messageout.h
+ net/manaserv/network.cpp
+ net/manaserv/network.h
+ net/manaserv/npchandler.cpp
+ net/manaserv/npchandler.h
+ net/manaserv/partyhandler.cpp
+ net/manaserv/partyhandler.h
+ net/manaserv/playerhandler.cpp
+ net/manaserv/playerhandler.h
+ net/manaserv/protocol.h
+ net/manaserv/specialhandler.cpp
+ net/manaserv/specialhandler.h
+ net/manaserv/tradehandler.cpp
+ net/manaserv/tradehandler.h
+ )
+
+IF (WIN32)
+ SET(SRCS_MANAPLUS
+ ${SRCS_MANAPLUS}
+ utils/specialfolder.cpp
+ utils/specialfolder.h
+ mana.rc
+ )
+ENDIF ()
+
+SET (PROGRAMS manaplus)
+
+ADD_EXECUTABLE(manaplus WIN32 ${SRCS} ${SRCS_MANAPLUS} ${SRCS_TMWA})
+
+TARGET_LINK_LIBRARIES(manaplus
+ ${SDLGFX_LIBRARIES}
+ ${SDL_LIBRARY}
+ ${SDLIMAGE_LIBRARY}
+ ${SDLMIXER_LIBRARY}
+ ${SDLNET_LIBRARY}
+ ${SDLTTF_LIBRARY}
+ ${PNG_LIBRARIES}
+ ${PHYSFS_LIBRARY}
+ ${CURL_LIBRARIES}
+ ${LIBXML2_LIBRARIES}
+ ${GUICHAN_LIBRARIES}
+ ${OPENGL_LIBRARIES}
+ ${LIBINTL_LIBRARIES}
+ ${EXTRA_LIBRARIES})
+INSTALL(TARGETS manaplus RUNTIME DESTINATION ${PKG_BINDIR})
+
+IF (CMAKE_SYSTEM_NAME STREQUAL SunOS)
+ # we expect the SMCgtxt package to be present on Solaris;
+ # the Solaris gettext is not API-compatible to GNU gettext
+ SET_TARGET_PROPERTIES(manaplus PROPERTIES LINK_FLAGS "-L/usr/local/lib")
+ENDIF()
+
+SET_TARGET_PROPERTIES(manaplus PROPERTIES COMPILE_FLAGS "${FLAGS}")
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 000000000..311f0d8e2
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,589 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+bin_PROGRAMS = manaplus
+
+manaplus_CXXFLAGS = -DPKG_DATADIR=\""$(pkgdatadir)/"\" \
+ -DLOCALEDIR=\""$(localedir)"\" \
+ -Wall
+
+manaplus_SOURCES = enet/callbacks.c \
+ enet/compress.c \
+ enet/host.c \
+ enet/list.c \
+ enet/packet.c \
+ enet/peer.c \
+ enet/protocol.c \
+ enet/unix.c \
+ enet/win32.c \
+ enet/callbacks.h \
+ enet/enet.h \
+ enet/list.h \
+ enet/protocol.h \
+ enet/time.h \
+ enet/types.h \
+ enet/unix.h \
+ enet/utility.h \
+ enet/win32.h
+
+manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
+ gui/widgets/avatarlistbox.h \
+ gui/widgets/battletab.cpp \
+ gui/widgets/battletab.h \
+ gui/widgets/browserbox.cpp \
+ gui/widgets/browserbox.h \
+ gui/widgets/button.cpp \
+ gui/widgets/button.h \
+ gui/widgets/channeltab.cpp \
+ gui/widgets/channeltab.h \
+ gui/widgets/chattab.cpp \
+ gui/widgets/chattab.h \
+ gui/widgets/checkbox.cpp \
+ gui/widgets/checkbox.h \
+ gui/widgets/container.cpp \
+ gui/widgets/container.h \
+ gui/widgets/desktop.cpp \
+ gui/widgets/desktop.h \
+ gui/widgets/dropdown.cpp \
+ gui/widgets/dropdown.h \
+ gui/widgets/emoteshortcutcontainer.cpp \
+ gui/widgets/emoteshortcutcontainer.h \
+ gui/widgets/flowcontainer.cpp \
+ gui/widgets/flowcontainer.h \
+ gui/widgets/icon.cpp \
+ gui/widgets/icon.h \
+ gui/widgets/inttextfield.cpp \
+ gui/widgets/inttextfield.h \
+ gui/widgets/itemcontainer.cpp \
+ gui/widgets/itemcontainer.h \
+ gui/widgets/itemlinkhandler.cpp \
+ gui/widgets/itemlinkhandler.h \
+ gui/widgets/dropshortcutcontainer.cpp \
+ gui/widgets/dropshortcutcontainer.h \
+ gui/widgets/itemshortcutcontainer.cpp \
+ gui/widgets/itemshortcutcontainer.h \
+ gui/widgets/spellshortcutcontainer.cpp \
+ gui/widgets/spellshortcutcontainer.h \
+ gui/widgets/label.cpp \
+ gui/widgets/label.h \
+ gui/widgets/layout.cpp \
+ gui/widgets/layout.h \
+ gui/widgets/layouthelper.cpp \
+ gui/widgets/layouthelper.h \
+ gui/widgets/linkhandler.h \
+ gui/widgets/listbox.cpp \
+ gui/widgets/listbox.h \
+ gui/widgets/passwordfield.cpp \
+ gui/widgets/passwordfield.h \
+ gui/widgets/playerbox.cpp \
+ gui/widgets/playerbox.h \
+ gui/widgets/popup.cpp \
+ gui/widgets/popup.h \
+ gui/widgets/progressbar.cpp \
+ gui/widgets/progressbar.h \
+ gui/widgets/progressindicator.cpp \
+ gui/widgets/progressindicator.h \
+ gui/widgets/radiobutton.cpp \
+ gui/widgets/radiobutton.h \
+ gui/widgets/resizegrip.cpp \
+ gui/widgets/resizegrip.h \
+ gui/widgets/scrollarea.cpp \
+ gui/widgets/scrollarea.h \
+ gui/widgets/setuptab.cpp \
+ gui/widgets/setuptab.h \
+ gui/widgets/shopitems.cpp \
+ gui/widgets/shopitems.h \
+ gui/widgets/shoplistbox.cpp \
+ gui/widgets/shoplistbox.h \
+ gui/widgets/shortcutcontainer.cpp \
+ gui/widgets/shortcutcontainer.h \
+ gui/widgets/slider.cpp \
+ gui/widgets/slider.h \
+ gui/widgets/tab.cpp \
+ gui/widgets/tab.h \
+ gui/widgets/tabbedarea.cpp \
+ gui/widgets/tabbedarea.h \
+ gui/widgets/table.cpp \
+ gui/widgets/table.h \
+ gui/widgets/tablemodel.cpp \
+ gui/widgets/tablemodel.h \
+ gui/widgets/textbox.cpp \
+ gui/widgets/textbox.h \
+ gui/widgets/textfield.cpp \
+ gui/widgets/textfield.h \
+ gui/widgets/textpreview.cpp \
+ gui/widgets/textpreview.h \
+ gui/widgets/tradetab.cpp \
+ gui/widgets/tradetab.h \
+ gui/widgets/vertcontainer.cpp \
+ gui/widgets/vertcontainer.h \
+ gui/widgets/whispertab.cpp \
+ gui/widgets/whispertab.h \
+ gui/widgets/window.cpp \
+ gui/widgets/window.h \
+ gui/widgets/windowcontainer.cpp \
+ gui/widgets/windowcontainer.h \
+ gui/beingpopup.cpp \
+ gui/beingpopup.h \
+ gui/buy.cpp \
+ gui/buy.h \
+ gui/buysell.cpp \
+ gui/buysell.h \
+ gui/changeemaildialog.cpp \
+ gui/changeemaildialog.h \
+ gui/changepassworddialog.cpp \
+ gui/changepassworddialog.h \
+ gui/charselectdialog.cpp \
+ gui/charselectdialog.h \
+ gui/charcreatedialog.cpp \
+ gui/charcreatedialog.h \
+ gui/chat.cpp \
+ gui/chat.h \
+ gui/confirmdialog.cpp \
+ gui/confirmdialog.h \
+ gui/connectiondialog.cpp \
+ gui/connectiondialog.h \
+ gui/debugwindow.cpp \
+ gui/debugwindow.h \
+ gui/emotepopup.cpp \
+ gui/emotepopup.h \
+ gui/equipmentwindow.cpp \
+ gui/equipmentwindow.h \
+ gui/focushandler.cpp \
+ gui/focushandler.h \
+ gui/gui.cpp \
+ gui/gui.h \
+ gui/help.cpp \
+ gui/help.h \
+ gui/inventorywindow.cpp \
+ gui/inventorywindow.h \
+ gui/itemamount.cpp \
+ gui/itemamount.h \
+ gui/itempopup.cpp \
+ gui/itempopup.h \
+ gui/spellpopup.cpp \
+ gui/spellpopup.h \
+ gui/statuspopup.cpp \
+ gui/statuspopup.h \
+ gui/killstats.cpp \
+ gui/killstats.h \
+ gui/login.cpp \
+ gui/login.h \
+ gui/minimap.cpp \
+ gui/minimap.h \
+ gui/ministatus.cpp \
+ gui/ministatus.h \
+ gui/npcdialog.cpp \
+ gui/npcdialog.h \
+ gui/npcpostdialog.cpp \
+ gui/npcpostdialog.h \
+ gui/okdialog.cpp \
+ gui/okdialog.h \
+ gui/editdialog.cpp \
+ gui/editdialog.h \
+ gui/outfitwindow.cpp \
+ gui/outfitwindow.h \
+ gui/botcheckerwindow.cpp \
+ gui/botcheckerwindow.h \
+ gui/textcommandeditor.cpp \
+ gui/textcommandeditor.h \
+ gui/palette.cpp \
+ gui/palette.h \
+ gui/popupmenu.cpp \
+ gui/popupmenu.h \
+ gui/quitdialog.cpp \
+ gui/quitdialog.h \
+ gui/register.cpp \
+ gui/register.h \
+ gui/sdlinput.cpp \
+ gui/sdlinput.h \
+ gui/sell.cpp \
+ gui/sell.h \
+ gui/serverdialog.cpp \
+ gui/serverdialog.h \
+ gui/setup.cpp \
+ gui/setup.h \
+ gui/setup_audio.cpp \
+ gui/setup_audio.h \
+ gui/setup_colors.cpp \
+ gui/setup_colors.h \
+ gui/setup_joystick.cpp \
+ gui/setup_joystick.h \
+ gui/setup_other.cpp \
+ gui/setup_other.h \
+ gui/setup_theme.cpp \
+ gui/setup_theme.h \
+ gui/setup_chat.cpp \
+ gui/setup_chat.h \
+ gui/setup_keyboard.cpp \
+ gui/setup_keyboard.h \
+ gui/setup_players.cpp \
+ gui/setup_players.h \
+ gui/setup_video.cpp \
+ gui/setup_video.h \
+ gui/shopwindow.cpp \
+ gui/shopwindow.h \
+ gui/shortcutwindow.cpp \
+ gui/shortcutwindow.h \
+ gui/skilldialog.cpp \
+ gui/skilldialog.h \
+ gui/socialwindow.cpp \
+ gui/socialwindow.h \
+ gui/speechbubble.cpp \
+ gui/speechbubble.h \
+ gui/specialswindow.cpp \
+ gui/specialswindow.h \
+ gui/statuswindow.cpp \
+ gui/statuswindow.h \
+ gui/textdialog.cpp \
+ gui/textdialog.h \
+ gui/textpopup.cpp \
+ gui/textpopup.h \
+ gui/theme.cpp \
+ gui/theme.h \
+ gui/trade.cpp \
+ gui/trade.h \
+ gui/truetypefont.cpp \
+ gui/truetypefont.h \
+ gui/unregisterdialog.cpp \
+ gui/unregisterdialog.h \
+ gui/updatewindow.cpp \
+ gui/updatewindow.h \
+ gui/userpalette.cpp \
+ gui/userpalette.h \
+ gui/viewport.cpp \
+ gui/viewport.h \
+ gui/whoisonline.cpp \
+ gui/whoisonline.h \
+ gui/windowmenu.cpp \
+ gui/windowmenu.h \
+ gui/worldselectdialog.cpp \
+ gui/worldselectdialog.h \
+ net/adminhandler.h \
+ net/charhandler.cpp \
+ net/charhandler.h \
+ net/chathandler.h \
+ net/download.cpp \
+ net/download.h \
+ net/gamehandler.h \
+ net/generalhandler.h \
+ net/guildhandler.h \
+ net/inventoryhandler.h \
+ net/logindata.h \
+ net/loginhandler.h \
+ net/messagehandler.h \
+ net/messagein.cpp \
+ net/messagein.h \
+ net/messageout.cpp \
+ net/messageout.h \
+ net/net.cpp \
+ net/net.h \
+ net/npchandler.h \
+ net/partyhandler.h \
+ net/playerhandler.h \
+ net/serverinfo.h \
+ net/specialhandler.h \
+ net/tradehandler.h \
+ net/worldinfo.h \
+ net/packetcounters.cpp \
+ net/packetcounters.h \
+ resources/action.cpp \
+ resources/action.h \
+ resources/ambientlayer.cpp \
+ resources/ambientlayer.h \
+ resources/ambientoverlay.cpp \
+ resources/ambientoverlay.h \
+ resources/animation.cpp \
+ resources/animation.h \
+ resources/beinginfo.cpp \
+ resources/beinginfo.h \
+ resources/colordb.cpp \
+ resources/colordb.h \
+ resources/dye.cpp \
+ resources/dye.h \
+ resources/emotedb.cpp \
+ resources/emotedb.h \
+ resources/image.cpp \
+ resources/image.h \
+ resources/imageloader.cpp \
+ resources/imageloader.h \
+ resources/imageset.h \
+ resources/imageset.cpp \
+ resources/imagewriter.cpp \
+ resources/imagewriter.h \
+ resources/itemdb.cpp \
+ resources/itemdb.h \
+ resources/iteminfo.h \
+ resources/iteminfo.cpp \
+ resources/mapreader.cpp \
+ resources/mapreader.h \
+ resources/monsterdb.cpp \
+ resources/monsterdb.h \
+ resources/music.cpp \
+ resources/music.h \
+ resources/npcdb.cpp \
+ resources/npcdb.h \
+ resources/resource.cpp \
+ resources/resource.h \
+ resources/resourcemanager.cpp \
+ resources/resourcemanager.h \
+ resources/soundeffect.h \
+ resources/soundeffect.cpp \
+ resources/specialdb.cpp \
+ resources/specialdb.h \
+ resources/spritedef.h \
+ resources/spritedef.cpp \
+ resources/wallpaper.cpp \
+ resources/wallpaper.h \
+ utils/base64.cpp \
+ utils/base64.h \
+ utils/copynpaste.cpp \
+ utils/copynpaste.h \
+ utils/dtor.h \
+ utils/gettext.h \
+ utils/mathutils.h \
+ utils/mkdir.cpp \
+ utils/mkdir.h \
+ utils/sha256.cpp \
+ utils/sha256.h \
+ utils/specialfolder.cpp \
+ utils/specialfolder.h \
+ utils/stringutils.cpp \
+ utils/stringutils.h \
+ utils/mutex.h \
+ utils/xml.cpp \
+ utils/xml.h \
+ actor.cpp \
+ actor.h \
+ actorsprite.cpp \
+ actorsprite.h \
+ actorspritelistener.h \
+ actorspritemanager.cpp \
+ actorspritemanager.h \
+ animatedsprite.cpp \
+ animatedsprite.h \
+ animationparticle.cpp \
+ animationparticle.h \
+ avatar.cpp \
+ avatar.h \
+ being.cpp \
+ being.h \
+ spellmanager.cpp \
+ spellmanager.h \
+ chatlog.cpp \
+ chatlog.h \
+ client.cpp \
+ client.h \
+ channel.cpp \
+ channel.h \
+ channelmanager.cpp \
+ channelmanager.h \
+ commandhandler.cpp \
+ commandhandler.h \
+ compoundsprite.cpp \
+ compoundsprite.h \
+ configlistener.h \
+ configuration.cpp \
+ configuration.h \
+ defaults.cpp \
+ defaults.h \
+ effectmanager.cpp \
+ effectmanager.h \
+ emoteshortcut.cpp \
+ emoteshortcut.h \
+ equipment.h \
+ event.cpp \
+ event.h \
+ flooritem.cpp \
+ flooritem.h \
+ game.cpp \
+ game.h \
+ graphics.cpp \
+ graphics.h \
+ guichanfwd.h \
+ guild.cpp \
+ guild.h \
+ imageparticle.cpp \
+ imageparticle.h \
+ imagesprite.cpp \
+ imagesprite.h \
+ inventory.cpp \
+ inventory.h \
+ item.cpp \
+ item.h \
+ itemshortcut.cpp \
+ itemshortcut.h \
+ dropshortcut.cpp \
+ dropshortcut.h \
+ spellshortcut.cpp \
+ spellshortcut.h \
+ textcommand.cpp \
+ textcommand.h \
+ joystick.cpp \
+ joystick.h \
+ keyboardconfig.cpp \
+ keyboardconfig.h \
+ listener.cpp \
+ listener.h \
+ localplayer.cpp \
+ localplayer.h \
+ log.cpp \
+ log.h \
+ main.cpp \
+ main.h \
+ map.cpp\
+ map.h \
+ opengl1graphics.cpp\
+ opengl1graphics.h \
+ openglgraphics.cpp\
+ openglgraphics.h \
+ particle.cpp \
+ particle.h \
+ particlecontainer.cpp \
+ particlecontainer.h \
+ particleemitter.cpp \
+ particleemitter.h \
+ particleemitterprop.h \
+ party.cpp \
+ party.h \
+ playerinfo.cpp \
+ playerinfo.h \
+ playerrelations.cpp \
+ playerrelations.h \
+ position.cpp \
+ position.h \
+ properties.h \
+ rotationalparticle.cpp \
+ rotationalparticle.h \
+ shopitem.cpp \
+ shopitem.h \
+ simpleanimation.cpp \
+ simpleanimation.h \
+ sound.cpp \
+ sound.h \
+ sprite.h \
+ statuseffect.cpp \
+ statuseffect.h \
+ text.cpp \
+ text.h \
+ textmanager.cpp \
+ textmanager.h \
+ textparticle.cpp \
+ textparticle.h \
+ textrenderer.h \
+ tileset.h \
+ units.cpp \
+ units.h \
+ variabledata.h \
+ vector.cpp \
+ vector.h \
+ winver.h
+
+manaplus_SOURCES += \
+ net/manaserv/attributes.cpp \
+ net/manaserv/attributes.h \
+ net/manaserv/adminhandler.cpp \
+ net/manaserv/adminhandler.h \
+ net/manaserv/beinghandler.cpp \
+ net/manaserv/beinghandler.h \
+ net/manaserv/buysellhandler.cpp \
+ net/manaserv/buysellhandler.h \
+ net/manaserv/charhandler.cpp \
+ net/manaserv/charhandler.h \
+ net/manaserv/chathandler.cpp \
+ net/manaserv/chathandler.h \
+ net/manaserv/connection.cpp \
+ net/manaserv/connection.h \
+ net/manaserv/defines.h \
+ net/manaserv/effecthandler.cpp \
+ net/manaserv/effecthandler.h \
+ net/manaserv/gamehandler.cpp \
+ net/manaserv/gamehandler.h \
+ net/manaserv/generalhandler.cpp \
+ net/manaserv/generalhandler.h \
+ net/manaserv/guildhandler.cpp \
+ net/manaserv/guildhandler.h \
+ net/manaserv/internal.cpp \
+ net/manaserv/internal.h \
+ net/manaserv/inventoryhandler.cpp \
+ net/manaserv/inventoryhandler.h \
+ net/manaserv/itemhandler.h \
+ net/manaserv/itemhandler.cpp \
+ net/manaserv/loginhandler.cpp \
+ net/manaserv/loginhandler.h \
+ net/manaserv/messagehandler.cpp \
+ net/manaserv/messagehandler.h \
+ net/manaserv/messagein.cpp \
+ net/manaserv/messagein.h \
+ net/manaserv/messageout.cpp \
+ net/manaserv/messageout.h \
+ net/manaserv/network.cpp \
+ net/manaserv/network.h \
+ net/manaserv/npchandler.cpp \
+ net/manaserv/npchandler.h \
+ net/manaserv/partyhandler.cpp \
+ net/manaserv/partyhandler.h \
+ net/manaserv/playerhandler.cpp \
+ net/manaserv/playerhandler.h \
+ net/manaserv/protocol.h \
+ net/manaserv/specialhandler.cpp \
+ net/manaserv/specialhandler.h \
+ net/manaserv/tradehandler.cpp \
+ net/manaserv/tradehandler.h
+
+manaplus_SOURCES += \
+ net/tmwa/gui/guildtab.cpp \
+ net/tmwa/gui/guildtab.h \
+ net/tmwa/gui/partytab.cpp \
+ net/tmwa/gui/partytab.h \
+ net/tmwa/adminhandler.cpp \
+ net/tmwa/adminhandler.h \
+ net/tmwa/beinghandler.cpp \
+ net/tmwa/beinghandler.h \
+ net/tmwa/buysellhandler.cpp \
+ net/tmwa/buysellhandler.h \
+ net/tmwa/charserverhandler.cpp \
+ net/tmwa/charserverhandler.h \
+ net/tmwa/chathandler.cpp \
+ net/tmwa/chathandler.h \
+ net/tmwa/gamehandler.cpp \
+ net/tmwa/gamehandler.h \
+ net/tmwa/generalhandler.cpp \
+ net/tmwa/generalhandler.h \
+ net/tmwa/guildhandler.cpp \
+ net/tmwa/guildhandler.h \
+ net/tmwa/inventoryhandler.cpp \
+ net/tmwa/inventoryhandler.h \
+ net/tmwa/itemhandler.cpp \
+ net/tmwa/itemhandler.h \
+ net/tmwa/loginhandler.cpp \
+ net/tmwa/loginhandler.h \
+ net/tmwa/messagehandler.cpp \
+ net/tmwa/messagehandler.h \
+ net/tmwa/messagein.cpp \
+ net/tmwa/messagein.h \
+ net/tmwa/messageout.cpp \
+ net/tmwa/messageout.h \
+ net/tmwa/network.cpp \
+ net/tmwa/network.h \
+ net/tmwa/npchandler.cpp \
+ net/tmwa/npchandler.h \
+ net/tmwa/partyhandler.cpp \
+ net/tmwa/partyhandler.h \
+ net/tmwa/playerhandler.cpp \
+ net/tmwa/playerhandler.h \
+ net/tmwa/protocol.h \
+ net/tmwa/specialhandler.cpp \
+ net/tmwa/specialhandler.h \
+ net/tmwa/token.h \
+ net/tmwa/tradehandler.cpp \
+ net/tmwa/tradehandler.h
+
+manaplus_SOURCES += \
+ mumblemanager.cpp \
+ mumblemanager.h
+
+EXTRA_DIST = CMakeLists.txt \
+ winver.h.in
+
+# set the include path found by configure
+INCLUDES = $(all_includes)
diff --git a/src/SDLMain.h b/src/SDLMain.h
new file mode 100644
index 000000000..4683df57a
--- /dev/null
+++ b/src/SDLMain.h
@@ -0,0 +1,11 @@
+/* SDLMain.m - main entry point for our Cocoa-ized SDL app
+ Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+ Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+ Feel free to customize this file to suit your needs
+*/
+
+#import <Cocoa/Cocoa.h>
+
+@interface SDLMain : NSObject
+@end
diff --git a/src/SDLMain.m b/src/SDLMain.m
new file mode 100644
index 000000000..d7e9273bc
--- /dev/null
+++ b/src/SDLMain.m
@@ -0,0 +1,385 @@
+/* SDLMain.m - main entry point for our Cocoa-ized SDL app
+ Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+ Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+ Feel free to customize this file to suit your needs
+ */
+
+#import "SDL.h"
+#import "SDLMain.h"
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
+ but the method still is there and works. To avoid warnings, we declare
+ it ourselves here. */
+@interface NSApplication(SDL_Missing_Methods)
+- (void)setAppleMenu:(NSMenu *)menu;
+@end
+
+/* Use this flag to determine whether we use SDLMain.nib or not */
+#define SDL_USE_NIB_FILE 0
+
+/* Use this flag to determine whether we use CPS (docking) or not */
+#define SDL_USE_CPS 1
+#ifdef SDL_USE_CPS
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum
+ {
+ UInt32 lo;
+ UInt32 hi;
+ } CPSProcessSerNum;
+
+extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+#endif /* SDL_USE_CPS */
+
+static int gArgc;
+static char **gArgv;
+static BOOL gFinderLaunch;
+static BOOL gCalledAppMainline = FALSE;
+
+static NSString *getApplicationName(void)
+{
+ NSDictionary *dict;
+ NSString *appName = 0;
+
+ /* Determine the application name */
+ dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
+ if (dict)
+ appName = [dict objectForKey: @"CFBundleName"];
+
+ if (![appName length])
+ appName = [[NSProcessInfo processInfo] processName];
+
+ return appName;
+}
+
+#if SDL_USE_NIB_FILE
+/* A helper category for NSString */
+@interface NSString (ReplaceSubString)
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
+@end
+#endif
+
+@interface SDLApplication : NSApplication
+@end
+
+@implementation SDLApplication
+/* Invoked from the Quit menu item */
+- (void)terminate:(id)sender
+{
+ /* Post a SDL_QUIT event */
+ SDL_Event event;
+ event.type = SDL_QUIT;
+ SDL_PushEvent(&event);
+}
+@end
+
+/* The main class of the application, the application's delegate */
+@implementation SDLMain
+
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory:(BOOL)shouldChdir
+{
+ if (shouldChdir)
+ {
+ char parentdir[MAXPATHLEN];
+ CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
+ if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
+ assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
+ }
+ CFRelease(url);
+ CFRelease(url2);
+ }
+
+}
+
+#if SDL_USE_NIB_FILE
+
+/* Fix menu to contain the real app name instead of "SDL App" */
+- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
+{
+ NSRange aRange;
+ NSEnumerator *enumerator;
+ NSMenuItem *menuItem;
+
+ aRange = [[aMenu title] rangeOfString:@"SDL App"];
+ if (aRange.length != 0)
+ [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
+
+ enumerator = [[aMenu itemArray] objectEnumerator];
+ while ((menuItem = [enumerator nextObject]))
+ {
+ aRange = [[menuItem title] rangeOfString:@"SDL App"];
+ if (aRange.length != 0)
+ [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
+ if ([menuItem hasSubmenu])
+ [self fixMenu:[menuItem submenu] withAppName:appName];
+ }
+ [ aMenu sizeToFit ];
+}
+
+#else
+
+static void setApplicationMenu(void)
+{
+ /* warning: this code is very odd */
+ NSMenu *appleMenu;
+ NSMenuItem *menuItem;
+ NSString *title;
+ NSString *appName;
+
+ appName = getApplicationName();
+ appleMenu = [[NSMenu alloc] initWithTitle:@""];
+
+ /* Add menu items */
+ title = [@"About " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Hide " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
+
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+
+ [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Quit " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+
+
+ /* Put menu into the menubar */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:appleMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Tell the application object that this is now the application menu */
+ [NSApp setAppleMenu:appleMenu];
+
+ /* Finally give up our references to the objects */
+ [appleMenu release];
+ [menuItem release];
+}
+
+/* Create a window menu */
+static void setupWindowMenu(void)
+{
+ NSMenu *windowMenu;
+ NSMenuItem *windowMenuItem;
+ NSMenuItem *menuItem;
+
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+
+ /* "Minimize" item */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+ [windowMenu addItem:menuItem];
+ [menuItem release];
+
+ /* Put menu into the menubar */
+ windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+ [windowMenuItem setSubmenu:windowMenu];
+ [[NSApp mainMenu] addItem:windowMenuItem];
+
+ /* Tell the application object that this is now the window menu */
+ [NSApp setWindowsMenu:windowMenu];
+
+ /* Finally give up our references to the objects */
+ [windowMenu release];
+ [windowMenuItem release];
+}
+
+/* Replacement for NSApplicationMain */
+static void CustomApplicationMain (int argc, char **argv)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ SDLMain *sdlMain;
+
+ /* Ensure the application object is initialised */
+ [SDLApplication sharedApplication];
+
+#ifdef SDL_USE_CPS
+ {
+ CPSProcessSerNum PSN;
+ /* Tell the dock about us */
+ if (!CPSGetCurrentProcess(&PSN))
+ if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+ if (!CPSSetFrontProcess(&PSN))
+ [SDLApplication sharedApplication];
+ }
+#endif /* SDL_USE_CPS */
+
+ /* Set up the menubar */
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
+ setApplicationMenu();
+ setupWindowMenu();
+
+ /* Create SDLMain and make it the app delegate */
+ sdlMain = [[SDLMain alloc] init];
+ [NSApp setDelegate:sdlMain];
+
+ /* Start the main event loop */
+ [NSApp run];
+
+ [sdlMain release];
+ [pool release];
+}
+
+#endif
+
+
+/*
+ * Catch document open requests...this lets us notice files when the app
+ * was launched by double-clicking a document, or when a document was
+ * dragged/dropped on the app's icon. You need to have a
+ * CFBundleDocumentsType section in your Info.plist to get this message,
+ * apparently.
+ *
+ * Files are added to gArgv, so to the app, they'll look like command line
+ * arguments. Previously, apps launched from the finder had nothing but
+ * an argv[0].
+ *
+ * This message may be received multiple times to open several docs on launch.
+ *
+ * This message is ignored once the app's mainline has been called.
+ */
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+ const char *temparg;
+ size_t arglen;
+ char *arg;
+ char **newargv;
+
+ if (!gFinderLaunch) /* MacOS is passing command line args. */
+ return FALSE;
+
+ if (gCalledAppMainline) /* app has started, ignore this document. */
+ return FALSE;
+
+ temparg = [filename UTF8String];
+ arglen = SDL_strlen(temparg) + 1;
+ arg = (char *) SDL_malloc(arglen);
+ if (arg == NULL)
+ return FALSE;
+
+ newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
+ if (newargv == NULL)
+ {
+ SDL_free(arg);
+ return FALSE;
+ }
+ gArgv = newargv;
+
+ SDL_strlcpy(arg, temparg, arglen);
+ gArgv[gArgc++] = arg;
+ gArgv[gArgc] = NULL;
+ return TRUE;
+}
+
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+ int status;
+
+ /* Set the working directory to the .app's parent directory */
+ [self setupWorkingDirectory:gFinderLaunch];
+
+#if SDL_USE_NIB_FILE
+ /* Set the main menu to contain the real app name instead of "SDL App" */
+ [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
+#endif
+
+ /* Hand off to main application code */
+ gCalledAppMainline = TRUE;
+ status = SDL_main (gArgc, gArgv);
+
+ /* We're done, thank you for playing */
+ exit(status);
+}
+@end
+
+
+@implementation NSString (ReplaceSubString)
+
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
+{
+ unsigned int bufferSize;
+ unsigned int selfLen = [self length];
+ unsigned int aStringLen = [aString length];
+ unichar *buffer;
+ NSRange localRange;
+ NSString *result;
+
+ bufferSize = selfLen + aStringLen - aRange.length;
+ buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
+
+ /* Get first part into buffer */
+ localRange.location = 0;
+ localRange.length = aRange.location;
+ [self getCharacters:buffer range:localRange];
+
+ /* Get middle part into buffer */
+ localRange.location = 0;
+ localRange.length = aStringLen;
+ [aString getCharacters:(buffer+aRange.location) range:localRange];
+
+ /* Get last part into buffer */
+ localRange.location = aRange.location + aRange.length;
+ localRange.length = selfLen - localRange.location;
+ [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
+
+ /* Build output string */
+ result = [NSString stringWithCharacters:buffer length:bufferSize];
+
+ NSDeallocateMemoryPages(buffer, bufferSize);
+
+ return result;
+}
+
+@end
+
+
+
+#ifdef main
+# undef main
+#endif
+
+
+/* Main entry point to executable - should *not* be SDL_main! */
+int main (int argc, char **argv)
+{
+ /* Copy the arguments into a global variable */
+ /* This is passed if we are launched by double-clicking */
+ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+ gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
+ gArgv[0] = argv[0];
+ gArgv[1] = NULL;
+ gArgc = 1;
+ gFinderLaunch = YES;
+ }
+ else
+ {
+ int i;
+ gArgc = argc;
+ gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
+ for (i = 0; i <= argc; i++)
+ gArgv[i] = argv[i];
+ gFinderLaunch = NO;
+ }
+
+#if SDL_USE_NIB_FILE
+ [SDLApplication poseAsClass:[NSApplication class]];
+ NSApplicationMain (argc, argv);
+#else
+ CustomApplicationMain (argc, argv);
+#endif
+ return 0;
+}
diff --git a/src/SDL_gfxBlitFunc.h b/src/SDL_gfxBlitFunc.h
new file mode 100644
index 000000000..f233aa617
--- /dev/null
+++ b/src/SDL_gfxBlitFunc.h
@@ -0,0 +1,128 @@
+/*
+
+ SDL_gfxBlitFunc: custom blitters (part of SDL_gfx library)
+
+ LGPL (c) A. Schiffler
+
+*/
+
+#ifndef _SDL_gfxBlitFunc_h
+#define _SDL_gfxBlitFunc_h
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <SDL.h>
+#include <SDL_video.h>
+
+/* -------- Prototypes */
+
+#ifdef WIN32
+# ifdef DLL_EXPORT
+# define SDL_GFXBLITFUNC_SCOPE __declspec(dllexport)
+# else
+# ifdef LIBSDL_GFX_DLL_IMPORT
+# define SDL_GFXBLITFUNC_SCOPE __declspec(dllimport)
+# endif
+# endif
+#endif
+#ifndef SDL_GFXBLITFUNC_SCOPE
+# define SDL_GFXBLITFUNC_SCOPE extern
+#endif
+
+
+SDL_GFXBLITFUNC_SCOPE int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect);
+
+SDL_GFXBLITFUNC_SCOPE int SDL_gfxSetAlpha(SDL_Surface * src, Uint8 a);
+
+
+/* -------- Macros */
+
+/* Define SDL macros locally as a substitute for a #include "SDL_blit.h", */
+
+/* which doesn't work since the include file doesn't get installed. */
+
+/* The structure passed to the low level blit functions */
+ typedef struct {
+ Uint8 *s_pixels;
+ int s_width;
+ int s_height;
+ int s_skip;
+ Uint8 *d_pixels;
+ int d_width;
+ int d_height;
+ int d_skip;
+ void *aux_data;
+ SDL_PixelFormat *src;
+ Uint8 *table;
+ SDL_PixelFormat *dst;
+ } SDL_gfxBlitInfo;
+
+#define GFX_RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a) \
+{ \
+ r = ((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss; \
+ g = ((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss; \
+ b = ((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss; \
+ a = ((pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss; \
+}
+
+#define GFX_DISEMBLE_RGBA(buf, bpp, fmt, pixel, r, g, b, a) \
+do { \
+ pixel = *((Uint32 *)(buf)); \
+ GFX_RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a); \
+ pixel &= ~fmt->Amask; \
+} while(0)
+
+#define GFX_PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a) \
+{ \
+ pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift)| \
+ ((a<<fmt->Aloss)<<fmt->Ashift); \
+}
+
+#define GFX_ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \
+{ \
+ Uint32 pixel; \
+ \
+ GFX_PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \
+ *((Uint32 *)(buf)) = pixel; \
+}
+
+/* Blend the RGB values of two pixels based on a source alpha value */
+#define GFX_ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \
+do { \
+ dR = (((sR-dR)*(A))/255)+dR; \
+ dG = (((sG-dG)*(A))/255)+dG; \
+ dB = (((sB-dB)*(A))/255)+dB; \
+} while(0)
+
+/* This is a very useful loop for optimizing blitters */
+
+/* 4-times unrolled loop */
+#define GFX_DUFFS_LOOP4(pixel_copy_increment, width) \
+{ int n = (width+3)/4; \
+ switch (width & 3) { \
+ case 0: do { pixel_copy_increment; \
+ case 3: pixel_copy_increment; \
+ case 2: pixel_copy_increment; \
+ case 1: pixel_copy_increment; \
+ } while ( --n > 0 ); \
+ } \
+}
+
+//deleted
+
+/* --- */
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SDL_gfxBlitFunc_h */
diff --git a/src/actor.cpp b/src/actor.cpp
new file mode 100644
index 000000000..b7b039755
--- /dev/null
+++ b/src/actor.cpp
@@ -0,0 +1,64 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "actor.h"
+
+#include "map.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+Actor::Actor():
+ mMap(0)
+{}
+
+Actor::~Actor()
+{
+ setMap(0);
+}
+
+void Actor::setMap(Map *map)
+{
+ // Remove Actor from potential previous map
+ if (mMap)
+ mMap->removeActor(mMapActor);
+
+ mMap = map;
+
+ // Add Actor to potential new map
+ if (mMap)
+ mMapActor = mMap->addActor(this);
+}
+
+int Actor::getTileX() const
+{
+ if (!mMap || !mMap->getTileWidth())
+ return 0;
+
+ return getPixelX() / mMap->getTileWidth();
+}
+
+int Actor::getTileY() const
+{
+ if (!mMap || !mMap->getTileHeight())
+ return 0;
+
+ return getPixelY() / mMap->getTileHeight();
+}
diff --git a/src/actor.h b/src/actor.h
new file mode 100644
index 000000000..4e1ede128
--- /dev/null
+++ b/src/actor.h
@@ -0,0 +1,128 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ACTOR_H
+#define ACTOR_H
+
+#include "vector.h"
+
+#include <list>
+
+class Actor;
+class Graphics;
+class Image;
+class Map;
+
+typedef std::list<Actor*> Actors;
+
+class Actor
+{
+public:
+ Actor();
+
+ virtual ~Actor();
+
+ /**
+ * Draws the Actor to the given graphics context.
+ *
+ * Note: this function could be simplified if the graphics context
+ * would support setting a translation offset. It already does this
+ * partly with the clipping rectangle support.
+ */
+ virtual bool draw(Graphics *graphics, int offsetX, int offsetY) const = 0;
+
+ /**
+ * Returns the horizontal size of the actors graphical representation
+ * in pixels or 0 when it is undefined.
+ */
+ virtual int getWidth() const
+ { return 0; }
+
+ /**
+ * Returns the vertical size of the actors graphical representation
+ * in pixels or 0 when it is undefined.
+ */
+ virtual int getHeight() const
+ { return 0; }
+
+ /**
+ * Returns the pixel position of this actor.
+ */
+ const Vector &getPosition() const
+ { return mPos; }
+
+ /**
+ * Sets the pixel position of this actor.
+ */
+ virtual void setPosition(const Vector &pos)
+ { mPos = pos; }
+
+ /**
+ * Returns the pixels X coordinate of the actor.
+ */
+ int getPixelX() const
+ { return static_cast<int>(mPos.x); }
+
+ /**
+ * Returns the pixel Y coordinate of the actor.
+ */
+ virtual int getPixelY() const
+ { return static_cast<int>(mPos.y); }
+
+ /**
+ * Returns the x coordinate in tiles of the actor.
+ */
+ virtual int getTileX() const;
+
+ /**
+ * Returns the y coordinate in tiles of the actor.
+ */
+ virtual int getTileY() const;
+
+ /**
+ * Returns the number of Image layers used to draw the actor.
+ */
+ virtual int getNumberOfLayers() const
+ { return 0; }
+
+ /**
+ * Returns the current alpha value used to draw the actor.
+ */
+ virtual float getAlpha() const = 0;
+
+ /**
+ * Sets the alpha value used to draw the actor.
+ */
+ virtual void setAlpha(float alpha) = 0;
+
+ void setMap(Map *map);
+
+ Map* getMap() const
+ { return mMap; }
+
+protected:
+ Map *mMap;
+ Vector mPos; /**< Position in pixels relative to map. */
+
+private:
+ Actors::iterator mMapActor;
+};
+
+#endif // ACTOR_H
diff --git a/src/actorsprite.cpp b/src/actorsprite.cpp
new file mode 100644
index 000000000..8b29b91b6
--- /dev/null
+++ b/src/actorsprite.cpp
@@ -0,0 +1,491 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "actorsprite.h"
+#include "actorspritelistener.h"
+
+#include "client.h"
+#include "effectmanager.h"
+#include "imagesprite.h"
+#include "localplayer.h"
+#include "log.h"
+#include "simpleanimation.h"
+#include "sound.h"
+#include "statuseffect.h"
+
+#include "gui/theme.h"
+
+#include "net/net.h"
+
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/resourcemanager.h"
+
+#define EFFECTS_FILE "effects.xml"
+
+ImageSet *ActorSprite::targetCursorImages[2][NUM_TC];
+SimpleAnimation *ActorSprite::targetCursor[2][NUM_TC];
+bool ActorSprite::loaded = false;
+
+ActorSprite::ActorSprite(int id):
+ mId(id),
+ mStunMode(0),
+ mStatusParticleEffects(&mStunParticleEffects, false),
+ mChildParticleEffects(&mStatusParticleEffects, false),
+ mMustResetParticles(false),
+ mUsedTargetCursor(0)
+{
+}
+
+ActorSprite::~ActorSprite()
+{
+ setMap(0);
+
+ mUsedTargetCursor = 0;
+
+ if (player_node && player_node->getTarget() == this)
+ player_node->setTarget(0);
+
+ // Notify listeners of the destruction.
+ for (ActorSpriteListenerIterator iter = mActorSpriteListeners.begin(),
+ end = mActorSpriteListeners.end(); iter != end; ++iter)
+ {
+ (*iter)->actorSpriteDestroyed(*this);
+ }
+}
+
+bool ActorSprite::draw(Graphics *graphics, int offsetX, int offsetY) const
+{
+ // TODO: Eventually, we probably should fix all sprite offsets so that
+ // these translations aren't necessary anymore. The sprites know
+ // best where their base point should be.
+ const int px = getPixelX() + offsetX - 16;
+ // Temporary fix to the Y offset.
+ const int py = getPixelY() + offsetY -
+ ((Net::getNetworkType() == ServerInfo::MANASERV) ? 15 : 32);
+
+ if (mUsedTargetCursor)
+ {
+ mUsedTargetCursor->reset();
+ mUsedTargetCursor->update(tick_time * MILLISECONDS_IN_A_TICK);
+ mUsedTargetCursor->draw(graphics, px + getTargetOffsetX(),
+ py + getTargetOffsetY());
+ }
+
+ return drawSpriteAt(graphics, px, py);
+}
+
+bool ActorSprite::drawSpriteAt(Graphics *graphics, int x, int y) const
+{
+ return CompoundSprite::draw(graphics, x, y);
+}
+
+void ActorSprite::logic()
+{
+ // Update sprite animations
+ update(tick_time * MILLISECONDS_IN_A_TICK);
+
+ // Restart status/particle effects, if needed
+ if (mMustResetParticles)
+ {
+ mMustResetParticles = false;
+ for (std::set<int>::iterator it = mStatusEffects.begin();
+ it != mStatusEffects.end(); it++)
+ {
+ const StatusEffect *effect
+ = StatusEffect::getStatusEffect(*it, true);
+ if (effect && effect->particleEffectIsPersistent())
+ updateStatusEffect(*it, true);
+ }
+ }
+
+ // Update particle effects
+ mChildParticleEffects.moveTo(mPos.x, mPos.y);
+}
+
+void ActorSprite::actorLogic()
+{
+}
+
+void ActorSprite::setMap(Map* map)
+{
+ Actor::setMap(map);
+
+ // Clear particle effect list because child particles became invalid
+ mChildParticleEffects.clear();
+ mMustResetParticles = true; // Reset status particles on next redraw
+}
+
+void ActorSprite::controlParticle(Particle *particle)
+{
+ mChildParticleEffects.addLocally(particle);
+}
+
+void ActorSprite::setTargetType(TargetCursorType type)
+{
+ if (type == TCT_NONE)
+ untarget();
+ else
+ mUsedTargetCursor = targetCursor[type][getTargetCursorSize()];
+}
+
+struct EffectDescription
+{
+ std::string mGFXEffect;
+ std::string mSFXEffect;
+};
+
+static EffectDescription *default_effect = 0;
+static std::map<int, EffectDescription *> effects;
+static bool effects_initialized = false;
+
+static EffectDescription *getEffectDescription(xmlNodePtr node, int *id)
+{
+ EffectDescription *ed = new EffectDescription;
+
+ *id = atoi(XML::getProperty(node, "id", "-1").c_str());
+ ed->mSFXEffect = XML::getProperty(node, "audio", "");
+ ed->mGFXEffect = XML::getProperty(node, "particle", "");
+
+ return ed;
+}
+
+static EffectDescription *getEffectDescription(int effectId)
+{
+ if (!effects_initialized)
+ {
+ XML::Document doc(EFFECTS_FILE);
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "being-effects"))
+ {
+ logger->log1("Error loading being effects file: "
+ EFFECTS_FILE);
+ return NULL;
+ }
+
+ for_each_xml_child_node(node, root)
+ {
+ int id;
+
+ if (xmlStrEqual(node->name, BAD_CAST "effect"))
+ {
+ EffectDescription *EffectDescription =
+ getEffectDescription(node, &id);
+ effects[id] = EffectDescription;
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "default"))
+ {
+ EffectDescription *effectDescription =
+ getEffectDescription(node, &id);
+
+ delete default_effect;
+
+ default_effect = effectDescription;
+ }
+ }
+
+ effects_initialized = true;
+ } // done initializing
+
+ EffectDescription *ed = effects[effectId];
+
+ return ed ? ed : default_effect;
+}
+
+void ActorSprite::setStatusEffect(int index, bool active)
+{
+ const bool wasActive = mStatusEffects.find(index) != mStatusEffects.end();
+
+ if (active != wasActive)
+ {
+ updateStatusEffect(index, active);
+ if (active)
+ mStatusEffects.insert(index);
+ else
+ mStatusEffects.erase(index);
+ }
+}
+
+void ActorSprite::setStatusEffectBlock(int offset, Uint16 newEffects)
+{
+ for (int i = 0; i < STATUS_EFFECTS; i++)
+ {
+ int index = StatusEffect::blockEffectIndexToEffectIndex(offset + i);
+
+ if (index != -1)
+ setStatusEffect(index, (newEffects & (1 << i)) > 0);
+ }
+}
+
+void ActorSprite::internalTriggerEffect(int effectId, bool sfx, bool gfx)
+{
+ if (player_node)
+ {
+ logger->log("Special effect #%d on %s", effectId,
+ getId() == player_node->getId() ? "self" : "other");
+ }
+
+ EffectDescription *ed = getEffectDescription(effectId);
+
+ if (!ed)
+ {
+ logger->log1("Unknown special effect and no default recorded");
+ return;
+ }
+
+ if (gfx && !ed->mGFXEffect.empty() && particleEngine)
+ {
+ Particle *selfFX;
+
+ selfFX = particleEngine->addEffect(ed->mGFXEffect, 0, 0);
+ controlParticle(selfFX);
+ }
+
+ if (sfx && !ed->mSFXEffect.empty())
+ sound.playSfx(ed->mSFXEffect);
+}
+
+void ActorSprite::updateStunMode(int oldMode, int newMode)
+{
+ handleStatusEffect(StatusEffect::getStatusEffect(oldMode, false), -1);
+ handleStatusEffect(StatusEffect::getStatusEffect(newMode, true), -1);
+}
+
+void ActorSprite::updateStatusEffect(int index, bool newStatus)
+{
+ handleStatusEffect(StatusEffect::getStatusEffect(index, newStatus), index);
+}
+
+void ActorSprite::handleStatusEffect(StatusEffect *effect, int effectId)
+{
+ if (!effect)
+ return;
+
+ // TODO: Find out how this is meant to be used
+ // (SpriteAction != Being::Action)
+ //SpriteAction action = effect->getAction();
+ //if (action != ACTION_INVALID)
+ // setAction(action);
+
+ Particle *particle = effect->getParticle();
+
+ if (effectId >= 0)
+ {
+ mStatusParticleEffects.setLocally(effectId, particle);
+ }
+ else
+ {
+ mStunParticleEffects.clearLocally();
+ if (particle)
+ mStunParticleEffects.addLocally(particle);
+ }
+}
+
+void ActorSprite::setupSpriteDisplay(const SpriteDisplay &display,
+ bool forceDisplay)
+{
+ clear();
+
+ SpriteRefs it, it_end;
+
+ for (it = display.sprites.begin(), it_end = display.sprites.end();
+ it != it_end; it++)
+ {
+ std::string file = "graphics/sprites/" + (*it)->sprite;
+ int variant = (*it)->variant;
+ addSprite(AnimatedSprite::load(file, variant));
+ }
+
+ // Ensure that something is shown, if desired
+ if (size() == 0 && forceDisplay)
+ {
+ if (display.image.empty())
+ {
+ addSprite(AnimatedSprite::load("graphics/sprites/error.xml"));
+ }
+ else
+ {
+ ResourceManager *resman = ResourceManager::getInstance();
+ std::string imagePath = "graphics/items/" + display.image;
+ Image *img = resman->getImage(imagePath);
+
+ if (!img)
+ img = Theme::getImageFromTheme("unknown-item.png");
+
+ addSprite(new ImageSprite(img));
+ }
+ }
+
+ mChildParticleEffects.clear();
+
+ //setup particle effects
+ if (Particle::enabled && particleEngine)
+ {
+ std::list<std::string>::const_iterator it, it_end;
+ for (it = display.particles.begin(), it_end = display.particles.end();
+ it != it_end; it++)
+ {
+ Particle *p = particleEngine->addEffect(*it, 0, 0);
+ controlParticle(p);
+ }
+ }
+
+ mMustResetParticles = true;
+}
+
+void ActorSprite::load()
+{
+ if (loaded)
+ unload();
+
+ initTargetCursor();
+
+ loaded = true;
+}
+
+void ActorSprite::unload()
+{
+ if (!loaded)
+ return;
+
+ cleanupTargetCursors();
+ loaded = false;
+}
+
+void ActorSprite::addActorSpriteListener(ActorSpriteListener *listener)
+{
+ mActorSpriteListeners.push_front(listener);
+}
+
+void ActorSprite::removeActorSpriteListener(ActorSpriteListener *listener)
+{
+ mActorSpriteListeners.remove(listener);
+}
+
+static const char *cursorType(int type)
+{
+ switch (type)
+ {
+ case ActorSprite::TCT_IN_RANGE:
+ return "in-range";
+ default:
+ case ActorSprite::TCT_NORMAL:
+ return "normal";
+// default:
+// assert(false);
+ }
+}
+
+static const char *cursorSize(int size)
+{
+ switch (size)
+ {
+ case ActorSprite::TC_LARGE:
+ return "l";
+ case ActorSprite::TC_MEDIUM:
+ return "m";
+ default:
+ case ActorSprite::TC_SMALL:
+ return "s";
+// default:
+// assert(false);
+ }
+}
+
+void ActorSprite::initTargetCursor()
+{
+ static std::string targetCursor = "graphics/target-cursor-%s-%s.png";
+ static int targetWidths[NUM_TC] = {44, 62, 82};
+ static int targetHeights[NUM_TC] = {35, 44, 60};
+
+ // Load target cursors
+ for (int size = TC_SMALL; size < NUM_TC; size++)
+ {
+ for (int type = TCT_NORMAL; type < NUM_TCT; type++)
+ {
+ loadTargetCursor(strprintf(targetCursor.c_str(), cursorType(type),
+ cursorSize(size)), targetWidths[size],
+ targetHeights[size], type, size);
+ }
+ }
+}
+
+void ActorSprite::cleanupTargetCursors()
+{
+ for (int size = TC_SMALL; size < NUM_TC; size++)
+ {
+ for (int type = TCT_NORMAL; type < NUM_TCT; type++)
+ {
+ if (targetCursor[type][size])
+ {
+ delete targetCursor[type][size];
+ targetCursor[type][size] = 0;
+ }
+ if (targetCursorImages[type][size])
+ {
+ targetCursorImages[type][size]->decRef();
+ targetCursorImages[type][size] = 0;
+ }
+ }
+ }
+}
+
+void ActorSprite::loadTargetCursor(const std::string &filename,
+ int width, int height, int type, int size)
+{
+ if (size < TC_SMALL || size >= NUM_TC)
+ return;
+
+// assert(size > -1);
+// assert(size < 3);
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ ImageSet *currentImageSet = resman->getImageSet(filename, width, height);
+
+ if (!currentImageSet)
+ {
+ logger->log("Error loading target cursor: %s", filename.c_str());
+ return;
+ }
+
+ Animation *anim = new Animation;
+
+ for (unsigned int i = 0; i < currentImageSet->size(); ++i)
+ {
+// anim->addFrame(currentImageSet->get(i), 0,
+ anim->addFrame(currentImageSet->get(i), 75,
+ (16 - (currentImageSet->getWidth() / 2)),
+ (16 - (currentImageSet->getHeight() / 2)));
+ }
+
+ SimpleAnimation *currentCursor = new SimpleAnimation(anim);
+
+ if (targetCursor[type][size])
+ {
+ delete targetCursor[type][size];
+ targetCursor[type][size] = 0;
+ if (targetCursorImages[type][size])
+ targetCursorImages[type][size]->decRef();
+ }
+
+ targetCursorImages[type][size] = currentImageSet;
+ targetCursor[type][size] = currentCursor;
+}
diff --git a/src/actorsprite.h b/src/actorsprite.h
new file mode 100644
index 000000000..9d648355e
--- /dev/null
+++ b/src/actorsprite.h
@@ -0,0 +1,255 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ACTORSPRITE_H
+#define ACTORSPRITE_H
+
+#include "actor.h"
+#include "compoundsprite.h"
+#include "map.h"
+#include "particlecontainer.h"
+
+#include <SDL_types.h>
+
+#include <set>
+#include <list>
+
+class SimpleAnimation;
+class StatusEffect;
+class ActorSpriteListener;
+
+class ActorSprite : public CompoundSprite, public Actor
+{
+public:
+ enum Type
+ {
+ UNKNOWN = 0,
+ PLAYER,
+ NPC,
+ MONSTER,
+ FLOOR_ITEM,
+ PORTAL
+ };
+
+ enum TargetCursorSize
+ {
+ TC_SMALL = 0,
+ TC_MEDIUM,
+ TC_LARGE,
+ NUM_TC
+ };
+
+ enum TargetCursorType
+ {
+ TCT_NONE = -1,
+ TCT_NORMAL = 0,
+ TCT_IN_RANGE,
+ NUM_TCT
+ };
+
+ ActorSprite(int id);
+
+ ~ActorSprite();
+
+ int getId() const
+ { return mId; }
+
+ void setId(int id)
+ { mId = id; }
+
+ /**
+ * Returns the type of the ActorSprite.
+ */
+ virtual Type getType() const
+ { return UNKNOWN; }
+
+ virtual bool draw(Graphics *graphics, int offsetX, int offsetY) const;
+
+ virtual bool drawSpriteAt(Graphics *graphics, int x, int y) const;
+
+ virtual void logic();
+
+ static void actorLogic();
+
+ void setMap(Map* map);
+
+ /**
+ * Gets the way the object blocks pathfinding for other objects
+ */
+ virtual Map::BlockType getBlockType() const
+ { return Map::BLOCKTYPE_NONE; }
+
+ /**
+ * Take control of a particle.
+ */
+ void controlParticle(Particle *particle);
+
+ /**
+ * Returns the required size of a target cursor for this being.
+ */
+ virtual TargetCursorSize getTargetCursorSize() const
+ { return TC_MEDIUM; }
+
+ virtual int getTargetOffsetX() const
+ { return 0; }
+
+ virtual int getTargetOffsetY() const
+ { return 0; }
+
+ /**
+ * Sets the target animation for this actor.
+ */
+ void setTargetType(TargetCursorType type);
+
+ /**
+ * Untargets the actor.
+ */
+ void untarget() { mUsedTargetCursor = NULL; }
+
+ /**
+ * Triggers a visual effect, such as `level up'. Only draws the visual
+ * effect, does not play sound effects.
+ *
+ * \param effectId ID of the effect to trigger
+ */
+ virtual void triggerEffect(int effectId)
+ { internalTriggerEffect(effectId, false, true); }
+
+ /**
+ * Sets the actor's stun mode. If zero, the being is `normal', otherwise it
+ * is `stunned' in some fashion.
+ */
+ void setStunMode(Uint16 stunMode)
+ {
+ if (mStunMode != stunMode)
+ updateStunMode(mStunMode, stunMode);
+ mStunMode = stunMode;
+ }
+
+ void setStatusEffect(int index, bool active);
+
+ /**
+ * A status effect block is a 16 bit mask of status effects. We assign each
+ * such flag a block ID of offset + bitnr.
+ *
+ * These are NOT the same as the status effect indices.
+ */
+ void setStatusEffectBlock(int offset, Uint16 flags);
+
+ virtual void setAlpha(float alpha)
+ { CompoundSprite::setAlpha(alpha); }
+
+ virtual float getAlpha() const
+ { return CompoundSprite::getAlpha(); }
+
+ virtual int getWidth() const
+ { return CompoundSprite::getWidth(); }
+
+ virtual int getHeight() const
+ { return CompoundSprite::getHeight(); }
+
+ static void load();
+
+ static void unload();
+
+ /**
+ * Add an ActorSprite listener.
+ */
+ void addActorSpriteListener(ActorSpriteListener *listener);
+
+ /**
+ * Remove an ActorSprite listener.
+ */
+ void removeActorSpriteListener(ActorSpriteListener *listener);
+
+protected:
+ /**
+ * Trigger visual effect, with components
+ *
+ * \param effectId ID of the effect to trigger
+ * \param sfx Whether to trigger sound effects
+ * \param gfx Whether to trigger graphical effects
+ */
+ void internalTriggerEffect(int effectId, bool sfx, bool gfx);
+
+ /**
+ * Notify self that the stun mode has been updated. Invoked by
+ * setStunMode if something changed.
+ */
+ virtual void updateStunMode(int oldMode, int newMode);
+
+ /**
+ * Notify self that a status effect has flipped.
+ * The new flag is passed.
+ */
+ virtual void updateStatusEffect(int index, bool newStatus);
+
+ /**
+ * Handle an update to a status or stun effect
+ *
+ * \param The StatusEffect to effect
+ * \param effectId -1 for stun, otherwise the effect index
+ */
+ virtual void handleStatusEffect(StatusEffect *effect, int effectId);
+
+ void setupSpriteDisplay(const SpriteDisplay &display,
+ bool forceDisplay = true);
+
+ int mId;
+ Uint16 mStunMode; /**< Stun mode; zero if not stunned */
+ std::set<int> mStatusEffects; /**< set of active status effects */
+
+ ParticleList mStunParticleEffects;
+ ParticleVector mStatusParticleEffects;
+ ParticleList mChildParticleEffects;
+
+private:
+ /** Reset particle status effects on next redraw? */
+ bool mMustResetParticles;
+
+ /** Load the target cursors into memory */
+ static void initTargetCursor();
+
+ /** Remove the target cursors from memory */
+ static void cleanupTargetCursors();
+
+ /**
+ * Helper function for loading target cursors
+ */
+ static void loadTargetCursor(const std::string &filename,
+ int width, int height, int type, int size);
+
+ /** Images of the target cursor. */
+ static ImageSet *targetCursorImages[NUM_TCT][NUM_TC];
+
+ /** Animated target cursors. */
+ static SimpleAnimation *targetCursor[NUM_TCT][NUM_TC];
+
+ static bool loaded;
+
+ /** Target cursor being used */
+ SimpleAnimation *mUsedTargetCursor;
+
+ typedef std::list<ActorSpriteListener*> ActorSpriteListeners;
+ typedef ActorSpriteListeners::iterator ActorSpriteListenerIterator;
+ ActorSpriteListeners mActorSpriteListeners;
+};
+
+#endif // ACTORSPRITE_H
diff --git a/src/actorspritelistener.h b/src/actorspritelistener.h
new file mode 100644
index 000000000..994494f4f
--- /dev/null
+++ b/src/actorspritelistener.h
@@ -0,0 +1,42 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ACTORSPRITELISTENER_H
+#define ACTORSPRITELISTENER_H
+
+class ActorSprite;
+
+class ActorSpriteListener
+{
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~ActorSpriteListener() {}
+
+ /**
+ * Called when the ActorSprite has been destroyed. The listener will
+ * have to be registered first.
+ * @param actorSprite the ActorSprite being destroyed.
+ */
+ virtual void actorSpriteDestroyed(const ActorSprite &actorSprite) = 0;
+};
+
+#endif // ACTORSPRITELISTENER_H
diff --git a/src/actorspritemanager.cpp b/src/actorspritemanager.cpp
new file mode 100644
index 000000000..01eba1866
--- /dev/null
+++ b/src/actorspritemanager.cpp
@@ -0,0 +1,1081 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "actorspritemanager.h"
+
+#include "configuration.h"
+#include "localplayer.h"
+#include "log.h"
+#include "playerinfo.h"
+#include "playerrelations.h"
+
+#include "gui/widgets/chattab.h"
+#include "gui/killstats.h"
+#include "gui/chat.h"
+#include "gui/skilldialog.h"
+#include "gui/viewport.h"
+
+#include "utils/dtor.h"
+#include "utils/stringutils.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+
+#include <algorithm>
+#include <list>
+#include <vector>
+
+#define for_actors ActorSpritesConstIterator it, it_end; \
+for (it = mActors.begin(), it_end = mActors.end() ; it != it_end; it++)
+
+class FindBeingFunctor
+{
+ public:
+ bool operator() (ActorSprite *actor)
+ {
+ if (!actor || actor->getType() == ActorSprite::FLOOR_ITEM
+ || actor->getType() == ActorSprite::PORTAL)
+ {
+ return false;
+ }
+ Being* b = static_cast<Being*>(actor);
+
+ unsigned other_y = y + ((b->getType()
+ == ActorSprite::NPC) ? 1 : 0);
+ const Vector &pos = b->getPosition();
+ return (static_cast<unsigned>(pos.x) / 32 == x &&
+ (static_cast<unsigned>(pos.y) / 32 == y
+ || static_cast<unsigned>(pos.y) / 32 == other_y) &&
+ b->isAlive() && (type == ActorSprite::UNKNOWN
+ || b->getType() == type));
+ }
+
+ Uint16 x, y;
+ ActorSprite::Type type;
+} beingFinder;
+
+class FindBeingEqualFunctor
+{
+ public:
+ bool operator() (Being *being)
+ {
+ if (!being || !findBeing)
+ return false;
+ return being->getId() == findBeing->getId();
+ }
+
+ Being *findBeing;
+} beingEqualFinder;
+
+class SortBeingFunctor
+{
+ public:
+ bool operator() (Being* being1, Being* being2)
+ {
+ if (!being1 || !being2)
+ return false;
+
+ if (being1->getDistance() != being2->getDistance())
+ return being1->getDistance() < being2->getDistance();
+
+ int d1, d2;
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ const Vector &pos1 = being1->getPosition();
+ d1 = abs(((int) pos1.x) - x) + abs(((int) pos1.y) - y);
+ const Vector &pos2 = being2->getPosition();
+ d2 = abs(((int) pos2.x) - x) + abs(((int) pos2.y) - y);
+ }
+ else
+ {
+ d1 = abs(being1->getTileX() - x) + abs(being1->getTileY() - y);
+ d2 = abs(being2->getTileX() - x) + abs(being2->getTileY() - y);
+ }
+
+ if (d1 != d2)
+ return d1 < d2;
+ return (being1->getName() < being2->getName());
+ }
+ int x, y;
+
+} beingSorter;
+
+ActorSpriteManager::ActorSpriteManager() :
+ mMap(0)
+{
+ mSpellHeal1 = serverConfig.getValue("spellHeal1", "#lum");
+ mSpellHeal2 = serverConfig.getValue("spellHeal2", "#inma");
+ mSpellItenplz = serverConfig.getValue("spellItenplz", "#itenplz");
+ mTargetDeadPlayers = config.getBoolValue("targetDeadPlayers");
+ mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable");
+ mCyclePlayers = config.getBoolValue("cyclePlayers");
+ mCycleMonsters = config.getBoolValue("cycleMonsters");
+
+ config.addListener("targetDeadPlayers", this);
+ config.addListener("targetOnlyReachable", this);
+ config.addListener("cyclePlayers", this);
+ config.addListener("cycleMonsters", this);
+}
+
+ActorSpriteManager::~ActorSpriteManager()
+{
+ config.removeListener("targetDeadPlayers", this);
+ config.removeListener("targetOnlyReachable", this);
+ config.removeListener("cyclePlayers", this);
+ config.removeListener("cycleMonsters", this);
+ clear();
+}
+
+void ActorSpriteManager::setMap(Map *map)
+{
+ mMap = map;
+
+ if (player_node)
+ player_node->setMap(map);
+}
+
+void ActorSpriteManager::setPlayer(LocalPlayer *player)
+{
+ player_node = player;
+ mActors.insert(player);
+}
+
+Being *ActorSpriteManager::createBeing(int id, ActorSprite::Type type,
+ Uint16 subtype)
+{
+/*
+ for_actors
+ {
+ if ((*it)->getId() == id && (*it)->getType() == type)
+ {
+ if ((*it) && (*it)->getType() == Being::PLAYER)
+ static_cast<Being*>(*it)->addToCache();
+ if (player_node)
+ {
+ if (player_node->getTarget() == *it)
+ player_node->setTarget(0);
+ if (player_node->getPickUpTarget() == *it)
+ player_node->unSetPickUpTarget();
+ }
+ if (viewport)
+ viewport->clearHover(*it);
+ mActors.erase(*it);
+ delete *it;
+ break;
+ }
+ }
+*/
+ Being *being = new Being(id, type, subtype, mMap);
+
+ mActors.insert(being);
+ return being;
+}
+
+FloorItem *ActorSpriteManager::createItem(int id, int itemId,
+ int x, int y, int amount)
+{
+ FloorItem *floorItem = new FloorItem(id, itemId, x, y, mMap, amount);
+
+ mActors.insert(floorItem);
+ return floorItem;
+}
+
+void ActorSpriteManager::destroy(ActorSprite *actor)
+{
+ if (!actor || actor == player_node)
+ return;
+
+ mDeleteActors.insert(actor);
+}
+
+void ActorSpriteManager::erase(ActorSprite *actor)
+{
+ if (!actor || actor == player_node)
+ return;
+
+ mActors.erase(actor);
+}
+
+void ActorSpriteManager::undelete(ActorSprite *actor)
+{
+ if (!actor || actor == player_node)
+ return;
+
+ ActorSpritesConstIterator it, it_end;
+
+ for (it = mDeleteActors.begin(), it_end = mDeleteActors.end();
+ it != it_end; ++it)
+ {
+ ActorSprite *actor = *it;
+ if (*it == actor)
+ {
+ mDeleteActors.erase(*it);
+ return;
+ }
+ }
+}
+
+Being *ActorSpriteManager::findBeing(int id) const
+{
+ for_actors
+ {
+ ActorSprite *actor = *it;
+ if (actor->getId() == id &&
+ actor->getType() != ActorSprite::FLOOR_ITEM)
+ {
+ return static_cast<Being*>(actor);
+ }
+ }
+
+ return NULL;
+}
+
+Being *ActorSpriteManager::findBeing(int x, int y,
+ ActorSprite::Type type) const
+{
+ beingFinder.x = static_cast<Uint16>(x);
+ beingFinder.y = static_cast<Uint16>(y);
+ beingFinder.type = type;
+
+ ActorSpritesConstIterator it = find_if(mActors.begin(), mActors.end(),
+ beingFinder);
+
+ return (it == mActors.end()) ? NULL : static_cast<Being*>(*it);
+}
+
+Being *ActorSpriteManager::findBeingByPixel(int x, int y,
+ bool allPlayers) const
+{
+ if (!mMap)
+ return NULL;
+
+ bool targetDead = mTargetDeadPlayers;
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+
+ int xtol = 16;
+ int uptol = 32;
+
+ if ((being->isAlive()
+ || (targetDead && being->getType() == Being::PLAYER))
+ && (allPlayers || being != player_node))
+ {
+
+ if ((being->getPixelX() - xtol <= x) &&
+ (being->getPixelX() + xtol > x) &&
+ (being->getPixelY() - uptol <= y) &&
+ (being->getPixelY() > y))
+ {
+ return being;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void ActorSpriteManager::findBeingsByPixel(std::list<Being*> &beings,
+ int x, int y, bool allPlayers) const
+{
+ if (!mMap)
+ return;
+
+ bool targetDead = mTargetDeadPlayers;
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+
+ int xtol = 16;
+ int uptol = 32;
+
+ if ((being->isAlive()
+ || (targetDead && being->getType() == Being::PLAYER))
+ && (allPlayers || being != player_node))
+ {
+
+ if ((being->getPixelX() - xtol <= x) &&
+ (being->getPixelX() + xtol > x) &&
+ (being->getPixelY() - uptol <= y) &&
+ (being->getPixelY() > y))
+ {
+ beings.push_back(being);
+ }
+ }
+ }
+}
+
+Being *ActorSpriteManager::findPortalByTile(int x, int y) const
+{
+ if (!mMap)
+ return NULL;
+
+ for_actors
+ {
+ if ((*it)->getType() != ActorSprite::PORTAL)
+ continue;
+
+ Being *being = static_cast<Being*>(*it);
+
+ if (being->getTileX() == x && being->getTileY() == y)
+ return being;
+ }
+
+ return NULL;
+}
+
+FloorItem *ActorSpriteManager::findItem(int id) const
+{
+ for_actors
+ {
+ if ((*it)->getId() == id &&
+ (*it)->getType() == ActorSprite::FLOOR_ITEM)
+ {
+ return static_cast<FloorItem*>(*it);
+ }
+ }
+
+ return NULL;
+}
+
+FloorItem *ActorSpriteManager::findItem(int x, int y) const
+{
+ for_actors
+ {
+ if ((*it)->getTileX() == x && (*it)->getTileY() == y &&
+ (*it)->getType() == ActorSprite::FLOOR_ITEM)
+ {
+ return static_cast<FloorItem*>(*it);
+ }
+ }
+
+ return NULL;
+}
+
+bool ActorSpriteManager::pickUpAll(int x1, int y1, int x2, int y2,
+ bool serverBuggy)
+{
+ if (!player_node)
+ return false;
+
+ bool finded(false);
+ if (!serverBuggy)
+ {
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ && ((*it)->getTileX() >= x1 && (*it)->getTileX() <= x2)
+ && ((*it)->getTileY() >= y1 && (*it)->getTileY() <= y2))
+ {
+ if (player_node->pickUp(static_cast<FloorItem*>(*it)))
+ finded = true;
+ }
+ }
+ }
+ else if (Client::checkPackets(PACKET_PICKUP))
+ {
+ FloorItem *item = 0;
+ unsigned cnt = 65535;
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ && ((*it)->getTileX() >= x1 && (*it)->getTileX() <= x2)
+ && ((*it)->getTileY() >= y1 && (*it)->getTileY() <= y2))
+ {
+ FloorItem *tempItem = static_cast<FloorItem*>(*it);
+ if (tempItem->getPickupCount() < cnt)
+ {
+ item = tempItem;
+ cnt = item->getPickupCount();
+ if (cnt == 0)
+ {
+ item->incrementPickup();
+ player_node->pickUp(item);
+ return true;
+ }
+ }
+ }
+ }
+ if (item && player_node->pickUp(item))
+ finded = true;
+ }
+ return finded;
+}
+
+bool ActorSpriteManager::pickUpNearest(int x, int y, int maxdist)
+{
+ if (!player_node)
+ return false;
+
+ maxdist = maxdist * maxdist;
+ FloorItem *closestItem = NULL;
+ int dist = 0;
+
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM)
+ {
+ FloorItem *item = static_cast<FloorItem*>(*it);
+
+ int d = (item->getTileX() - x) * (item->getTileX() - x)
+ + (item->getTileY() - y) * (item->getTileY() - y);
+
+ if ((d < dist || !closestItem) && (!mTargetOnlyReachable
+ || player_node->isReachable(item->getTileX(),
+ item->getTileY())))
+ {
+ dist = d;
+ closestItem = item;
+ }
+ }
+ }
+ if (closestItem && player_node && dist <= maxdist)
+ return player_node->pickUp(closestItem);
+
+ return false;
+}
+
+Being *ActorSpriteManager::findBeingByName(const std::string &name,
+ ActorSprite::Type type) const
+{
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+ if (being->getName() == name &&
+ (type == ActorSprite::UNKNOWN || type == being->getType()))
+ {
+ return being;
+ }
+ }
+ return NULL;
+}
+
+Being *ActorSpriteManager::findNearestByName(const std::string &name,
+ Being::Type type) const
+{
+ if (!player_node)
+ return 0;
+
+ int dist = 0;
+ Being* closestBeing = NULL;
+ int x, y;
+
+ x = player_node->getTileX();
+ y = player_node->getTileY();
+
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+
+ if (being && being->getName() == name &&
+ (type == Being::UNKNOWN || type == being->getType()))
+ {
+ if (being->getType() == Being::PLAYER)
+ return being;
+ else
+ {
+ int d = (being->getTileX() - x) * (being->getTileX() - x)
+ + (being->getTileY() - y) * (being->getTileY() - y);
+
+ if (validateBeing(0, being, type, 0, 50)
+ && (d < dist || closestBeing == NULL))
+ {
+ dist = d;
+ closestBeing = being;
+ }
+ }
+ }
+ }
+ return closestBeing;
+}
+
+const ActorSprites &ActorSpriteManager::getAll() const
+{
+ return mActors;
+}
+
+void ActorSpriteManager::logic()
+{
+ for_actors
+ (*it)->logic();
+
+ if (mDeleteActors.empty())
+ return;
+
+ for (it = mDeleteActors.begin(), it_end = mDeleteActors.end();
+ it != it_end; ++it)
+ {
+ if ((*it) && (*it)->getType() == Being::PLAYER)
+ static_cast<Being*>(*it)->addToCache();
+ if (player_node)
+ {
+ if (player_node->getTarget() == *it)
+ player_node->setTarget(0);
+ if (player_node->getPickUpTarget() == *it)
+ player_node->unSetPickUpTarget();
+ }
+ if (viewport)
+ viewport->clearHover(*it);
+ }
+
+ for (it = mDeleteActors.begin(), it_end = mDeleteActors.end();
+ it != it_end; ++it)
+ {
+ mActors.erase(*it);
+ delete *it;
+ }
+
+ mDeleteActors.clear();
+}
+
+void ActorSpriteManager::clear()
+{
+ if (player_node)
+ {
+ player_node->setTarget(0);
+ mActors.erase(player_node);
+ }
+
+ for_actors
+ {
+ delete *it;
+ }
+ mActors.clear();
+ mDeleteActors.clear();
+
+ if (player_node)
+ mActors.insert(player_node);
+}
+
+Being *ActorSpriteManager::findNearestLivingBeing(int x, int y,
+ int maxTileDist,
+ ActorSprite::Type type,
+ Being *excluded) const
+{
+ //Being *closestBeing = 0;
+ //int dist = 0;
+
+ const int maxDist = maxTileDist * 32;
+
+ return findNearestLivingBeing(NULL, maxDist, type, x, y, excluded);
+
+/*
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM)
+ continue;
+
+ Being *being = static_cast<Being*>(*it);
+ const Vector &pos = being->getPosition();
+ int d = abs(((int) pos.x) - x) + abs(((int) pos.y) - y);
+
+ if ((being->getType() == type || type == ActorSprite::UNKNOWN)
+ && (d < dist || !closestBeing) // it is closer
+ && being->isAlive() // no dead beings
+ && being != excluded)
+ {
+ dist = d;
+ closestBeing = being;
+ }
+ }
+
+ return (maxDist >= dist) ? closestBeing : 0;
+*/
+}
+
+Being *ActorSpriteManager::findNearestLivingBeing(Being *aroundBeing,
+ int maxDist,
+ Being::Type type) const
+{
+ if (!aroundBeing)
+ return 0;
+
+ int x = aroundBeing->getTileX();
+ int y = aroundBeing->getTileY();
+
+ return findNearestLivingBeing(aroundBeing, maxDist, type,
+ x, y, aroundBeing);
+}
+
+Being *ActorSpriteManager::findNearestLivingBeing(Being *aroundBeing,
+ int maxDist,
+ Being::Type type,
+ int x, int y,
+ Being *excluded) const
+{
+ if (!aroundBeing || !player_node)
+ return 0;
+
+ Being *closestBeing = 0;
+ int dist = 0;
+
+ maxDist = maxDist * maxDist;
+
+ bool cycleSelect = (mCyclePlayers && type == Being::PLAYER)
+ || (mCycleMonsters && type == Being::MONSTER);
+
+ if (cycleSelect)
+ {
+ std::vector<Being*> sortedBeings;
+
+ for (ActorSprites::const_iterator i = mActors.begin(),
+ i_end = mActors.end();
+ i != i_end; ++i)
+ {
+ if ((*i)->getType() == ActorSprite::FLOOR_ITEM
+ || (*i)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*i);
+
+ if (validateBeing(aroundBeing, being, type, 0, maxDist))
+ {
+ if (being != excluded)
+ sortedBeings.push_back(being);
+ }
+ }
+
+ // no selectable beings
+ if (sortedBeings.empty())
+ return 0;
+
+ beingSorter.x = x;
+ beingSorter.y = y;
+ sort(sortedBeings.begin(), sortedBeings.end(), beingSorter);
+
+ if (player_node->getTarget() == NULL)
+ {
+ // if no selected being, return first nearest being
+ return sortedBeings.at(0);
+ }
+
+ beingEqualFinder.findBeing = player_node->getTarget();
+ std::vector<Being*>::const_iterator i = find_if(sortedBeings.begin(),
+ sortedBeings.end(), beingEqualFinder);
+
+ if (i == sortedBeings.end() || ++i == sortedBeings.end())
+ {
+ // if no selected being in vector, return first nearest being
+ return sortedBeings.at(0);
+ }
+
+ // we find next being after target
+ return *i;
+ }
+ else
+ {
+ for (ActorSprites::const_iterator i = mActors.begin(),
+ i_end = mActors.end();
+ i != i_end; ++i)
+ {
+ if ((*i)->getType() == ActorSprite::FLOOR_ITEM
+ || (*i)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+ Being *being = static_cast<Being*>(*i);
+
+// Being *being = (*i);
+
+ bool valid = validateBeing(aroundBeing, being, type, excluded, 50);
+ int d = being->getDistance();
+ if (being->getType() != Being::MONSTER
+ || !mTargetOnlyReachable)
+ { // if distance not calculated, use old distance
+ d = (being->getTileX() - x) * (being->getTileX() - x)
+ + (being->getTileY() - y) * (being->getTileY() - y);
+ }
+
+// logger->log("being name:" + being->getName());
+// logger->log("d:" + toString(d));
+// logger->log("valid:" + toString(valid));
+
+ if (valid && (d < dist || closestBeing == 0))
+ {
+// if ((being->getType() == type || type == Being::UNKNOWN)
+// && (d < dist || closestBeing == NULL) // it is closer
+// && (being->mAction != Being::DEAD // no dead beings
+// || (config.getValue("targetDeadPlayers", false) && type == Being::PLAYER))
+// && being != aroundBeing)
+// {
+ dist = d;
+ closestBeing = being;
+ }
+ }
+ return (maxDist >= dist) ? closestBeing : 0;
+ }
+}
+
+bool ActorSpriteManager::validateBeing(Being *aroundBeing, Being* being,
+ Being::Type type, Being* excluded,
+ int maxCost) const
+{
+ return being && ((being->getType() == type
+ || type == Being::UNKNOWN) && (being->isAlive()
+ || (mTargetDeadPlayers && type == Being::PLAYER))
+ && being != aroundBeing) && being != excluded
+ && (type != Being::MONSTER || !mTargetOnlyReachable
+ || player_node->isReachable(being, maxCost));
+}
+
+void ActorSpriteManager::healTarget(LocalPlayer* player_node)
+{
+ if (!player_node)
+ return;
+
+ heal(player_node, player_node->getTarget());
+}
+
+void ActorSpriteManager::heal(LocalPlayer* player_node, Being* target)
+{
+ if (!player_node || !chatWindow || !player_node->isAlive()
+ || !Net::getPlayerHandler()->canUseMagic())
+ {
+ return;
+ }
+
+ if (target && player_node->getName() == target->getName())
+ {
+ if (PlayerInfo::getAttribute(MP) >= 6
+ && PlayerInfo::getAttribute(HP)
+ != PlayerInfo::getAttribute(MAX_HP))
+ {
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+ chatWindow->localChatInput(mSpellHeal1);
+ }
+ }
+ else if (PlayerInfo::getStatEffective(340) < 2
+ || PlayerInfo::getStatEffective(341) < 2)
+ {
+ if (PlayerInfo::getAttribute(MP) >= 6)
+ {
+ if (target && target->getType() != Being::MONSTER)
+ {
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+ chatWindow->localChatInput(mSpellHeal1 + " "
+ + target->getName());
+ }
+ else if (PlayerInfo::getAttribute(HP)
+ != PlayerInfo::getAttribute(MAX_HP))
+ {
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+ chatWindow->localChatInput(mSpellHeal1);
+ }
+ }
+ }
+ else
+ {
+ if (PlayerInfo::getAttribute(MP) >= 10 && target
+ && target->getType() != Being::MONSTER)
+ {
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+ chatWindow->localChatInput(mSpellHeal2 + " " + target->getName());
+ }
+ else if ((!target || target->getType() == Being::MONSTER)
+ && PlayerInfo::getAttribute(MP) >= 6
+ && PlayerInfo::getAttribute(HP)
+ != PlayerInfo::getAttribute(MAX_HP))
+ {
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+ chatWindow->localChatInput(mSpellHeal1);
+ }
+ }
+}
+
+void ActorSpriteManager::itenplz()
+{
+ if (!player_node || !chatWindow || !player_node->isAlive()
+ || !Net::getPlayerHandler()->canUseMagic())
+ {
+ return;
+ }
+
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+
+ chatWindow->localChatInput(mSpellItenplz);
+}
+
+bool ActorSpriteManager::hasActorSprite(ActorSprite *actor) const
+{
+ for_actors
+ {
+ if (actor == *it)
+ return true;
+ }
+
+ return false;
+}
+
+void ActorSpriteManager::addBlock(Uint32 id)
+{
+ bool alreadyBlocked(false);
+ for (int i = 0; i < (int)blockedBeings.size(); i++)
+ {
+ if (id == blockedBeings.at(i))
+ {
+ alreadyBlocked = true;
+ break;
+ }
+ }
+ if (alreadyBlocked == false)
+ blockedBeings.push_back(id);
+}
+
+void ActorSpriteManager::deleteBlock(Uint32 id)
+{
+ std::vector<Uint32>::iterator iter = blockedBeings.begin();
+ while (iter != blockedBeings.end())
+ {
+ if (*iter == id)
+ {
+ iter = blockedBeings.erase(iter);
+ break;
+ }
+ }
+}
+
+bool ActorSpriteManager::isBlocked(Uint32 id)
+{
+ bool blocked(false);
+ for (int i = 0; i < (int)blockedBeings.size(); i++)
+ {
+ if (id == blockedBeings.at(i))
+ {
+ blocked = true;
+ break;
+ }
+ }
+ return blocked;
+}
+
+void ActorSpriteManager::printAllToChat() const
+{
+ printBeingsToChat(getAll(), "Visible on map");
+}
+
+void ActorSpriteManager::printBeingsToChat(ActorSprites beings,
+ std::string header) const
+{
+ if (!debugChatTab)
+ return;
+
+ debugChatTab->chatLog("---------------------------------------");
+ debugChatTab->chatLog(header);
+ std::set<ActorSprite*>::iterator it;
+ for (it = beings.begin(); it != beings.end(); ++it)
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM)
+ continue;
+
+ const Being *being = static_cast<Being*>(*it);
+
+ debugChatTab->chatLog(being->getName()
+ + " (" + toString(being->getTileX()) + ","
+ + toString(being->getTileY()) + ") "
+ + toString(being->getSubType()), BY_SERVER);
+ }
+ debugChatTab->chatLog("---------------------------------------");
+}
+
+void ActorSpriteManager::printBeingsToChat(std::vector<Being*> beings,
+ std::string header) const
+{
+ if (!debugChatTab)
+ return;
+
+ debugChatTab->chatLog("---------------------------------------");
+ debugChatTab->chatLog(header);
+
+ std::vector<Being*>::iterator i;
+ for (i = beings.begin(); i != beings.end(); ++i)
+ {
+ const Being *being = *i;
+
+ debugChatTab->chatLog(being->getName()
+ + " (" + toString(being->getTileX()) + ","
+ + toString(being->getTileY()) + ") "
+ + toString(being->getSubType()), BY_SERVER);
+ }
+ debugChatTab->chatLog("---------------------------------------");
+}
+
+void ActorSpriteManager::getPlayerNames(std::vector<std::string> &names,
+ bool npcNames)
+{
+ names.clear();
+
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+ if ((being->getType() == ActorSprite::PLAYER
+ || (being->getType() == ActorSprite::NPC && npcNames))
+ && being->getName() != "")
+ {
+ names.push_back(being->getName());
+ }
+ }
+}
+
+void ActorSpriteManager::getMobNames(std::vector<std::string> &names)
+{
+ names.clear();
+
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+ if (being->getType() == ActorSprite::MONSTER && being->getName() != "")
+ names.push_back(being->getName());
+ }
+}
+
+void ActorSpriteManager::updatePlayerNames()
+{
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+ if (being->getType() == ActorSprite::PLAYER && being->getName() != "")
+ being->updateName();
+ }
+}
+
+void ActorSpriteManager::updatePlayerColors()
+{
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+ if (being->getType() == ActorSprite::PLAYER && being->getName() != "")
+ being->updateColors();
+ }
+}
+
+void ActorSpriteManager::updatePlayerGuild()
+{
+ for_actors
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM
+ || (*it)->getType() == ActorSprite::PORTAL)
+ {
+ continue;
+ }
+
+ Being *being = static_cast<Being*>(*it);
+ if (being->getType() == ActorSprite::PLAYER && being->getName() != "")
+ being->updateGuild();
+ }
+}
+
+void ActorSpriteManager::parseLevels(std::string levels)
+{
+ levels += ", ";
+ unsigned int f = 0;
+ unsigned long pos = 0;
+ const std::string brkEnd = "), ";
+
+ pos = levels.find(brkEnd, f);
+ while (pos != std::string::npos)
+ {
+ std::string part = levels.substr(f, pos - f);
+ if (part.empty())
+ break;
+ unsigned long bktPos = part.rfind("(");
+ if (bktPos != std::string::npos)
+ {
+ Being *being = findBeingByName(part.substr(0, bktPos),
+ Being::PLAYER);
+ if (being)
+ {
+ being->setLevel(atoi(part.substr(bktPos + 1).c_str()));
+ being->addToCache();
+ }
+ }
+ f = static_cast<int>(pos + brkEnd.length());
+ pos = levels.find(brkEnd, f);
+ }
+ updatePlayerNames();
+}
+
+void ActorSpriteManager::optionChanged(const std::string &name)
+{
+ if (name == "targetDeadPlayers")
+ mTargetDeadPlayers = config.getBoolValue("targetDeadPlayers");
+ else if (name == "targetOnlyReachable")
+ mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable");
+ else if (name == "cyclePlayers")
+ mCyclePlayers = config.getBoolValue("cyclePlayers");
+ else if (name == "cycleMonsters")
+ mCycleMonsters = config.getBoolValue("cycleMonsters");
+} \ No newline at end of file
diff --git a/src/actorspritemanager.h b/src/actorspritemanager.h
new file mode 100644
index 000000000..e42bdf5bc
--- /dev/null
+++ b/src/actorspritemanager.h
@@ -0,0 +1,253 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ACTORSPRITEMANAGER_H
+#define ACTORSPRITEMANAGER_H
+
+#include "actorsprite.h"
+#include "being.h"
+#include "configlistener.h"
+#include "flooritem.h"
+
+#include <vector>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class LocalPlayer;
+class Map;
+
+typedef std::set<ActorSprite*> ActorSprites;
+typedef ActorSprites::iterator ActorSpritesIterator;
+typedef ActorSprites::const_iterator ActorSpritesConstIterator;
+
+class ActorSpriteManager: public ConfigListener
+{
+ public:
+ ActorSpriteManager();
+
+ ~ActorSpriteManager();
+
+ /**
+ * Sets the map on which ActorSprites are created.
+ */
+ void setMap(Map *map);
+
+ /**
+ * Sets the current player.
+ */
+ void setPlayer(LocalPlayer *player);
+
+ /**
+ * Create a Being and add it to the list of ActorSprites.
+ */
+ Being *createBeing(int id, ActorSprite::Type type, Uint16 subtype);
+
+ /**
+ * Create a FloorItem and add it to the list of ActorSprites.
+ */
+ FloorItem *createItem(int id, int itemId, int x, int y, int amount);
+
+ /**
+ * Destroys the given ActorSprite at the end of
+ * ActorSpriteManager::logic.
+ */
+ void destroy(ActorSprite *actor);
+
+ void erase(ActorSprite *actor);
+
+ void undelete(ActorSprite *actor);
+
+ /**
+ * Returns a specific Being, by id;
+ */
+ Being *findBeing(int id) const;
+
+ /**
+ * Returns a being at specific coordinates.
+ */
+ Being *findBeing(int x, int y,
+ ActorSprite::Type type = ActorSprite::UNKNOWN) const;
+
+ /**
+ * Returns a being at the specific pixel.
+ */
+ Being *findBeingByPixel(int x, int y, bool allPlayers = false) const;
+
+ /**
+ * Returns a beings at the specific pixel.
+ */
+ void findBeingsByPixel(std::list<Being*> &beings, int x, int y,
+ bool allPlayers) const;
+
+ /**
+ * Returns a portal at the specific tile.
+ */
+ Being *findPortalByTile(int x, int y) const;
+
+ /**
+ * Returns a specific FloorItem, by id.
+ */
+ FloorItem *findItem(int id) const;
+
+ /**
+ * Returns a FloorItem at specific coordinates.
+ */
+ FloorItem *findItem(int x, int y) const;
+
+ /**
+ * Returns a being nearest to specific coordinates.
+ *
+ * @param x X coordinate in pixels.
+ * @param y Y coordinate in pixels.
+ * @param maxTileDist Maximal distance in tiles. If minimal distance is
+ * larger, no being is returned.
+ * @param type The type of being to look for.
+ */
+ Being *findNearestLivingBeing(int x, int y, int maxTileDist,
+ ActorSprite::Type type = Being::UNKNOWN,
+ Being *excluded = 0) const;
+
+ /**
+ * Returns a being nearest to another being.
+ *
+ * @param aroundBeing The being to search around.
+ * @param maxTileDist Maximal distance in tiles. If minimal distance is
+ * larger, no being is returned.
+ * @param type The type of being to look for.
+ */
+ Being *findNearestLivingBeing(Being *aroundBeing, int maxTileDist,
+ ActorSprite::Type type = Being::UNKNOWN
+ ) const;
+
+ /**
+ * Finds a being by name and (optionally) by type.
+ */
+ Being *findBeingByName(const std::string &name,
+ ActorSprite::Type type = Being::UNKNOWN) const;
+
+ /**
+ * Finds a nearest being by name and (optionally) by type.
+ */
+ Being *findNearestByName(const std::string &name,
+ Being::Type type = Being::UNKNOWN) const;
+
+ /**
+ * Heal all players in distance.
+ *
+ * \param maxdist maximal distance. If minimal distance is larger,
+ * no being is returned
+ */
+// void HealAllTargets(Being *aroundBeing, int maxdist,
+// Being::Type type) const;
+
+ void healTarget(LocalPlayer* player_node);
+
+ void heal(LocalPlayer* player_node, Being* target);
+
+ void itenplz();
+
+ /**
+ * Returns the whole list of beings.
+ */
+ const ActorSprites &getAll() const;
+
+ /**
+ * Returns true if the given ActorSprite is in the manager's list,
+ * false otherwise.
+ *
+ * \param actor the ActorSprite to search for
+ */
+ bool hasActorSprite(ActorSprite *actor) const;
+
+ /**
+ * Performs ActorSprite logic and deletes ActorSprite scheduled to be
+ * deleted.
+ */
+ void logic();
+
+ /**
+ * Destroys all ActorSprites except the local player
+ */
+ void clear();
+
+ std::vector<Uint32> blockedBeings;
+
+ void addBlock(Uint32 id);
+
+ void deleteBlock(Uint32 id);
+
+ bool isBlocked(Uint32 id);
+
+ void printAllToChat() const;
+
+ void printBeingsToChat(ActorSprites beings, std::string header) const;
+
+ void printBeingsToChat(std::vector<Being*> beings,
+ std::string header) const;
+
+ void getPlayerNames(std::vector<std::string> &names,
+ bool npcNames);
+
+ void getMobNames(std::vector<std::string> &names);
+
+ void updatePlayerNames();
+
+ void updatePlayerColors();
+
+ void updatePlayerGuild();
+
+ void parseLevels(std::string levels);
+
+ bool pickUpAll(int x1, int y1, int x2, int y2,
+ bool serverBuggy = false);
+
+ bool pickUpNearest(int x, int y, int maxdist);
+
+ void optionChanged(const std::string &name);
+
+ protected:
+ bool validateBeing(Being *aroundBeing, Being* being,
+ Being::Type type, Being* excluded = 0,
+ int maxCost = 20) const;
+
+ Being *findNearestLivingBeing(Being *aroundBeing, int maxdist,
+ Being::Type type, int x, int y,
+ Being *excluded = 0) const;
+
+ ActorSprites mActors;
+ ActorSprites mDeleteActors;
+ Map *mMap;
+ std::string mSpellHeal1;
+ std::string mSpellHeal2;
+ std::string mSpellItenplz;
+ bool mTargetDeadPlayers;
+ bool mTargetOnlyReachable;
+ bool mCyclePlayers;
+ bool mCycleMonsters;
+};
+
+extern ActorSpriteManager *actorSpriteManager;
+
+#endif // ACTORSPRITEMANAGER_H
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
new file mode 100644
index 000000000..327e9958e
--- /dev/null
+++ b/src/animatedsprite.cpp
@@ -0,0 +1,241 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "animatedsprite.h"
+
+#include "graphics.h"
+#include "log.h"
+
+#include "resources/action.h"
+#include "resources/animation.h"
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/xml.h"
+
+#include <cassert>
+
+AnimatedSprite::AnimatedSprite(SpriteDef *sprite):
+ mDirection(DIRECTION_DOWN),
+ mLastTime(0),
+ mFrameIndex(0),
+ mFrameTime(0),
+ mSprite(sprite),
+ mAction(0),
+ mAnimation(0),
+ mFrame(0)
+{
+// assert(mSprite);
+
+ mAlpha = 1.0f;
+
+ // Take possession of the sprite
+ if (mSprite)
+ mSprite->incRef();
+
+ // Play the stand animation by default
+ play(SpriteAction::STAND);
+}
+
+AnimatedSprite *AnimatedSprite::load(const std::string &filename, int variant)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ SpriteDef *s = resman->getSprite(filename, variant);
+ if (!s)
+ return 0;
+ AnimatedSprite *as = new AnimatedSprite(s);
+ s->decRef();
+ return as;
+}
+
+AnimatedSprite::~AnimatedSprite()
+{
+ if (mSprite)
+ mSprite->decRef();
+}
+
+bool AnimatedSprite::reset()
+{
+ bool ret = mFrameIndex !=0 || mFrameTime != 0 || mLastTime != 0;
+
+ mFrameIndex = 0;
+ mFrameTime = 0;
+ mLastTime = 0;
+
+ return ret;
+}
+
+bool AnimatedSprite::play(std::string spriteAction)
+{
+ if (!mSprite)
+ return false;
+
+ Action *action = mSprite->getAction(spriteAction);
+ if (!action)
+ return false;
+
+ mAction = action;
+ Animation *animation = mAction->getAnimation(mDirection);
+
+ if (animation && animation != mAnimation && animation->getLength() > 0)
+ {
+ mAnimation = animation;
+ mFrame = mAnimation->getFrame(0);
+
+ reset();
+
+ return true;
+ }
+
+ return false;
+}
+
+bool AnimatedSprite::update(int time)
+{
+ // Avoid freaking out at first frame or when tick_time overflows
+ if (time < mLastTime || mLastTime == 0)
+ mLastTime = time;
+
+ // If not enough time has passed yet, do nothing
+ if (time <= mLastTime || !mAnimation)
+ return false;
+
+ unsigned int dt = time - mLastTime;
+ mLastTime = time;
+
+ Animation *animation = mAnimation;
+ Frame *frame = mFrame;
+
+ if (!updateCurrentAnimation(dt))
+ {
+ // Animation finished, reset to default
+ play(SpriteAction::STAND);
+ }
+
+ // Make sure something actually changed
+ return animation != mAnimation || frame != mFrame;
+}
+
+bool AnimatedSprite::updateCurrentAnimation(unsigned int time)
+{
+ if (!mFrame || !mAnimation || Animation::isTerminator(*mFrame))
+ return false;
+
+ mFrameTime += time;
+
+ while (mFrameTime > (unsigned)mFrame->delay && mFrame->delay > 0)
+ {
+ mFrameTime -= (unsigned)mFrame->delay;
+ mFrameIndex++;
+
+ if (mFrameIndex == mAnimation->getLength())
+ mFrameIndex = 0;
+
+ mFrame = mAnimation->getFrame(mFrameIndex);
+
+ if (Animation::isTerminator(*mFrame))
+ {
+ mAnimation = 0;
+ mFrame = 0;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool AnimatedSprite::draw(Graphics *graphics, int posX, int posY) const
+{
+ if (!mFrame || !mFrame->image)
+ return false;
+
+ if (mFrame->image->getAlpha() != mAlpha)
+ mFrame->image->setAlpha(mAlpha);
+
+ return graphics->drawImage(mFrame->image,
+ posX + mFrame->offsetX,
+ posY + mFrame->offsetY);
+}
+
+bool AnimatedSprite::setDirection(SpriteDirection direction)
+{
+ if (mDirection != direction)
+ {
+ mDirection = direction;
+
+ if (!mAction)
+ return false;
+
+ Animation *animation = mAction->getAnimation(mDirection);
+
+ if (animation && animation != mAnimation && animation->getLength() > 0)
+ {
+ mAnimation = animation;
+ mFrame = mAnimation->getFrame(0);
+ reset();
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+unsigned int AnimatedSprite::getCurrentFrame() const
+{
+ return mFrameIndex;
+}
+
+unsigned int AnimatedSprite::getFrameCount() const
+{
+ if (mAnimation)
+ return mAnimation->getLength();
+ else
+ return 0;
+}
+
+int AnimatedSprite::getWidth() const
+{
+ if (mFrame)
+ return mFrame->image ? mFrame->image->getWidth() : 0;
+ else
+ return 0;
+}
+
+int AnimatedSprite::getHeight() const
+{
+ if (mFrame)
+ return mFrame->image ? mFrame->image->getHeight() : 0;
+ else
+ return 0;
+}
+
+std::string AnimatedSprite::getIdPath()
+{
+ if (!mSprite)
+ return "";
+ return mSprite->getIdPath();
+}
+
+const Image* AnimatedSprite::getImage() const
+{
+ return mFrame ? mFrame->image : 0;
+}
diff --git a/src/animatedsprite.h b/src/animatedsprite.h
new file mode 100644
index 000000000..4ba5a9503
--- /dev/null
+++ b/src/animatedsprite.h
@@ -0,0 +1,97 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ANIMATEDSPRITE_H
+#define ANIMATEDSPRITE_H
+
+#include "sprite.h"
+
+#include <map>
+#include <string>
+
+class Animation;
+struct Frame;
+
+/**
+ * Animates a sprite by adding playback state.
+ */
+class AnimatedSprite : public Sprite
+{
+ public:
+ /**
+ * Constructor.
+ * @param sprite the sprite to animate
+ */
+ AnimatedSprite(SpriteDef *sprite);
+
+ /**
+ * An helper function, which will request the sprite to animate
+ * from the resource manager.
+ *
+ * @param filename the file of the sprite to animate
+ * @param variant the sprite variant
+ */
+ static AnimatedSprite *load(const std::string &filename,
+ int variant = 0);
+
+ virtual ~AnimatedSprite();
+
+ bool reset();
+
+ bool play(std::string action);
+
+ bool update(int time);
+
+ bool draw(Graphics* graphics, int posX, int posY) const;
+
+ int getWidth() const;
+
+ int getHeight() const;
+
+ const Image* getImage() const;
+
+ bool setDirection(SpriteDirection direction);
+
+ int getNumberOfLayers()
+ { return 1; }
+
+ std::string getIdPath();
+
+ unsigned int getCurrentFrame() const;
+
+ unsigned int getFrameCount() const;
+
+ private:
+ bool updateCurrentAnimation(unsigned int dt);
+
+ SpriteDirection mDirection; /**< The sprite direction. */
+ int mLastTime; /**< The last time update was called. */
+
+ unsigned int mFrameIndex; /**< The index of the current frame. */
+ unsigned int mFrameTime; /**< The time since start of frame. */
+
+ SpriteDef *mSprite; /**< The sprite definition. */
+ Action *mAction; /**< The currently active action. */
+ Animation *mAnimation; /**< The currently active animation. */
+ Frame *mFrame; /**< The currently active frame. */
+};
+
+#endif
diff --git a/src/animationparticle.cpp b/src/animationparticle.cpp
new file mode 100644
index 000000000..d2bc9a5a9
--- /dev/null
+++ b/src/animationparticle.cpp
@@ -0,0 +1,54 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "animationparticle.h"
+
+#include "graphics.h"
+#include "simpleanimation.h"
+
+AnimationParticle::AnimationParticle(Map *map, Animation *animation):
+ ImageParticle(map, 0),
+ mAnimation(new SimpleAnimation(animation))
+{
+}
+
+AnimationParticle::AnimationParticle(Map *map, xmlNodePtr animationNode):
+ ImageParticle(map, 0),
+ mAnimation(new SimpleAnimation(animationNode))
+{
+}
+
+AnimationParticle::~AnimationParticle()
+{
+ delete mAnimation;
+ mAnimation = 0;
+ mImage = 0;
+}
+
+bool AnimationParticle::update()
+{
+ if (mAnimation)
+ {
+ mAnimation->update(10); // particle engine is updated every 10ms
+ mImage = mAnimation->getCurrentImage();
+ }
+ return Particle::update();
+}
diff --git a/src/animationparticle.h b/src/animationparticle.h
new file mode 100644
index 000000000..0837fec64
--- /dev/null
+++ b/src/animationparticle.h
@@ -0,0 +1,48 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ANIMATION_PARTICLE_H
+#define ANIMATION_PARTICLE_H
+
+#include "imageparticle.h"
+
+#include <libxml/tree.h>
+
+class Animation;
+class Map;
+class SimpleAnimation;
+
+class AnimationParticle : public ImageParticle
+{
+ public:
+ AnimationParticle(Map *map, Animation *animation);
+
+ AnimationParticle(Map *map, xmlNodePtr animationNode);
+
+ ~AnimationParticle();
+
+ virtual bool update();
+
+ private:
+ SimpleAnimation *mAnimation; /**< Used animation for this particle */
+};
+
+#endif
diff --git a/src/avatar.cpp b/src/avatar.cpp
new file mode 100644
index 000000000..ea3f1fe87
--- /dev/null
+++ b/src/avatar.cpp
@@ -0,0 +1,62 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "avatar.h"
+
+#include "localplayer.h"
+
+#include <sstream>
+
+Avatar::Avatar(const std::string &name):
+ mId(0),
+ mCharId(0),
+ mName(name),
+ mOriginalName(name),
+ mHp(0), mMaxHp(0),
+ mDamageHp(0),
+ mLevel(1),
+ mOnline(false),
+ mDisplayBold(false),
+ mMap(""),
+ mX(-1),
+ mY(-1),
+ mType(AVATAR_PLAYER),
+ mExp(0),
+ mGender(GENDER_UNSPECIFIED),
+ mRace(-1),
+ mIp("")
+{
+}
+
+std::string Avatar::getComplexName() const
+{
+ if (mName == mOriginalName || mOriginalName.empty())
+ return mName;
+ else
+ return mName + "(" + mOriginalName + ")";
+}
+
+std::string Avatar::getAdditionString() const
+{
+ if (!getIp().empty())
+ return " - " + getIp();
+ else
+ return "";
+} \ No newline at end of file
diff --git a/src/avatar.h b/src/avatar.h
new file mode 100644
index 000000000..59c0d3d51
--- /dev/null
+++ b/src/avatar.h
@@ -0,0 +1,189 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef AVATAR_H
+#define AVATAR_H
+
+#include <string>
+
+enum AvatarType
+{
+ AVATAR_PLAYER = 0
+// AVATAR_PORTAL
+};
+
+class Avatar
+{
+public:
+ Avatar(const std::string &name = "");
+
+ /**
+ * Returns the avatar's name.
+ */
+ std::string getName() const
+ { return mName; }
+
+ /**
+ * Set the avatar's name.
+ */
+ void setName(const std::string &name)
+ { mName = name; }
+
+ /**
+ * Returns the avatar's original name.
+ */
+ std::string getOriginalName() const
+ { return mOriginalName; }
+
+ std::string getComplexName() const;
+
+ virtual std::string getAdditionString() const;
+
+ /**
+ * Set the avatar's original name.
+ */
+ void setOriginalName(const std::string &name)
+ { mOriginalName = name; }
+
+ /**
+ * Returns the avatar's online status.
+ */
+ bool getOnline() const
+ { return mOnline; }
+
+ /**
+ * Set the avatar's online status.
+ */
+ void setOnline(bool online)
+ { mOnline = online; }
+
+ int getHp() const
+ { return mHp; }
+
+ void setHp(int hp)
+ { mHp = hp; }
+
+ int getMaxHp() const
+ { return mMaxHp; }
+
+ void setMaxHp(int maxHp)
+ { mMaxHp = maxHp; }
+
+ int getDamageHp() const
+ { return mDamageHp; }
+
+ void setDamageHp(int damageHp)
+ { mDamageHp = damageHp; }
+
+ bool getDisplayBold() const
+ { return mDisplayBold; }
+
+ void setDisplayBold(bool displayBold)
+ { mDisplayBold = displayBold; }
+
+ int getLevel() const
+ { return mLevel; }
+
+ void setLevel(int level)
+ { mLevel = level; }
+
+ std::string getMap() const
+ { return mMap; }
+
+ void setMap(std::string map)
+ { mMap = map; }
+
+ int getX() const
+ { return mX; }
+
+ void setX(int x)
+ { mX = x; }
+
+ int getY() const
+ { return mY; }
+
+ void setY(int y)
+ { mY = y; }
+
+ int getType() const
+ { return mType; }
+
+ void setType(int n)
+ { mType = n; }
+
+ int getExp() const
+ { return mExp; }
+
+ void setExp(int n)
+ { mExp = n; }
+
+ int getID() const
+ { return mId; }
+
+ void setID(int id)
+ { mId = id; }
+
+ int getCharId() const
+ { return mCharId; }
+
+ void setCharId(int id)
+ { mCharId = id; }
+
+ int getGender() const
+ { return mGender; }
+
+ void setGender(int g)
+ { mGender = g; }
+
+ int getRace() const
+ { return mRace; }
+
+ void setRace(int r)
+ { mRace = r; }
+
+ const std::string &getIp() const
+ { return mIp; }
+
+ void setIp(std::string ip)
+ { mIp = ip; }
+
+protected:
+ int mId;
+ int mCharId;
+ std::string mName;
+ std::string mOriginalName;
+ int mHp;
+ int mMaxHp;
+ int mDamageHp;
+ int mLevel;
+ bool mOnline;
+ bool mDisplayBold;
+ std::string mMap;
+ int mX;
+ int mY;
+ int mType;
+ int mExp;
+ int mGender;
+ int mRace;
+ std::string mIp;
+};
+
+#endif // AVATAR_H
diff --git a/src/being.cpp b/src/being.cpp
new file mode 100644
index 000000000..08893c2f4
--- /dev/null
+++ b/src/being.cpp
@@ -0,0 +1,2009 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "being.h"
+
+#include "actorspritemanager.h"
+#include "animatedsprite.h"
+#include "client.h"
+#include "configuration.h"
+#include "effectmanager.h"
+#include "graphics.h"
+#include "guild.h"
+#include "localplayer.h"
+#include "log.h"
+#include "map.h"
+#include "particle.h"
+#include "party.h"
+#include "playerrelations.h"
+#include "simpleanimation.h"
+#include "sound.h"
+#include "sprite.h"
+#include "text.h"
+#include "statuseffect.h"
+
+#include "gui/buy.h"
+#include "gui/buysell.h"
+#include "gui/gui.h"
+#include "gui/npcdialog.h"
+#include "gui/npcpostdialog.h"
+#include "gui/sell.h"
+#include "gui/socialwindow.h"
+#include "gui/speechbubble.h"
+#include "gui/theme.h"
+#include "gui/truetypefont.h"
+#include "gui/userpalette.h"
+
+#include "net/charhandler.h"
+#include "net/gamehandler.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+#include "net/playerhandler.h"
+
+#include "resources/beinginfo.h"
+#include "resources/colordb.h"
+#include "resources/emotedb.h"
+#include "resources/image.h"
+#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
+#include "resources/monsterdb.h"
+#include "resources/npcdb.h"
+#include "resources/resourcemanager.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "utils/dtor.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <cassert>
+#include <cmath>
+
+#define CACHE_SIZE 50
+#define HAIR_FILE "hair.xml"
+
+static const int DEFAULT_BEING_WIDTH = 32;
+static const int DEFAULT_BEING_HEIGHT = 32;
+
+class BeingCacheEntry
+{
+ public:
+ BeingCacheEntry(int id):
+ mId(id),
+ mName(""),
+ mPartyName(""),
+ mLevel(0),
+ mPvpRank(0),
+ mTime(0)
+ {
+ }
+
+ int getId() const
+ { return mId; }
+
+ /**
+ * Returns the name of the being.
+ */
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Sets the name for the being.
+ *
+ * @param name The name that should appear.
+ */
+ void setName(const std::string &name)
+ { mName = name; }
+
+ /**
+ * Following are set from the server (mainly for players)
+ */
+ void setPartyName(const std::string &name)
+ { mPartyName = name; }
+
+ const std::string &getPartyName() const
+ { return mPartyName; }
+
+ void setLevel(int n)
+ { mLevel = n; }
+
+ int getLevel() const
+ { return mLevel; }
+
+ void setTime(int n)
+ { mTime = n; }
+
+ int getTime() const
+ { return mTime; }
+
+ unsigned getPvpRank() const
+ { return mPvpRank; }
+
+ void setPvpRank(int r)
+ { mPvpRank = r; }
+
+ std::string getIp() const
+ { return mIp; }
+
+ void setIp(std::string ip)
+ { mIp = ip; }
+
+ protected:
+ int mId; /**< Unique sprite id */
+ std::string mName; /**< Name of character */
+ std::string mPartyName;
+ int mLevel;
+ unsigned int mPvpRank;
+ int mTime;
+ std::string mIp;
+};
+
+
+int Being::mNumberOfHairstyles = 1;
+
+int Being::mUpdateConfigTime = 0;
+unsigned int Being::mConfLineLim = 0;
+int Being::mSpeechType = 0;
+bool Being::mHighlightMapPortals = false;
+bool Being::mHighlightMonsterAttackRange = false;
+bool Being::mLowTraffic = true;
+bool Being::mDrawHotKeys = true;
+bool Being::mShowBattleEvents = false;
+bool Being::mShowMobHP = false;
+
+std::list<BeingCacheEntry*> beingInfoCache;
+
+
+// TODO: mWalkTime used by eAthena only
+Being::Being(int id, Type type, Uint16 subtype, Map *map):
+ ActorSprite(id),
+ mInfo(BeingInfo::Unknown),
+ mActionTime(0),
+ mEmotion(0), mEmotionTime(0),
+ mSpeechTime(0),
+ mAttackType(1),
+ mAttackSpeed(350),
+ mAction(STAND),
+ mSubType(0xFFFF),
+ mDirection(DOWN),
+ mSpriteDirection(DIRECTION_DOWN),
+ mDispName(0),
+ mShowName(false),
+ mEquippedWeapon(NULL),
+ mText(0),
+ mLevel(0),
+ mGender(GENDER_UNSPECIFIED),
+ mParty(0),
+ mIsGM(false),
+ mType(type),
+ mX(0), mY(0),
+ mDamageTaken(0),
+ mHP(0), mMaxHP(0),
+ mDistance(0),
+ mIsReachable(REACH_UNKNOWN),
+ mErased(false),
+ mEnemy(false),
+ mIp(""),
+ mPvpRank(0)
+{
+ mSpriteRemap = new int[20];
+
+ for (int f = 0; f < 20; f ++)
+ mSpriteRemap[f] = f;
+
+ setMap(map);
+ setSubtype(subtype);
+
+ mSpeechBubble = new SpeechBubble;
+
+ mWalkSpeed = Net::getPlayerHandler()->getDefaultWalkSpeed();
+
+ if (getType() == PLAYER)
+ mShowName = config.getBoolValue("visiblenames");
+
+ config.addListener("visiblenames", this);
+
+ if (getType() == NPC)
+ setShowName(true);
+ else
+ setShowName(mShowName);
+
+ updateColors();
+ resetCounters();
+}
+
+Being::~Being()
+{
+ config.removeListener("visiblenames", this);
+
+ delete[] mSpriteRemap;
+ mSpriteRemap = 0;
+
+ delete mSpeechBubble;
+ mSpeechBubble = 0;
+ delete mDispName;
+ mDispName = 0;
+ delete mText;
+ mText = 0;
+}
+
+void Being::setSubtype(Uint16 subtype)
+{
+ if (!mInfo)
+ return;
+
+ if (subtype == mSubType)
+ return;
+
+ mSubType = subtype;
+
+ if (getType() == MONSTER)
+ {
+ mInfo = MonsterDB::get(mSubType);
+ if (mInfo)
+ {
+ setName(mInfo->getName());
+ setupSpriteDisplay(mInfo->getDisplay());
+ }
+ }
+ else if (getType() == NPC)
+ {
+ mInfo = NPCDB::get(mSubType);
+ if (mInfo)
+ setupSpriteDisplay(mInfo->getDisplay(), false);
+ }
+ else if (getType() == PLAYER)
+ {
+ int id = -100 - subtype;
+
+ // Prevent showing errors when sprite doesn't exist
+ if (!ItemDB::exists(id))
+ id = -100;
+
+ setSprite(Net::getCharHandler()->baseSprite(), id);
+ }
+}
+
+ActorSprite::TargetCursorSize Being::getTargetCursorSize() const
+{
+ if (!mInfo)
+ return ActorSprite::TC_SMALL;
+
+ return mInfo->getTargetCursorSize();
+}
+
+int Being::getTargetOffsetX() const
+{
+ if (!mInfo)
+ return 0;
+
+ return mInfo->getTargetOffsetX();
+}
+
+int Being::getTargetOffsetY() const
+{
+ if (!mInfo)
+ return 0;
+
+ return mInfo->getTargetOffsetY();
+}
+
+unsigned char Being::getWalkMask() const
+{
+ if (!mInfo)
+ return 0;
+
+ return mInfo->getWalkMask();
+}
+
+Map::BlockType Being::getBlockType() const
+{
+ if (!mInfo)
+ return Map::BLOCKTYPE_NONE;
+
+ return mInfo->getBlockType();
+}
+
+void Being::setPosition(const Vector &pos)
+{
+ Actor::setPosition(pos);
+
+ updateCoords();
+
+ if (mText)
+ {
+ mText->adviseXY((int)pos.x,
+ (int)pos.y - getHeight() - mText->getHeight() - 6);
+ }
+}
+
+void Being::setDestination(int dstX, int dstY)
+{
+ if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+ if (mMap)
+ setPath(mMap->findPath(mX, mY, dstX, dstY, getWalkMask()));
+ return;
+ }
+
+ // Manaserv's part:
+
+ // We can't calculate anything without a map anyway.
+ if (!mMap)
+ return;
+
+ // Don't handle flawed destinations from server...
+ if (dstX == 0 || dstY == 0)
+ return;
+
+ // If the destination is unwalkable, don't bother trying to get there
+ if (!mMap->getWalk(dstX / 32, dstY / 32))
+ return;
+
+ Position dest = mMap->checkNodeOffsets(getCollisionRadius(), getWalkMask(),
+ dstX, dstY);
+ Path thisPath = mMap->findPixelPath(static_cast<int>(mPos.x),
+ static_cast<int>(mPos.y), dest.x, dest.y,
+ static_cast<int>(getCollisionRadius()),
+ static_cast<int>(getWalkMask()));
+
+ if (thisPath.empty())
+ {
+ // If there is no path but the destination is on the same walkable tile,
+ // we accept it.
+ if ((int)mPos.x / 32 == dest.x / 32
+ && (int)mPos.y / 32 == dest.y / 32)
+ {
+ mDest.x = static_cast<float>(dest.x);
+ mDest.y = static_cast<float>(dest.y);
+ }
+ setPath(Path());
+ return;
+ }
+
+ // The destination is valid, so we set it.
+ mDest.x = static_cast<float>(dest.x);
+ mDest.y = static_cast<float>(dest.y);
+
+ setPath(thisPath);
+}
+
+void Being::clearPath()
+{
+ mPath.clear();
+}
+
+void Being::setPath(const Path &path)
+{
+ mPath = path;
+
+ if ((Net::getNetworkType() == ServerInfo::TMWATHENA) &&
+ mAction != MOVE && mAction != DEAD)
+ {
+ nextTile();
+ mActionTime = tick_time;
+ }
+}
+
+void Being::setSpeech(const std::string &text, int time)
+{
+ if (!userPalette)
+ return;
+
+ // Remove colors
+ mSpeech = removeColors(text);
+
+ // Trim whitespace
+ trim(mSpeech);
+
+ unsigned int lineLim = mConfLineLim;
+ if (lineLim > 0 && mSpeech.length() > lineLim)
+ mSpeech = mSpeech.substr(0, lineLim);
+
+ trim(mSpeech);
+ if (mSpeech.length() < 1)
+ return;
+
+ // Check for links
+ std::string::size_type start = mSpeech.find('[');
+ std::string::size_type end = mSpeech.find(']', start);
+
+ while (start != std::string::npos && end != std::string::npos)
+ {
+ // Catch multiple embeds and ignore them so it doesn't crash the client.
+ while ((mSpeech.find('[', start + 1) != std::string::npos) &&
+ (mSpeech.find('[', start + 1) < end))
+ {
+ start = mSpeech.find('[', start + 1);
+ }
+
+ std::string::size_type position = mSpeech.find('|');
+ if (mSpeech[start + 1] == '@' && mSpeech[start + 2] == '@')
+ {
+ mSpeech.erase(end, 1);
+ mSpeech.erase(start, (position - start) + 1);
+ }
+ position = mSpeech.find('@');
+
+ while (position != std::string::npos)
+ {
+ mSpeech.erase(position, 2);
+ position = mSpeech.find('@');
+ }
+
+ start = mSpeech.find('[', start + 1);
+ end = mSpeech.find(']', start);
+ }
+
+ if (!mSpeech.empty())
+ mSpeechTime = time <= SPEECH_MAX_TIME ? time : SPEECH_MAX_TIME;
+
+ const int speech = mSpeechType;
+ if (speech == TEXT_OVERHEAD && userPalette)
+ {
+ delete mText;
+
+ mText = new Text(mSpeech,
+ getPixelX(), getPixelY() - getHeight(),
+ gcn::Graphics::CENTER,
+ &userPalette->getColor(UserPalette::PARTICLE),
+ true);
+ }
+}
+
+void Being::takeDamage(Being *attacker, int amount, AttackType type)
+{
+ if (!userPalette || !attacker)
+ return;
+
+ gcn::Font *font = 0;
+ std::string damage = amount ? toString(amount) : type == FLEE ?
+ "dodge" : "miss";
+ const gcn::Color *color;
+
+ if (gui)
+ font = gui->getInfoParticleFont();
+
+ // Selecting the right color
+ if (type == CRITICAL || type == FLEE)
+ {
+ if (attacker == player_node)
+ {
+ color = &userPalette->getColor(
+ UserPalette::HIT_LOCAL_PLAYER_CRITICAL);
+ }
+ else
+ {
+ color = &userPalette->getColor(UserPalette::HIT_CRITICAL);
+ }
+ }
+ else if (!amount)
+ {
+ if (attacker == player_node)
+ {
+ // This is intended to be the wrong direction to visually
+ // differentiate between hits and misses
+ color = &userPalette->getColor(UserPalette::HIT_LOCAL_PLAYER_MISS);
+ }
+ else
+ {
+ color = &userPalette->getColor(UserPalette::MISS);
+ }
+ }
+ else if (getType() == MONSTER)
+ {
+ if (attacker == player_node)
+ {
+ color = &userPalette->getColor(
+ UserPalette::HIT_LOCAL_PLAYER_MONSTER);
+ }
+ else
+ {
+ color = &userPalette->getColor(
+ UserPalette::HIT_PLAYER_MONSTER);
+ }
+ }
+ else if (getType() == PLAYER && attacker != player_node
+ && this == player_node)
+ {
+ // here player was attacked by other player. mark him as enemy.
+ color = &userPalette->getColor(UserPalette::HIT_PLAYER_PLAYER);
+ attacker->setEnemy(true);
+ attacker->updateColors();
+ }
+ else
+ {
+ color = &userPalette->getColor(UserPalette::HIT_MONSTER_PLAYER);
+ }
+
+ if (chatWindow && mShowBattleEvents)
+ {
+ if (this == player_node)
+ {
+ if (attacker->getType() == PLAYER || amount)
+ {
+ chatWindow->battleChatLog(attacker->getName() + " : Hit you -"
+ + toString(amount), BY_OTHER);
+ }
+ }
+ else if (attacker == player_node && amount)
+ {
+ chatWindow->battleChatLog(attacker->getName() + " : You hit "
+ + getName() + " -" + toString(amount), BY_PLAYER);
+ }
+ }
+ if (font && particleEngine)
+ {
+ // Show damage number
+ particleEngine->addTextSplashEffect(damage,
+ getPixelX(), getPixelY() - 16,
+ color, font, true);
+ }
+
+ if (amount > 0)
+ {
+ if (player_node && player_node == this)
+ player_node->setLastHitFrom(attacker->getName());
+
+ mDamageTaken += amount;
+ if (mInfo)
+ {
+ sound.playSfx(mInfo->getSound(SOUND_EVENT_HURT));
+ if (!mInfo->isStaticMaxHP())
+ {
+ if (!mHP && mInfo->getMaxHP() < mDamageTaken)
+ mInfo->setMaxHP(mDamageTaken);
+ }
+ }
+ if (mHP && isAlive())
+ {
+ mHP -= amount;
+ if (mHP < 0)
+ mHP = 0;
+ }
+
+ if (getType() == MONSTER)
+ updateName();
+ else if (getType() == PLAYER && socialWindow && getName() != "")
+ socialWindow->updateAvatar(getName());
+
+ if (effectManager)
+ {
+ if (type != CRITICAL)
+ effectManager->trigger(26, this);
+ else
+ effectManager->trigger(28, this);
+ }
+ }
+}
+
+void Being::handleAttack(Being *victim, int damage,
+ AttackType type _UNUSED_)
+{
+ if (!victim || !mInfo)
+ return;
+
+ if (this != player_node)
+ setAction(Being::ATTACK, 1);
+
+ if (getType() == PLAYER && mEquippedWeapon)
+ fireMissile(victim, mEquippedWeapon->getMissileParticle());
+ else if (mInfo->getAttack(mAttackType))
+ fireMissile(victim, mInfo->getAttack(mAttackType)->missileParticle);
+
+ if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+ reset();
+ mActionTime = tick_time;
+ }
+
+ sound.playSfx(mInfo->getSound((damage > 0) ?
+ SOUND_EVENT_HIT : SOUND_EVENT_MISS));
+}
+
+void Being::setName(const std::string &name)
+{
+ if (getType() == NPC)
+ {
+ mName = name.substr(0, name.find('#', 0));
+ showName();
+ }
+ else
+ {
+ mName = name;
+
+ if (getType() == PLAYER && getShowName())
+ showName();
+ }
+}
+
+void Being::setShowName(bool doShowName)
+{
+ if (mShowName == doShowName)
+ return;
+
+ mShowName = doShowName;
+
+ if (doShowName)
+ {
+ showName();
+ }
+ else
+ {
+ delete mDispName;
+ mDispName = 0;
+ }
+}
+
+void Being::setGuildName(const std::string &name)
+{
+ mGuildName = name;
+}
+
+
+void Being::setGuildPos(const std::string &pos _UNUSED_)
+{
+// logger->log("Got guild position \"%s\" for being %s(%i)", pos.c_str(), mName.c_str(), mId);
+}
+
+void Being::addGuild(Guild *guild)
+{
+ if (!guild)
+ return;
+
+ mGuilds[guild->getId()] = guild;
+// guild->addMember(mId, 0, mName);
+
+ if (this == player_node && socialWindow)
+ socialWindow->addTab(guild);
+}
+
+void Being::removeGuild(int id)
+{
+ if (this == player_node && socialWindow)
+ socialWindow->removeTab(mGuilds[id]);
+
+ if (mGuilds[id])
+ mGuilds[id]->removeMember(getName());
+ mGuilds.erase(id);
+}
+
+Guild *Being::getGuild(const std::string &guildName) const
+{
+ std::map<int, Guild*>::const_iterator itr, itr_end = mGuilds.end();
+ for (itr = mGuilds.begin(); itr != itr_end; ++itr)
+ {
+ Guild *guild = itr->second;
+ if (guild && guild->getName() == guildName)
+ return guild;
+ }
+
+ return 0;
+}
+
+Guild *Being::getGuild(int id) const
+{
+ std::map<int, Guild*>::const_iterator itr;
+ itr = mGuilds.find(id);
+ if (itr != mGuilds.end())
+ return itr->second;
+
+ return 0;
+}
+
+Guild *Being::getGuild() const
+{
+ std::map<int, Guild*>::const_iterator itr;
+ itr = mGuilds.begin();
+ if (itr != mGuilds.end())
+ return itr->second;
+
+ return 0;
+}
+
+void Being::clearGuilds()
+{
+ std::map<int, Guild*>::const_iterator itr, itr_end = mGuilds.end();
+ for (itr = mGuilds.begin(); itr != itr_end; ++itr)
+ {
+ Guild *guild = itr->second;
+
+ if (guild)
+ {
+ if (this == player_node && socialWindow)
+ socialWindow->removeTab(guild);
+
+ guild->removeMember(mId);
+ }
+ }
+
+ mGuilds.clear();
+}
+
+void Being::setParty(Party *party)
+{
+ if (party == mParty)
+ return;
+
+ Party *old = mParty;
+ mParty = party;
+
+ if (old)
+ old->removeMember(mId);
+
+ if (party)
+ party->addMember(mId, mName);
+
+ updateColors();
+
+ if (this == player_node && socialWindow)
+ {
+ if (old)
+ socialWindow->removeTab(old);
+
+ if (party)
+ socialWindow->addTab(party);
+ }
+}
+
+void Being::updateGuild()
+{
+ if (!player_node)
+ return;
+
+ Guild *guild = player_node->getGuild();
+ if (!guild)
+ {
+ clearGuilds();
+ updateColors();
+ return;
+ }
+ if (guild->getMember(getName()))
+ setGuild(guild);
+ updateColors();
+}
+
+void Being::setGuild(Guild *guild)
+{
+ if (guild == getGuild())
+ return;
+
+ Guild *old = getGuild();
+ clearGuilds();
+ addGuild(guild);
+
+ if (old)
+ old->removeMember(mName);
+
+// if (guild)
+// guild->addMember(mId, mName);
+
+ updateColors();
+
+ if (this == player_node && socialWindow)
+ {
+ if (old)
+ socialWindow->removeTab(old);
+
+ if (guild)
+ socialWindow->addTab(guild);
+ }
+}
+
+void Being::fireMissile(Being *victim, const std::string &particle)
+{
+ if (!victim || particle.empty() || !particleEngine)
+ return;
+
+ Particle *target = particleEngine->createChild();
+
+ if (!target)
+ return;
+
+ Particle *missile = target->addEffect(particle, getPixelX(), getPixelY());
+
+ if (missile)
+ {
+ target->moveBy(Vector(0.0f, 0.0f, 32.0f));
+ target->setLifetime(1000);
+ victim->controlParticle(target);
+
+ missile->setDestination(target, 7, 0);
+ missile->setDieDistance(8);
+ missile->setLifetime(900);
+ }
+
+}
+
+void Being::setAction(Action action, int attackType _UNUSED_)
+{
+ std::string currentAction = SpriteAction::INVALID;
+
+ switch (action)
+ {
+ case MOVE:
+ currentAction = SpriteAction::MOVE;
+ // Note: When adding a run action,
+ // Differentiate walk and run with action name,
+ // while using only the ACTION_MOVE.
+ break;
+ case SIT:
+ currentAction = SpriteAction::SIT;
+ break;
+ case ATTACK:
+ if (mEquippedWeapon)
+ {
+ currentAction = mEquippedWeapon->getAttackAction();
+ reset();
+ }
+ else
+ {
+ mAttackType = attackType;
+ if (!mInfo || !mInfo->getAttack(attackType))
+ break;
+
+ currentAction = mInfo->getAttack(attackType)->action;
+ reset();
+
+ if (Net::getNetworkType() == ServerInfo::MANASERV
+ && mInfo->getAttack(attackType))
+ {
+ //attack particle effect
+ std::string particleEffect = mInfo->getAttack(attackType)
+ ->particleEffect;
+ if (!particleEffect.empty() && Particle::enabled)
+ {
+ int rotation = 0;
+ switch (mSpriteDirection)
+ {
+ case DIRECTION_DOWN: rotation = 0; break;
+ case DIRECTION_LEFT: rotation = 90; break;
+ case DIRECTION_UP: rotation = 180; break;
+ case DIRECTION_RIGHT: rotation = 270; break;
+ default: break;
+ }
+ ;
+ if (particleEngine)
+ {
+ Particle *p = particleEngine->addEffect(
+ particleEffect, 0, 0, rotation);
+ if (p)
+ controlParticle(p);
+ }
+ }
+ }
+ }
+
+ break;
+ case HURT:
+ //currentAction = SpriteAction::HURT;// Buggy: makes the player stop
+ // attacking and unable to attack
+ // again until he moves.
+ // TODO: fix this!
+ break;
+ case DEAD:
+ currentAction = SpriteAction::DEAD;
+ if (mInfo)
+ sound.playSfx(mInfo->getSound(SOUND_EVENT_DIE));
+ break;
+ case STAND:
+ currentAction = SpriteAction::STAND;
+ break;
+ default:
+ logger->log("Being::setAction unknown action: "
+ + toString(static_cast<unsigned>(action)));
+ break;
+ }
+
+ if (currentAction != SpriteAction::INVALID)
+ {
+ play(currentAction);
+ mAction = action;
+ }
+
+ if (currentAction != SpriteAction::MOVE)
+ mActionTime = tick_time;
+}
+
+void Being::setDirection(Uint8 direction)
+{
+ if (mDirection == direction)
+ return;
+
+ mDirection = direction;
+
+ // if the direction does not change much, keep the common component
+ int mFaceDirection = mDirection & direction;
+ if (!mFaceDirection)
+ mFaceDirection = direction;
+
+ SpriteDirection dir;
+ if (mFaceDirection & UP)
+ dir = DIRECTION_UP;
+ else if (mFaceDirection & DOWN)
+ dir = DIRECTION_DOWN;
+ else if (mFaceDirection & RIGHT)
+ dir = DIRECTION_RIGHT;
+ else
+ dir = DIRECTION_LEFT;
+ mSpriteDirection = dir;
+
+ CompoundSprite::setDirection(dir);
+}
+
+/** TODO: Used by eAthena only */
+void Being::nextTile()
+{
+ if (mPath.empty())
+ {
+ setAction(STAND);
+ return;
+ }
+
+ Position pos = mPath.front();
+ mPath.pop_front();
+
+ int dir = 0;
+ if (pos.x > mX)
+ dir |= RIGHT;
+ else if (pos.x < mX)
+ dir |= LEFT;
+ if (pos.y > mY)
+ dir |= DOWN;
+ else if (pos.y < mY)
+ dir |= UP;
+
+ setDirection(static_cast<Uint8>(dir));
+
+ if (!mMap->getWalk(pos.x, pos.y, getWalkMask()))
+ {
+ setAction(STAND);
+ return;
+ }
+
+ mX = pos.x;
+ mY = pos.y;
+ setAction(MOVE);
+ mActionTime += (int)(mWalkSpeed.x / 10);
+}
+
+int Being::getCollisionRadius() const
+{
+ // FIXME: Get this from XML file
+ return 16;
+}
+
+void Being::logic()
+{
+ // Reduce the time that speech is still displayed
+ if (mSpeechTime > 0)
+ mSpeechTime--;
+
+ // Remove text and speechbubbles if speech boxes aren't being used
+ if (mSpeechTime == 0 && mText)
+ {
+ delete mText;
+ mText = 0;
+ }
+
+ int frameCount = static_cast<int>(getFrameCount());
+ if ((Net::getNetworkType() == ServerInfo::MANASERV) && (mAction != DEAD))
+ {
+ const Vector dest = (mPath.empty()) ?
+ mDest : Vector(static_cast<float>(mPath.front().x),
+ static_cast<float>(mPath.front().y));
+
+ // This is a hack that stops NPCs from running off the map...
+ if (mDest.x <= 0 && mDest.y <= 0)
+ return;
+
+ // The Vector representing the difference between current position
+ // and the next destination path node.
+ Vector dir = dest - mPos;
+
+ const float nominalLength = dir.length();
+
+ // When we've not reached our destination, move to it.
+ if (nominalLength > 0.0f && !mWalkSpeed.isNull())
+ {
+ // The deplacement of a point along a vector is calculated
+ // using the Unit Vector (â) multiplied by the point speed.
+ // â = a / ||a|| (||a|| is the a length.)
+ // Then, diff = (dir/||dir||) * speed.
+ const Vector normalizedDir = dir.normalized();
+ Vector diff(normalizedDir.x * mWalkSpeed.x,
+ normalizedDir.y * mWalkSpeed.y);
+
+ // Test if we don't miss the destination by a move too far:
+ if (diff.length() > nominalLength)
+ {
+ setPosition(mPos + dir);
+
+ // Also, if the destination is reached, try to get the next
+ // path point, if existing.
+ if (!mPath.empty())
+ mPath.pop_front();
+ }
+ // Otherwise, go to it using the nominal speed.
+ else
+ {
+ setPosition(mPos + diff);
+ }
+
+ if (mAction != MOVE)
+ setAction(MOVE);
+
+ // Update the player sprite direction.
+ // N.B.: We only change this if the distance is more than one pixel.
+ if (nominalLength > 1.0f)
+ {
+ int direction = 0;
+ const float dx = std::abs(dir.x);
+ float dy = std::abs(dir.y);
+
+ // When not using mouse for the player, we slightly prefer
+ // UP and DOWN position, especially when walking diagonally.
+ if (player_node && this == player_node &&
+ !player_node->isPathSetByMouse())
+ {
+ dy = dy + 2;
+ }
+
+ if (dx > dy)
+ direction |= (dir.x > 0) ? RIGHT : LEFT;
+ else
+ direction |= (dir.y > 0) ? DOWN : UP;
+
+ setDirection(static_cast<Uint8>(direction));
+ }
+ }
+ else if (!mPath.empty())
+ {
+ // If the current path node has been reached,
+ // remove it and go to the next one.
+ mPath.pop_front();
+ }
+ else if (mAction == MOVE)
+ {
+ setAction(STAND);
+ }
+ }
+ else if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+
+ switch (mAction)
+ {
+ case STAND:
+ case SIT:
+ case DEAD:
+ case HURT:
+ default:
+ break;
+
+ case MOVE:
+ {
+ if (getWalkSpeed().x
+ && (int) ((get_elapsed_time(mActionTime) * frameCount)
+ / getWalkSpeed().x) >= frameCount)
+ {
+ nextTile();
+ }
+ break;
+ }
+
+ case ATTACK:
+ {
+ std::string particleEffect = "";
+
+ if (!mActionTime)
+ break;
+
+ int curFrame = 0;
+ if (mAttackSpeed)
+ {
+ curFrame = (get_elapsed_time(mActionTime) * frameCount)
+ / mAttackSpeed;
+ }
+
+ //attack particle effect
+ if (mEquippedWeapon)
+ {
+ particleEffect = mEquippedWeapon->getParticleEffect();
+
+ if (!particleEffect.empty() &&
+ findSameSubstring(particleEffect,
+ paths.getStringValue("particles")).empty())
+ {
+ particleEffect = paths.getStringValue("particles")
+ + particleEffect;
+ }
+ }
+ else if (mInfo && mInfo->getAttack(mAttackType))
+ {
+ particleEffect = mInfo->getAttack(mAttackType)
+ ->particleEffect;
+ }
+
+ if (particleEngine && !particleEffect.empty()
+ && Particle::enabled && curFrame == 1)
+ {
+ int rotation = 0;
+
+ switch (mDirection)
+ {
+ case DOWN: rotation = 0; break;
+ case LEFT: rotation = 90; break;
+ case UP: rotation = 180; break;
+ case RIGHT: rotation = 270; break;
+ default: break;
+ }
+ Particle *p = particleEngine->addEffect(particleEffect,
+ 0, 0, rotation);
+ controlParticle(p);
+ }
+
+ if (curFrame >= frameCount)
+ nextTile();
+
+ break;
+ }
+ }
+
+ // Update pixel coordinates
+ setPosition(static_cast<float>(mX * 32 + 16 + getXOffset()),
+ static_cast<float>(mY * 32 + 32 + getYOffset()));
+ }
+
+ if (mEmotion != 0)
+ {
+ mEmotionTime--;
+ if (mEmotionTime == 0)
+ mEmotion = 0;
+ }
+
+ ActorSprite::logic();
+
+// int frameCount = static_cast<int>(getFrameCount());
+ if (frameCount < 10)
+ frameCount = 10;
+
+ if (!isAlive() && getWalkSpeed().x
+ && Net::getGameHandler()->removeDeadBeings()
+ && (int) ((get_elapsed_time(mActionTime)
+ / getWalkSpeed().x) >= static_cast<float>(frameCount)))
+ {
+ if (getType() != PLAYER && actorSpriteManager)
+ actorSpriteManager->destroy(this);
+ }
+}
+
+void Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY)
+{
+ if (!mEmotion)
+ return;
+
+ const int px = getPixelX() - offsetX - 16;
+ const int py = getPixelY() - offsetY - 64 - 32;
+ const int emotionIndex = mEmotion - 1;
+
+ if (emotionIndex >= 0 && emotionIndex <= EmoteDB::getLast())
+ EmoteDB::getAnimation(emotionIndex)->draw(graphics, px, py);
+}
+
+void Being::drawSpeech(int offsetX, int offsetY)
+{
+ if (!mSpeechBubble)
+ return;
+
+ const int px = getPixelX() - offsetX;
+ const int py = getPixelY() - offsetY;
+ const int speech = mSpeechType;
+
+ // Draw speech above this being
+ if (mSpeechTime == 0)
+ {
+ if (mSpeechBubble->isVisible())
+ mSpeechBubble->setVisible(false);
+ }
+ else if (mSpeechTime > 0 && (speech == NAME_IN_BUBBLE ||
+ speech == NO_NAME_IN_BUBBLE))
+ {
+ const bool showName = (speech == NAME_IN_BUBBLE);
+
+ delete mText;
+ mText = 0;
+
+ mSpeechBubble->setCaption(showName ? mName : "", mTextColor);
+
+ mSpeechBubble->setText(mSpeech, showName);
+ mSpeechBubble->setPosition(px - (mSpeechBubble->getWidth() / 2),
+ py - getHeight()
+ - (mSpeechBubble->getHeight()));
+ mSpeechBubble->setVisible(true);
+ }
+ else if (mSpeechTime > 0 && speech == TEXT_OVERHEAD)
+ {
+ mSpeechBubble->setVisible(false);
+
+ if (!mText && userPalette)
+ {
+ mText = new Text(mSpeech,
+ getPixelX(), getPixelY() - getHeight(),
+ gcn::Graphics::CENTER,
+ &userPalette->getColor(UserPalette::PARTICLE),
+ true);
+ }
+ }
+ else if (speech == NO_SPEECH)
+ {
+ mSpeechBubble->setVisible(false);
+
+ delete mText;
+ mText = 0;
+ }
+}
+
+/** TODO: eAthena only */
+int Being::getOffset(char pos, char neg) const
+{
+ // Check whether we're walking in the requested direction
+ if (mAction != MOVE || !(mDirection & (pos | neg)))
+ return 0;
+
+ int offset = 0;
+
+ if (mMap)
+ {
+ offset = (pos == LEFT && neg == RIGHT) ?
+ (int)((static_cast<float>(get_elapsed_time(mActionTime))
+ * static_cast<float>(mMap->getTileWidth()))
+ / static_cast<float>(mWalkSpeed.x)) :
+ (int)((static_cast<float>(get_elapsed_time(mActionTime))
+ * static_cast<float>(mMap->getTileHeight()))
+ / static_cast<float>(mWalkSpeed.y));
+ }
+
+ // We calculate the offset _from_ the _target_ location
+ offset -= 32;
+ if (offset > 0)
+ offset = 0;
+
+ // Going into negative direction? Invert the offset.
+ if (mDirection & pos)
+ offset = -offset;
+
+ return offset;
+}
+
+int Being::getWidth() const
+{
+ return std::max(CompoundSprite::getWidth(), DEFAULT_BEING_WIDTH);
+}
+
+int Being::getHeight() const
+{
+ return std::max(CompoundSprite::getHeight(), DEFAULT_BEING_HEIGHT);
+}
+
+void Being::updateCoords()
+{
+ if (!mDispName)
+ return;
+
+ // Monster names show above the sprite instead of below it
+ if (getType() == MONSTER)
+ {
+ mDispName->adviseXY(getPixelX(),
+ getPixelY() - getHeight() - mDispName->getHeight());
+ }
+ else
+ {
+ mDispName->adviseXY(getPixelX(), getPixelY());
+ }
+}
+
+void Being::optionChanged(const std::string &value)
+{
+ if (getType() == PLAYER && value == "visiblenames")
+ setShowName(config.getBoolValue("visiblenames"));
+}
+
+void Being::flashName(int time)
+{
+ if (mDispName)
+ mDispName->flash(time);
+}
+
+void Being::showName()
+{
+ delete mDispName;
+ mDispName = 0;
+ std::string mDisplayName(mName);
+
+ if (getType() != MONSTER
+ && (config.getBoolValue("showgender")
+ || config.getBoolValue("showlevel")))
+ {
+ mDisplayName += " ";
+ if (config.getBoolValue("showlevel") && getLevel() != 0)
+ mDisplayName += toString(getLevel());
+
+ if (config.getBoolValue("showgender"))
+ {
+ if (getGender() == GENDER_FEMALE)
+ mDisplayName += "\u2640";
+ else if (getGender() == GENDER_MALE)
+ mDisplayName += "\u2642";
+ }
+ }
+
+ if (getType() == MONSTER)
+ {
+ if (config.getBoolValue("showMonstersTakedDamage"))
+ mDisplayName += ", " + toString(getDamageTaken());
+ }
+
+ gcn::Font *font = 0;
+ if (player_node && player_node->getTarget() == this
+ && getType() != MONSTER)
+ {
+ font = boldFont;
+ }
+
+ mDispName = new FlashText(mDisplayName, getPixelX(), getPixelY(),
+ gcn::Graphics::CENTER, mNameColor, font);
+
+ updateCoords();
+}
+
+void Being::updateColors()
+{
+ if (userPalette)
+ {
+ if (getType() == MONSTER)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::MONSTER);
+ mTextColor = &userPalette->getColor(UserPalette::MONSTER);
+ }
+ else if (getType() == NPC)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::NPC);
+ mTextColor = &userPalette->getColor(UserPalette::NPC);
+ }
+ else if (this == player_node)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::SELF);
+ mTextColor = &Theme::getThemeColor(Theme::PLAYER);
+ }
+ else
+ {
+ mTextColor = &userPalette->getColor(Theme::PLAYER);
+
+ mErased = false;
+
+ if (mIsGM)
+ {
+ mTextColor = &userPalette->getColor(UserPalette::GM);
+ mNameColor = &userPalette->getColor(UserPalette::GM);
+ }
+ else if (mEnemy)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::MONSTER);
+ }
+ else if (mParty && mParty == player_node->getParty())
+ {
+ mNameColor = &userPalette->getColor(UserPalette::PARTY);
+ }
+ else if (getGuild() && getGuild() == player_node->getGuild())
+ {
+ mNameColor = &userPalette->getColor(UserPalette::GUILD);
+ }
+ else if (player_relations.getRelation(mName) ==
+ PlayerRelation::FRIEND)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::FRIEND);
+ }
+ else if (player_relations.getRelation(mName) ==
+ PlayerRelation::DISREGARDED)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::DISREGARDED);
+ }
+ else if (player_relations.getRelation(mName) ==
+ PlayerRelation::IGNORED)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::IGNORED);
+ }
+ else if (player_relations.getRelation(mName) ==
+ PlayerRelation::ERASED)
+ {
+ mNameColor = &userPalette->getColor(UserPalette::ERASED);
+ mErased = true;
+ }
+ else
+ {
+ mNameColor = &userPalette->getColor(UserPalette::PC);
+ }
+ }
+
+ if (mDispName)
+ mDispName->setColor(mNameColor);
+ }
+}
+
+void Being::setSprite(unsigned int slot, int id, const std::string &color,
+ bool isWeapon)
+{
+ if (slot >= Net::getCharHandler()->maxSprite())
+ return;
+
+ if (slot >= size())
+ ensureSize(slot + 1);
+
+ if (slot >= mSpriteIDs.size())
+ mSpriteIDs.resize(slot + 1, 0);
+
+ if (slot >= mSpriteColors.size())
+ mSpriteColors.resize(slot + 1, "");
+
+ // id = 0 means unequip
+ if (id == 0)
+ {
+ removeSprite(slot);
+
+ if (isWeapon)
+ mEquippedWeapon = NULL;
+ }
+ else
+ {
+ std::string filename = ItemDB::get(id).getSprite(mGender);
+ AnimatedSprite *equipmentSprite = NULL;
+
+ if (!filename.empty())
+ {
+ if (!color.empty())
+ filename += "|" + color;
+
+ equipmentSprite = AnimatedSprite::load(
+ paths.getStringValue("sprites") + filename);
+ }
+
+ if (equipmentSprite)
+ equipmentSprite->setDirection(getSpriteDirection());
+
+ CompoundSprite::setSprite(slot, equipmentSprite);
+
+ if (isWeapon)
+ mEquippedWeapon = &ItemDB::get(id);
+
+ setAction(mAction);
+ }
+
+ mSpriteIDs[slot] = id;
+ mSpriteColors[slot] = color;
+ recalcSpritesOrder();
+}
+
+void Being::setSpriteID(unsigned int slot, int id)
+{
+ setSprite(slot, id, mSpriteColors[slot]);
+}
+
+void Being::setSpriteColor(unsigned int slot, const std::string &color)
+{
+ setSprite(slot, mSpriteIDs[slot], color);
+}
+
+int Being::getNumberOfLayers() const
+{
+ return CompoundSprite::getNumberOfLayers();
+}
+
+void Being::load()
+{
+ // Hairstyles are encoded as negative numbers. Count how far negative
+ // we can go.
+ int hairstyles = 1;
+
+ while (ItemDB::get(-hairstyles).getSprite(GENDER_MALE) !=
+ paths.getStringValue("spriteErrorFile"))
+ {
+ hairstyles++;
+ }
+
+ mNumberOfHairstyles = hairstyles;
+}
+
+void Being::updateName()
+{
+ if (mShowName)
+ showName();
+}
+
+void Being::reReadConfig()
+{
+ if (mUpdateConfigTime + 1 < cur_time)
+ {
+ mHighlightMapPortals = config.getBoolValue("highlightMapPortals");
+ mConfLineLim = config.getIntValue("chatMaxCharLimit");
+ mSpeechType = config.getIntValue("speech");
+ mHighlightMonsterAttackRange =
+ config.getBoolValue("highlightMonsterAttackRange");
+ mLowTraffic = config.getBoolValue("lowTraffic");
+ mDrawHotKeys = config.getBoolValue("drawHotKeys");
+ mShowBattleEvents = config.getBoolValue("showBattleEvents");
+ mShowMobHP = config.getBoolValue("showMobHP");
+
+ mUpdateConfigTime = cur_time;
+ }
+}
+
+bool Being::updateFromCache()
+{
+ BeingCacheEntry *entry = Being::getCacheEntry(getId());
+ if (entry && !entry->getName().empty()
+ && entry->getTime() + 120 < cur_time)
+ {
+ setName(entry->getName());
+ setPartyName(entry->getPartyName());
+ setLevel(entry->getLevel());
+ setPvpRank(entry->getPvpRank());
+ setIp(entry->getIp());
+ if (getType() == PLAYER)
+ updateColors();
+ return true;
+ }
+ return false;
+}
+
+void Being::addToCache()
+{
+ BeingCacheEntry *entry = Being::getCacheEntry(getId());
+ if (!entry)
+ {
+ entry = new BeingCacheEntry(getId());
+ beingInfoCache.push_front(entry);
+
+ if (beingInfoCache.size() >= CACHE_SIZE)
+ beingInfoCache.pop_back();
+ }
+ entry->setName(getName());
+ entry->setLevel(getLevel());
+ entry->setPartyName(getPartyName());
+ entry->setTime(cur_time);
+ entry->setPvpRank(getPvpRank());
+ entry->setIp(getIp());
+}
+
+BeingCacheEntry* Being::getCacheEntry(int id)
+{
+ for (std::list<BeingCacheEntry*>::iterator i = beingInfoCache.begin();
+ i != beingInfoCache.end(); ++i)
+ {
+ if (id == (*i)->getId())
+ {
+ // Raise priority: move it to front
+ if ((*i)->getTime() + 120 < cur_time)
+ {
+ beingInfoCache.splice(beingInfoCache.begin(),
+ beingInfoCache, i);
+ }
+ return *i;
+ }
+ }
+ return 0;
+}
+
+
+void Being::setGender(Gender gender)
+{
+ if (gender != mGender)
+ {
+ mGender = gender;
+
+ // Reload all subsprites
+ for (unsigned int i = 0; i < mSpriteIDs.size(); i++)
+ {
+ if (mSpriteIDs.at(i) != 0)
+ setSprite(i, mSpriteIDs.at(i), mSpriteColors.at(i));
+ }
+
+ updateName();
+ }
+}
+
+void Being::setGM(bool gm)
+{
+ mIsGM = gm;
+
+ updateColors();
+}
+
+bool Being::canTalk()
+{
+ return mType == NPC;
+}
+
+void Being::talkTo()
+{
+ if (!Client::limitPackets(PACKET_NPC_TALK))
+ return;
+
+ Net::getNpcHandler()->talk(mId);
+}
+
+bool Being::isTalking()
+{
+ return NpcDialog::isActive() || BuyDialog::isActive() ||
+ SellDialog::isActive() || BuySellDialog::isActive() ||
+ NpcPostDialog::isActive();
+}
+
+bool Being::draw(Graphics *graphics, int offsetX, int offsetY) const
+{
+ bool res = true;
+ if (!mErased)
+ res = ActorSprite::draw(graphics, offsetX, offsetY);
+
+ return res;
+}
+
+void Being::drawSprites(Graphics* graphics, int posX, int posY) const
+{
+// CompoundSprite::drawSprites(graphics, posX, posY);
+ for (int f = 0; f < getNumberOfLayers(); f ++)
+ {
+ Sprite *sprite = getSprite(mSpriteRemap[f]);
+ if (sprite)
+ {
+ sprite->setAlpha(mAlpha);
+ sprite->draw(graphics, posX, posY);
+ }
+ }
+}
+
+void Being::drawSpritesSDL(Graphics* graphics, int posX, int posY) const
+{
+// CompoundSprite::drawSprites(graphics, posX, posY);
+
+// logger->log("getNumberOfLayers: %d", getNumberOfLayers());
+
+ for (unsigned f = 0; f < size(); f ++)
+ {
+ Sprite *sprite = getSprite(mSpriteRemap[f]);
+ if (sprite)
+ sprite->draw(graphics, posX, posY);
+ }
+}
+
+bool Being::drawSpriteAt(Graphics *graphics, int x, int y) const
+{
+ bool res = true;
+
+ if (!mErased)
+ res = ActorSprite::drawSpriteAt(graphics, x, y);
+
+ if (mHighlightMapPortals && mMap && mSubType == 45 && !mMap->getHasWarps())
+ {
+ graphics->setColor(userPalette->
+ getColorWithAlpha(UserPalette::PORTAL_HIGHLIGHT));
+
+ graphics->fillRectangle(gcn::Rectangle(
+ x, y, 32, 32));
+
+/*
+ int num = socialWindow->getPortalIndex(getTileX(), getTileY());
+ if (num >= 0)
+ {
+ std::string str = outfitWindow->keyName(num);
+ if (str.length() > 4)
+ str = str.substr(0, 4);
+ gcn::Font *font = gui->getFont();
+ graphics->setColor(userPalette->getColor(UserPalette::BEING));
+ font->drawString(graphics, str, x, y);
+ }
+*/
+ if (mDrawHotKeys && !mName.empty())
+ {
+ gcn::Font *font = gui->getFont();
+ if (font)
+ {
+ graphics->setColor(userPalette->getColor(UserPalette::BEING));
+ font->drawString(graphics, mName, x, y);
+ }
+ }
+ }
+
+ if (mHighlightMonsterAttackRange && getType() == ActorSprite::MONSTER
+ && isAlive())
+ {
+ const int attackRange = 32;
+
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::MONSTER_ATTACK_RANGE));
+
+ graphics->fillRectangle(gcn::Rectangle(
+ x - attackRange, y - attackRange,
+ 2 * attackRange + 32, 2 * attackRange + 32));
+ }
+
+ if (mShowMobHP && player_node && player_node->getTarget() == this
+ && getType() == MONSTER)
+ {
+ // show hp bar here
+ drawHpBar(graphics, x - 50 + 16, y + 32 - 6, 2 * 50, 4);
+ }
+ return res;
+}
+
+void Being::drawHpBar(Graphics *graphics, int x, int y,
+ int width, int height) const
+{
+ if (!mInfo)
+ return;
+
+ int maxHP = mMaxHP;
+
+ if (!maxHP)
+ maxHP = mInfo->getMaxHP();
+
+ if (maxHP <= 0)
+ return;
+
+ if (!mHP && maxHP < mHP)
+ return;
+
+ float p;
+
+ if (mHP)
+ {
+ p = static_cast<float>(maxHP) / static_cast<float>(mHP);
+ }
+ else if (maxHP != mDamageTaken)
+ {
+ p = static_cast<float>(maxHP)
+ / static_cast<float>(maxHP - mDamageTaken);
+ }
+ else
+ {
+ p = 1;
+ }
+
+ if (p <= 0 || p > width)
+ return;
+
+ int dx = width / p;
+
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::MONSTER_HP));
+
+ graphics->fillRectangle(gcn::Rectangle(
+ x, y, dx, height));
+
+ if (width - dx <= 0)
+ return;
+
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::MONSTER_HP2));
+
+ graphics->fillRectangle(gcn::Rectangle(
+ x + dx, y, width - dx, height));
+}
+
+void Being::setHP(int hp)
+{
+ mHP = hp;
+ if (mMaxHP < mHP)
+ mMaxHP = mHP;
+}
+
+void Being::setMaxHP(int hp)
+{
+ mMaxHP = hp;
+ if (mMaxHP < mHP)
+ mMaxHP = mHP;
+}
+
+void Being::resetCounters()
+{
+ mMoveTime = 0;
+ mAttackTime = 0;
+ mTalkTime = 0;
+ mOtherTime = 0;
+ mTestTime = cur_time;
+}
+
+void Being::recalcSpritesOrder()
+{
+// logger->log("recalcSpritesOrder");
+ unsigned sz = size();
+ if (sz < 1)
+ return;
+
+ std::vector<int> slotRemap;
+ std::map<int, int> itemSlotRemap;
+
+// logger->log("preparation start");
+ std::vector<int>::iterator it;
+ for (unsigned slot = 0; slot < sz; slot ++)
+ {
+ slotRemap.push_back(slot);
+
+ int id = mSpriteIDs[slot];
+ if (!id)
+ continue;
+
+ const ItemInfo &info = ItemDB::get(id);
+ if (info.getDrawBefore() > 0)
+ {
+ int id2 = mSpriteIDs[info.getDrawBefore()];
+ std::map<int, int>::iterator orderIt = itemSlotRemap.find(id2);
+ if (orderIt != itemSlotRemap.end())
+ {
+// logger->log("found duplicate (before)");
+ const ItemInfo &info2 = ItemDB::get(id2);
+ if (info.getDrawPriority() < info2.getDrawPriority())
+ {
+// logger->log("old more priority");
+ continue;
+ }
+ else
+ {
+// logger->log("new more priority");
+ itemSlotRemap.erase(id2);
+ }
+ }
+
+ itemSlotRemap[id] = -info.getDrawBefore();
+// logger->log("item slot->slot %d %d->%d", id, slot, itemSlotRemap[id]);
+ }
+ else if (info.getDrawAfter() > 0)
+ {
+ int id2 = mSpriteIDs[info.getDrawAfter()];
+ std::map<int, int>::iterator orderIt = itemSlotRemap.find(id2);
+ if (orderIt != itemSlotRemap.end())
+ {
+// logger->log("found duplicate (after)");
+ const ItemInfo &info2 = ItemDB::get(id2);
+ if (info.getDrawPriority() < info2.getDrawPriority())
+ {
+// logger->log("old more priority");
+ continue;
+ }
+ else
+ {
+// logger->log("new more priority");
+ itemSlotRemap.erase(id2);
+ }
+ }
+
+ itemSlotRemap[id] = info.getDrawAfter();
+// logger->log("item slot->slot %d %d->%d", id, slot, itemSlotRemap[id]);
+ }
+ }
+// logger->log("preparation end");
+
+ int lastRemap = 0;
+ int cnt = 0;
+
+ while (cnt < 15 && lastRemap >= 0)
+ {
+ int lastRemap = -1;
+ cnt ++;
+// logger->log("iteration");
+
+ for (unsigned slot0 = 0; slot0 < sz; slot0 ++)
+ {
+ int slot = searchSlotValue(slotRemap, slot0);
+ int val = slotRemap.at(slot);
+ int id = mSpriteIDs[val];
+ int idx = -1;
+ int idx1 = -1;
+// logger->log("item %d, id=%d", slot, id);
+ int reorder = 0;
+ std::map<int, int>::iterator orderIt = itemSlotRemap.find(id);
+ if (orderIt != itemSlotRemap.end())
+ reorder = orderIt->second;
+
+ if (reorder < 0)
+ {
+// logger->log("move item %d before %d", slot, -reorder);
+ searchSlotValueItr(it, idx, slotRemap, -reorder);
+ if (it == slotRemap.end())
+ return;
+ searchSlotValueItr(it, idx1, slotRemap, val);
+ if (it == slotRemap.end())
+ return;
+ lastRemap = idx1;
+ if (idx1 + 1 != idx)
+ {
+ slotRemap.erase(it);
+ searchSlotValueItr(it, idx, slotRemap, -reorder);
+ slotRemap.insert(it, val);
+ }
+ }
+ else if (reorder > 0)
+ {
+// logger->log("move item %d after %d", slot, reorder);
+ searchSlotValueItr(it, idx, slotRemap, reorder);
+ searchSlotValueItr(it, idx1, slotRemap, val);
+ if (it == slotRemap.end())
+ return;
+ lastRemap = idx1;
+ if (idx1 != idx + 1)
+ {
+ slotRemap.erase(it);
+ searchSlotValueItr(it, idx, slotRemap, reorder);
+ if (it != slotRemap.end())
+ {
+ it ++;
+ if (it != slotRemap.end())
+ slotRemap.insert(it, val);
+ else
+ slotRemap.push_back(val);
+ }
+ else
+ {
+ slotRemap.push_back(val);
+ }
+ }
+ }
+ }
+ }
+
+// logger->log("after remap");
+ for (unsigned slot = 0; slot < sz; slot ++)
+ {
+ mSpriteRemap[slot] = slotRemap[slot];
+// logger->log("slot %d = %d", slot, mSpriteRemap[slot]);
+ }
+}
+
+int Being::searchSlotValue(std::vector<int> &slotRemap, int val)
+{
+ for (unsigned slot = 0; slot < size(); slot ++)
+ {
+ if (slotRemap[slot] == val)
+ return slot;
+ }
+ return getNumberOfLayers() - 1;
+}
+
+void Being::searchSlotValueItr(std::vector<int>::iterator &it, int &idx,
+ std::vector<int> &slotRemap, int val)
+{
+// logger->log("searching %d", val);
+ it = slotRemap.begin();
+ idx = 0;
+ while(it != slotRemap.end())
+ {
+// logger->log("testing %d", *it);
+ if (*it == val)
+ {
+// logger->log("found at %d", idx);
+ return;
+ }
+ it ++;
+ idx ++;
+ }
+// logger->log("not found");
+ idx = -1;
+ return;
+}
diff --git a/src/being.h b/src/being.h
new file mode 100644
index 000000000..09466f5af
--- /dev/null
+++ b/src/being.h
@@ -0,0 +1,770 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BEING_H
+#define BEING_H
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+#include "actorsprite.h"
+#include "configlistener.h"
+#include "map.h"
+#include "particlecontainer.h"
+#include "position.h"
+#include "vector.h"
+
+#include <guichan/color.hpp>
+
+#include <SDL_types.h>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#define FIRST_IGNORE_EMOTE 14
+#define STATUS_EFFECTS 32
+
+#define SPEECH_TIME 500
+#define SPEECH_MAX_TIME 1000
+
+class BeingCacheEntry;
+class BeingInfo;
+class FlashText;
+class Guild;
+class ItemInfo;
+class Item;
+class Particle;
+class Party;
+class Position;
+class SpeechBubble;
+class Text;
+
+extern volatile int cur_time;
+
+enum Gender
+{
+ GENDER_MALE = 0,
+ GENDER_FEMALE = 1,
+ GENDER_UNSPECIFIED = 2
+};
+
+class Being : public ActorSprite, public ConfigListener
+{
+ public:
+ /**
+ * Action the being is currently performing
+ * WARNING: Has to be in sync with the same enum in the Being class
+ * of the server!
+ */
+ enum Action
+ {
+ STAND = 0,
+ MOVE,
+ ATTACK,
+ SIT,
+ DEAD,
+ HURT
+ };
+
+ enum Speech
+ {
+ NO_SPEECH = 0,
+ TEXT_OVERHEAD,
+ NO_NAME_IN_BUBBLE,
+ NAME_IN_BUBBLE
+ };
+
+ enum AttackType
+ {
+ HIT = 0x00,
+ CRITICAL = 0x0a,
+ MULTI = 0x08,
+ REFLECT = 0x04,
+ FLEE = 0x0b
+ };
+
+ enum Reachable
+ {
+ REACH_UNKNOWN = 0,
+ REACH_YES = 1,
+ REACH_NO = 2
+ };
+
+ /**
+ * Directions, to be used as bitmask values
+ */
+ enum BeingDirection
+ {
+ DOWN = 1,
+ LEFT = 2,
+ UP = 4,
+ RIGHT = 8
+ };
+
+ /**
+ * Constructor.
+ *
+ * @param id a unique being id
+ * @param subtype partly determines the type of the being
+ * @param map the map the being is on
+ */
+ Being(int id, Type type, Uint16 subtype, Map *map);
+
+ virtual ~Being();
+
+ Type getType() const
+ { return mType; }
+
+ /**
+ * Removes all path nodes from this being.
+ */
+ void clearPath();
+
+ /**
+ * Returns the time spent in the current action.
+ */
+ int getActionTime() const
+ { return mActionTime; }
+
+ /**
+ * Set the current action time.
+ * @see Ea::BeingHandler that set it to tick time.
+ */
+ void setActionTime(int actionTime)
+ { mActionTime = actionTime; }
+
+ /**
+ * Makes this being take the next tile of its path.
+ * TODO: Used by eAthena only?
+ */
+ virtual void nextTile();
+
+ /**
+ * Get the current X pixel offset.
+ * TODO: Used by eAthena only?
+ */
+ int getXOffset() const
+ { return getOffset(LEFT, RIGHT); }
+
+ /**
+ * Get the current Y pixel offset.
+ * TODO: Used by eAthena only?
+ */
+ int getYOffset() const
+ { return getOffset(UP, DOWN); }
+
+ /**
+ * Creates a path for the being from current position to ex and ey
+ */
+ void setDestination(int ex, int ey);
+
+ /**
+ * Returns the destination for this being.
+ */
+ const Vector &getDestination() const
+ { return mDest; }
+
+ /**
+ * Returns the tile x coord
+ */
+ int getTileX() const
+ { return mX; }
+
+ /**
+ * Returns the tile y coord
+ */
+ int getTileY() const
+ { return mY; }
+
+ /**
+ * Sets the tile x and y coord
+ */
+ void setTileCoords(int x, int y)
+ { mX = x; mY = y; }
+
+ /**
+ * Puts a "speech balloon" above this being for the specified amount
+ * of time.
+ *
+ * @param text The text that should appear.
+ * @param time The amount of time the text should stay in milliseconds.
+ */
+ void setSpeech(const std::string &text, int time = 500);
+
+ /**
+ * Puts a damage bubble above this being.
+ *
+ * @param attacker the attacking being
+ * @param damage the amount of damage recieved (0 means miss)
+ * @param type the attack type
+ */
+ void takeDamage(Being *attacker, int damage, AttackType type);
+
+ /**
+ * Handles an attack of another being by this being.
+ *
+ * @param victim the victim being
+ * @param damage the amount of damage dealt (0 means miss)
+ * @param type the attack type
+ */
+ virtual void handleAttack(Being *victim, int damage, AttackType type);
+
+ /**
+ * Returns the name of the being.
+ */
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Sets the name for the being.
+ *
+ * @param name The name that should appear.
+ */
+ void setName(const std::string &name);
+
+ bool getShowName() const
+ { return mShowName; }
+
+ void setShowName(bool doShowName);
+
+ /**
+ * Sets the name of the party the being is in. Shown in BeingPopup.
+ */
+ void setPartyName(const std::string &name)
+ { mPartyName = name; }
+
+ const std::string &getPartyName() const
+ { return mPartyName; }
+
+ const std::string &getGuildName() const
+ { return mGuildName; }
+
+ /**
+ * Sets the name of the primary guild the being is in. Shown in
+ * BeingPopup (eventually).
+ */
+ void setGuildName(const std::string &name);
+
+ void setGuildPos(const std::string &pos);
+
+ /**
+ * Adds a guild to the being.
+ */
+ void addGuild(Guild *guild);
+
+ /**
+ * Removers a guild from the being.
+ */
+ void removeGuild(int id);
+
+ /**
+ * Returns a pointer to the specified guild that the being is in.
+ */
+ Guild *getGuild(const std::string &guildName) const;
+
+ /**
+ * Returns a pointer to the specified guild that the being is in.
+ */
+ Guild *getGuild(int id) const;
+
+ /**
+ * Returns a pointer to the specified guild that the being is in.
+ */
+ Guild *getGuild() const;
+
+ /**
+ * Returns all guilds the being is in.
+ */
+ const std::map<int, Guild*> &getGuilds() const
+ { return mGuilds; }
+
+ /**
+ * Removes all guilds the being is in.
+ */
+ void clearGuilds();
+
+ /**
+ * Get number of guilds the being belongs to.
+ */
+ short getNumberOfGuilds() const
+ { return static_cast<short>(mGuilds.size()); }
+
+ bool isInParty() const
+ { return mParty != NULL; }
+
+ void setParty(Party *party);
+
+ void setGuild(Guild *guild);
+
+ void updateGuild();
+
+ Party *getParty() const
+ { return mParty; }
+
+ int getSpritesCount()
+ { return static_cast<int>(size()); }
+
+ /**
+ * Sets visible equipments for this being.
+ */
+ void setSprite(unsigned int slot, int id,
+ const std::string &color = "", bool isWeapon = false);
+
+ void setSpriteID(unsigned int slot, int id);
+
+ void setSpriteColor(unsigned int slot, const std::string &color = "");
+
+ /**
+ * Get the number of hairstyles implemented
+ */
+ static int getNumOfHairstyles()
+ { return mNumberOfHairstyles; }
+
+ /**
+ * Get the number of layers used to draw the being
+ */
+ int getNumberOfLayers() const;
+
+ /**
+ * Performs being logic.
+ */
+ virtual void logic();
+
+ /**
+ * Draws the speech text above the being.
+ */
+ void drawSpeech(int offsetX, int offsetY);
+
+ /**
+ * Draws the emotion picture above the being.
+ */
+ void drawEmotion(Graphics *graphics, int offsetX, int offsetY);
+
+ Uint16 getSubType() const
+ { return mSubType; }
+
+ /**
+ * Set Being's subtype (mostly for view for monsters and NPCs)
+ */
+ void setSubtype(Uint16 subtype);
+
+ const BeingInfo *getInfo() const
+ { return mInfo; }
+
+ TargetCursorSize getTargetCursorSize() const;
+
+ int getTargetOffsetX() const;
+
+ int getTargetOffsetY() const;
+
+ /**
+ * Gets the way the object is blocked by other objects.
+ */
+ unsigned char getWalkMask() const;
+
+ /**
+ * Gets the way the monster blocks pathfinding for other objects
+ */
+ Map::BlockType getBlockType() const;
+
+ /**
+ * Sets the walk speed.
+ * in pixels per second for eAthena,
+ * in tiles per second for Manaserv.
+ */
+ void setWalkSpeed(Vector speed)
+ { mWalkSpeed = speed; }
+
+ /**
+ * Gets the walk speed.
+ * in pixels per second for eAthena,
+ * in tiles per second for Manaserv (0.1 precision).
+ */
+ Vector getWalkSpeed() const
+ { return mWalkSpeed; }
+
+ /**
+ * Sets the attack speed.
+ * @todo In what unit?
+ */
+ void setAttackSpeed(int speed)
+ { mAttackSpeed = speed; }
+
+ /**
+ * Gets the attack speed.
+ * @todo In what unit?
+ */
+ int getAttackSpeed() const
+ { return mAttackSpeed; }
+
+ /**
+ * Sets the current action.
+ */
+ virtual void setAction(Action action, int attackType = 0);
+
+ /**
+ * Get the being's action currently performed.
+ */
+ Action getCurrentAction() const
+ { return mAction; }
+
+ /**
+ * Returns whether this being is still alive.
+ */
+ bool isAlive() const
+ { return mAction != DEAD; }
+
+ /**
+ * Returns the current direction.
+ */
+ Uint8 getDirection() const
+ { return mDirection; }
+
+ /**
+ * Sets the current direction.
+ */
+ virtual void setDirection(Uint8 direction);
+
+ /**
+ * Returns the direction the being is facing.
+ */
+ SpriteDirection getSpriteDirection() const
+ { return SpriteDirection(mSpriteDirection); }
+
+ void setPosition(const Vector &pos);
+
+ /**
+ * Overloaded method provided for convenience.
+ *
+ * @see setPosition(const Vector &pos)
+ */
+ inline void setPosition(float x, float y, float z = 0.0f)
+ { setPosition(Vector(x, y, z)); }
+
+ /**
+ * Returns the horizontal size of the current base sprite of the being.
+ */
+ virtual int getWidth() const;
+
+ /**
+ * Returns the vertical size of the current base sprite of the being.
+ */
+ virtual int getHeight() const;
+
+ /**
+ * Returns the being's pixel radius used to detect collisions.
+ */
+ virtual int getCollisionRadius() const;
+
+ /**
+ * Shoots a missile particle from this being, to target being
+ */
+ void fireMissile(Being *target, const std::string &particle);
+
+ /**
+ * Returns the path this being is following. An empty path is returned
+ * when this being isn't following any path currently.
+ */
+ const Path &getPath() const
+ { return mPath; }
+
+ int getDistance()
+ { return mDistance; }
+
+ void setDistance(int n)
+ { mDistance = n; }
+
+ /**
+ * Set the Emoticon type and time displayed above
+ * the being.
+ */
+ void setEmote(Uint8 emotion, int emote_time)
+ {
+ mEmotion = emotion;
+ mEmotionTime = emote_time;
+ }
+
+ /**
+ * Get the current Emoticon type displayed above
+ * the being.
+ */
+ int getEmotion() const
+ { return mEmotion; }
+
+ virtual void drawSprites(Graphics* graphics, int posX, int posY) const;
+
+ virtual void drawSpritesSDL(Graphics* graphics,
+ int posX, int posY) const;
+
+ void drawHpBar(Graphics *graphics, int x, int y,
+ int width, int height) const;
+
+ static void load();
+
+ virtual void optionChanged(const std::string &value);
+
+ void flashName(int time);
+
+ int getDamageTaken() const
+ { return mDamageTaken; }
+
+ void setDamageTaken(int damage)
+ { mDamageTaken = damage; }
+
+ void updateName();
+
+ void setLevel(int n)
+ { mLevel = n; }
+
+ virtual int getLevel() const
+ { return mLevel; }
+
+ void setIsReachable(int n)
+ { mIsReachable = n; }
+
+ int isReachable()
+ { return mIsReachable; }
+
+ static void reReadConfig();
+
+ static BeingCacheEntry* getCacheEntry(int id);
+
+ void addToCache();
+
+ bool updateFromCache();
+
+ /**
+ * Sets the gender of this being.
+ */
+ virtual void setGender(Gender gender);
+
+ Gender getGender() const
+ { return mGender; }
+
+ /**
+ * Whether or not this player is a GM.
+ */
+ bool isGM() const
+ { return mIsGM; }
+
+ /**
+ * Triggers whether or not to show the name as a GM name.
+ */
+ void setGM(bool gm);
+
+ bool canTalk();
+
+ void talkTo();
+
+ static bool isTalking();
+
+ bool draw(Graphics *graphics, int offsetX, int offsetY) const;
+
+ bool drawSpriteAt(Graphics *graphics, int x, int y) const;
+
+ void setMoveTime()
+ { mMoveTime = cur_time; }
+
+ void setAttackTime()
+ { mAttackTime = cur_time; }
+
+ void setTalkTime()
+ { mTalkTime = cur_time; }
+
+ void setTestTime()
+ { mTestTime = cur_time; }
+
+ void setOtherTime()
+ { mOtherTime = cur_time; }
+
+ unsigned int getMoveTime() const
+ { return mMoveTime; }
+
+ unsigned int getAttackTime() const
+ { return mAttackTime; }
+
+ unsigned int getTalkTime() const
+ { return mTalkTime; }
+
+ unsigned int getTestTime() const
+ { return mTestTime; }
+
+ unsigned int getOtherTime() const
+ { return mOtherTime; }
+
+ void resetCounters();
+
+ virtual void updateColors();
+
+ void setEnemy(bool n)
+ { mEnemy = n; }
+
+ const std::string &getIp() const
+ { return mIp; }
+
+ void setIp(std::string ip)
+ { mIp = ip; }
+
+ unsigned int getPvpRank() const
+ { return mPvpRank; }
+
+ void setPvpRank(unsigned int rank)
+ { mPvpRank = rank; }
+
+ void setHP(int n);
+
+ void setMaxHP(int hp);
+
+ int getHP()
+ { return mHP; }
+
+ protected:
+ /**
+ * Sets the new path for this being.
+ */
+ void setPath(const Path &path);
+
+ /**
+ * Updates name's location.
+ */
+ virtual void updateCoords();
+
+ void recalcSpritesOrder();
+
+ void showName();
+
+ BeingInfo *mInfo;
+
+ int mActionTime; /**< Time spent in current action */
+
+ int mEmotion; /**< Currently showing emotion */
+ int mEmotionTime; /**< Time until emotion disappears */
+ /** Time until the last speech sentence disappears */
+ int mSpeechTime;
+
+ int mAttackType;
+ int mAttackSpeed; /**< Attack speed */
+
+ Action mAction; /**< Action the being is performing */
+ Uint16 mSubType; /**< Subtype (graphical view, basically) */
+
+ Uint8 mDirection; /**< Facing direction */
+ Uint8 mSpriteDirection; /**< Facing direction */
+ std::string mName; /**< Name of character */
+ std::string mPartyName;
+ std::string mGuildName;
+
+ /**
+ * Holds a text object when the being displays it's name, 0 otherwise
+ */
+ FlashText *mDispName;
+ const gcn::Color *mNameColor;
+ bool mShowName;
+
+ /** Engine-related infos about weapon. */
+ const ItemInfo *mEquippedWeapon;
+
+ static int mNumberOfHairstyles; /** Number of hair styles in use */
+
+ Path mPath;
+ std::string mSpeech;
+ Text *mText;
+ const gcn::Color *mTextColor;
+
+ int mLevel;
+ Vector mDest; /**< destination coordinates. */
+
+ std::vector<int> mSpriteIDs;
+ std::vector<std::string> mSpriteColors;
+ Gender mGender;
+
+ // Character guild information
+ std::map<int, Guild*> mGuilds;
+ Party *mParty;
+
+ bool mIsGM;
+
+ private:
+
+ /**
+ * Calculates the offset in the given directions.
+ * If walking in direction 'neg' the value is negated.
+ * TODO: Used by eAthena only?
+ */
+ int getOffset(char pos, char neg) const;
+
+ int searchSlotValue(std::vector<int> &slotRemap, int val);
+
+ void searchSlotValueItr(std::vector<int>::iterator &it, int &idx,
+ std::vector<int> &slotRemap, int val);
+
+ const Type mType;
+
+ /** Speech Bubble components */
+ SpeechBubble *mSpeechBubble;
+
+ /**
+ * Walk speed for x and y movement values.
+ * In pixels per second for eAthena,
+ * In pixels per ticks for Manaserv.
+ * @see MILLISECONDS_IN_A_TICK
+ */
+ Vector mWalkSpeed;
+
+ int mX, mY; /**< Position in tile */
+
+ int mDamageTaken;
+ int mHP;
+ int mMaxHP;
+ int mDistance;
+ int mIsReachable; /**< 0 - unknown, 1 - reachable, 2 - not reachable*/
+
+ static int mUpdateConfigTime;
+ static unsigned int mConfLineLim;
+ static int mSpeechType;
+ static bool mHighlightMapPortals;
+ static bool mHighlightMonsterAttackRange;
+ static bool mLowTraffic;
+ static bool mDrawHotKeys;
+ static bool mShowBattleEvents;
+ static bool mShowMobHP;
+// std::string mDisplayName;
+
+ unsigned int mMoveTime;
+ unsigned int mAttackTime;
+ unsigned int mTalkTime;
+ unsigned int mTestTime;
+ unsigned int mOtherTime;
+ bool mErased;
+ bool mEnemy;
+ std::string mIp;
+ unsigned int mPvpRank;
+ int *mSpriteRemap;
+};
+
+extern std::list<BeingCacheEntry*> beingInfoCache;
+
+#endif
diff --git a/src/channel.cpp b/src/channel.cpp
new file mode 100644
index 000000000..92c9b163d
--- /dev/null
+++ b/src/channel.cpp
@@ -0,0 +1,40 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "channel.h"
+
+#include "gui/widgets/channeltab.h"
+
+Channel::Channel(short id,
+ const std::string &name,
+ const std::string &announcement) :
+ mId(id),
+ mName(name),
+ mAnnouncement(announcement),
+ mTab(new ChannelTab(this))
+{
+}
+
+Channel::~Channel()
+{
+ delete mTab;
+ mTab = 0;
+}
diff --git a/src/channel.h b/src/channel.h
new file mode 100644
index 000000000..3e489802a
--- /dev/null
+++ b/src/channel.h
@@ -0,0 +1,89 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#include <string>
+
+class ChannelTab;
+
+class Channel
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param id the id associated with the channel.
+ * @param name the name of the channel.
+ * @param announcement a welcome message.
+ */
+ Channel(short id,
+ const std::string &name,
+ const std::string &announcement = std::string());
+
+ ~Channel();
+
+ /**
+ * Get the id associated witht his channel.
+ */
+ int getId() const { return mId; }
+
+ /**
+ * Get this channel's name.
+ */
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Get the announcement message for this channel.
+ */
+ const std::string &getAnnouncement() const
+ { return mAnnouncement; }
+
+ /**
+ * Sets the name of the channel.
+ */
+ void setName(const std::string &channelName)
+ { mName = channelName; }
+
+ /**
+ * Sets the announcement string of the channel.
+ */
+ void setAnnouncement(const std::string &channelAnnouncement)
+ { mAnnouncement = channelAnnouncement; }
+
+ ChannelTab *getTab()
+ { return mTab; }
+
+ protected:
+ friend class ChannelTab;
+ void setTab(ChannelTab *tab)
+ { mTab = tab; }
+
+ private:
+ unsigned short mId;
+ std::string mName;
+ std::string mAnnouncement;
+ ChannelTab *mTab;
+};
+
+#endif // CHANNEL_H
diff --git a/src/channelmanager.cpp b/src/channelmanager.cpp
new file mode 100644
index 000000000..5bdea4637
--- /dev/null
+++ b/src/channelmanager.cpp
@@ -0,0 +1,91 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "channelmanager.h"
+
+#include "channel.h"
+
+#include "utils/dtor.h"
+
+ChannelManager::ChannelManager()
+{
+}
+
+ChannelManager::~ChannelManager()
+{
+ delete_all(mChannels);
+ mChannels.clear();
+}
+
+Channel *ChannelManager::findById(int id) const
+{
+ Channel *channel = 0;
+ for (std::list<Channel*>::const_iterator itr = mChannels.begin(),
+ end = mChannels.end();
+ itr != end;
+ itr++)
+ {
+ Channel *c = (*itr);
+ if (!c)
+ continue;
+ if (c->getId() == id)
+ {
+ channel = c;
+ break;
+ }
+ }
+ return channel;
+}
+
+Channel *ChannelManager::findByName(const std::string &name) const
+{
+ Channel *channel = 0;
+ if (!name.empty())
+ {
+ for (std::list<Channel*>::const_iterator itr = mChannels.begin(),
+ end = mChannels.end();
+ itr != end;
+ itr++)
+ {
+ Channel *c = (*itr);
+ if (!c)
+ continue;
+ if (c->getName() == name)
+ {
+ channel = c;
+ break;
+ }
+ }
+ }
+ return channel;
+}
+
+void ChannelManager::addChannel(Channel *channel)
+{
+ mChannels.push_back(channel);
+}
+
+void ChannelManager::removeChannel(Channel *channel)
+{
+ mChannels.remove(channel);
+ delete channel;
+ channel = 0;
+}
diff --git a/src/channelmanager.h b/src/channelmanager.h
new file mode 100644
index 000000000..aeb66a9ab
--- /dev/null
+++ b/src/channelmanager.h
@@ -0,0 +1,48 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHANNELMANAGER_H
+#define CHANNELMANAGER_H
+
+#include <list>
+#include <string>
+
+class Channel;
+
+class ChannelManager
+{
+public:
+ ChannelManager();
+ ~ChannelManager();
+
+ Channel *findById(int id) const;
+ Channel *findByName(const std::string &name) const;
+
+ void addChannel(Channel *channel);
+ void removeChannel(Channel *channel);
+
+private:
+ std::list<Channel*> mChannels;
+};
+
+extern ChannelManager *channelManager;
+
+#endif
diff --git a/src/chatlog.cpp b/src/chatlog.cpp
new file mode 100644
index 000000000..73acab880
--- /dev/null
+++ b/src/chatlog.cpp
@@ -0,0 +1,201 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "chatlog.h"
+
+#include <iostream>
+#include <sstream>
+#include <dirent.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef WIN32
+#include <windows.h>
+#elif defined __APPLE__
+#include <Carbon/Carbon.h>
+#endif
+
+#include "log.h"
+#include "configuration.h"
+
+#include "utils/stringutils.h"
+
+ChatLogger::ChatLogger()
+{
+}
+
+ChatLogger::~ChatLogger()
+{
+ if (mLogFile.is_open())
+ mLogFile.close();
+}
+
+void ChatLogger::setLogFile(const std::string &logFilename)
+{
+ if (mLogFile.is_open())
+ mLogFile.close();
+
+ mLogFile.open(logFilename.c_str(), std::ios_base::app);
+
+ if (!mLogFile.is_open())
+ {
+ std::cout << "Warning: error while opening " << logFilename <<
+ " for writing.\n";
+ }
+}
+
+void ChatLogger::setLogDir(const std::string &logDir)
+{
+ mLogDir = logDir;
+
+ if (mLogFile.is_open())
+ mLogFile.close();
+
+ DIR *dir = opendir(mLogDir.c_str());
+ if (!dir)
+ makeDir(mLogDir);
+ else
+ closedir(dir);
+}
+
+void ChatLogger::log(std::string str)
+{
+ std::string dateStr = getDateString();
+ if (!mLogFile.is_open() || dateStr != mLogDate)
+ {
+ mLogDate = dateStr;
+ setLogFile(strprintf("%s/%s/#General_%s.log", mLogDir.c_str(),
+ mServerName.c_str(), dateStr.c_str()));
+ }
+
+ str = removeColors(str);
+ writeTo(mLogFile, str);
+}
+
+void ChatLogger::log(std::string name, std::string str)
+{
+ std::ofstream logFile;
+ logFile.open(strprintf("%s/%s/%s_%s.log", mLogDir.c_str(),
+ mServerName.c_str(), secureName(name).c_str(),
+ getDateString().c_str()).c_str(), std::ios_base::app);
+
+ if (!logFile.is_open())
+ return;
+
+ str = removeColors(str);
+ writeTo(logFile, str);
+
+ if (logFile.is_open())
+ logFile.close();
+}
+
+std::string ChatLogger::getDateString() const
+{
+ std::string date;
+
+ time_t rawtime;
+ struct tm *timeinfo;
+ char buffer [81];
+
+ time (&rawtime);
+ timeinfo = localtime(&rawtime);
+
+ strftime(buffer, 79, "%y-%m-%d", timeinfo);
+ date = buffer;
+ return date;
+}
+
+std::string ChatLogger::secureName(std::string &name) const
+{
+ for (unsigned int f = 0; f < name.length(); f ++)
+ {
+ if (name[f] < '0' && name[f] > '9' && name[f] < 'a' && name[f] > 'z'
+ && name[f] < 'A' && name[f] > 'Z'
+ && name[f] != '-' && name[f] != '+' && name[f] != '='
+ && name[f] != '.' && name[f] != ',' && name[f] != ')'
+ && name[f] != '(' && name[f] != '[' && name[f] != ']')
+ {
+ name[f] = '_';
+ }
+ }
+ return name;
+}
+
+void ChatLogger::writeTo(std::ofstream &file, const std::string &str) const
+{
+ file << str << std::endl;
+}
+
+void ChatLogger::setServerName(const std::string &serverName)
+{
+ mServerName = serverName;
+ if (mServerName == "")
+ mServerName = config.getStringValue("MostUsedServerName0");
+
+ if (mLogFile.is_open())
+ mLogFile.close();
+
+ secureName(mServerName);
+ if (mLogDir != "")
+ {
+ DIR *dir = opendir((mLogDir + "/" + mServerName).c_str());
+ if (!dir)
+ makeDir(mLogDir + "/" + mServerName);
+ else
+ closedir(dir);
+ }
+}
+
+void ChatLogger::makeDir(const std::string &dir)
+{
+#ifdef WIN32
+ mkdir(dir.c_str());
+#else
+ mkdir(dir.c_str(), 0750);
+#endif
+}
+
+void ChatLogger::loadLast(std::string name, std::list<std::string> &list,
+ unsigned n)
+{
+ std::ifstream logFile;
+
+ logFile.open(strprintf("%s/%s/%s_%s.log", mLogDir.c_str(),
+ mServerName.c_str(), secureName(name).c_str(),
+ getDateString().c_str()).c_str(), std::ios::in);
+
+ if (!logFile.is_open())
+ return;
+
+ char line[710];
+ while (logFile.getline(line, 700))
+ {
+ list.push_back(line);
+ if (list.size() > n)
+ list.pop_front();
+ }
+
+ if (logFile.is_open())
+ logFile.close();
+}
diff --git a/src/chatlog.h b/src/chatlog.h
new file mode 100644
index 000000000..d4cd4e73f
--- /dev/null
+++ b/src/chatlog.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CHATLOG_H
+#define _CHATLOG_H
+
+#include <fstream>
+#include <list>
+
+class ChatLogger
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ChatLogger();
+
+ /**
+ * Destructor, closes log file.
+ */
+ ~ChatLogger();
+
+ void setLogDir(const std::string &logDir);
+
+ /**
+ * Enters a message in the log. The message will be timestamped.
+ */
+ void log(std::string str);
+
+ void log(std::string name, std::string str);
+
+ void loadLast(std::string name, std::list<std::string> &list,
+ unsigned n);
+
+ std::string getDateString() const;
+
+ std::string secureName(std::string &str) const;
+
+ void setServerName(const std::string &serverName);
+
+ private:
+ /**
+ * Sets the file to log to and opens it
+ */
+ void setLogFile(const std::string &logFilename);
+
+ void writeTo(std::ofstream &file, const std::string &str) const;
+
+ void makeDir(const std::string &dir);
+
+ std::ofstream mLogFile;
+ std::string mLogDir;
+ std::string mServerName;
+ std::string mLogDate;
+};
+
+extern ChatLogger *chatLogger;
+
+#endif
diff --git a/src/client.cpp b/src/client.cpp
new file mode 100644
index 000000000..0039ce025
--- /dev/null
+++ b/src/client.cpp
@@ -0,0 +1,1986 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "client.h"
+#include "main.h"
+
+#include "chatlog.h"
+#include "configuration.h"
+#include "emoteshortcut.h"
+#include "event.h"
+#include "game.h"
+#include "itemshortcut.h"
+#include "dropshortcut.h"
+#include "keyboardconfig.h"
+#ifdef USE_OPENGL
+#include "openglgraphics.h"
+#include "opengl1graphics.h"
+#endif
+#include "playerrelations.h"
+#include "sound.h"
+#include "statuseffect.h"
+#include "units.h"
+
+#include "gui/changeemaildialog.h"
+#include "gui/changepassworddialog.h"
+#include "gui/charselectdialog.h"
+#include "gui/connectiondialog.h"
+#include "gui/gui.h"
+#include "gui/login.h"
+#include "gui/okdialog.h"
+#include "gui/quitdialog.h"
+#include "gui/register.h"
+#include "gui/sdlinput.h"
+#include "gui/serverdialog.h"
+#include "gui/setup.h"
+#include "gui/theme.h"
+#include "gui/unregisterdialog.h"
+#include "gui/updatewindow.h"
+#include "gui/userpalette.h"
+#include "gui/worldselectdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/desktop.h"
+
+#include "net/charhandler.h"
+#include "net/gamehandler.h"
+#include "net/generalhandler.h"
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+#include "net/packetcounters.h"
+#include "net/worldinfo.h"
+
+#include "resources/colordb.h"
+#include "resources/emotedb.h"
+#include "resources/image.h"
+#include "resources/itemdb.h"
+#include "resources/monsterdb.h"
+#include "resources/specialdb.h"
+#include "resources/npcdb.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+#include "utils/mkdir.h"
+#include "utils/stringutils.h"
+
+#ifdef __APPLE__
+#include <CoreFoundation/CFBundle.h>
+#endif
+
+#include <physfs.h>
+#include <SDL_image.h>
+
+#ifdef WIN32
+#include <SDL_syswm.h>
+#include "utils/specialfolder.h"
+#else
+#include <cerrno>
+#endif
+
+#include <sys/stat.h>
+#include <cassert>
+
+#include <iostream>
+#include <fstream>
+
+#include "mumblemanager.h"
+
+/**
+ * Tells the max tick value,
+ * setting it back to zero (and start again).
+ */
+static const int MAX_TICK_VALUE = 10000;
+
+static const int defaultSfxVolume = 100;
+static const int defaultMusicVolume = 60;
+
+// TODO: Get rid fo these globals
+std::string errorMessage;
+ErrorListener errorListener;
+LoginData loginData;
+
+Configuration config; /**< XML file configuration reader */
+Configuration serverConfig; /**< XML file server configuration reader */
+Configuration branding; /**< XML branding information reader */
+Configuration paths; /**< XML default paths information reader */
+Logger *logger; /**< Log object */
+ChatLogger *chatLogger; /**< Chat log object */
+KeyboardConfig keyboard;
+UserPalette *userPalette;
+Graphics *graphics;
+
+Sound sound;
+
+Uint32 nextTick(Uint32 interval, void *param _UNUSED_);
+Uint32 nextSecond(Uint32 interval, void *param _UNUSED_);
+
+void ErrorListener::action(const gcn::ActionEvent &)
+{
+ Client::setState(STATE_CHOOSE_SERVER);
+}
+
+volatile int tick_time; /**< Tick counter */
+volatile int fps = 0; /**< Frames counted in the last second */
+volatile int frame_count = 0; /**< Counts the frames during one second */
+volatile int cur_time;
+volatile bool runCounters;
+bool isSafeMode = false;
+
+/**
+ * Advances game logic counter.
+ * Called every 10 milliseconds by SDL_AddTimer()
+ * @see MILLISECONDS_IN_A_TICK value
+ */
+Uint32 nextTick(Uint32 interval, void *param _UNUSED_)
+{
+ tick_time++;
+ if (tick_time == MAX_TICK_VALUE)
+ tick_time = 0;
+ return interval;
+}
+
+/**
+ * Updates fps.
+ * Called every seconds by SDL_AddTimer()
+ */
+Uint32 nextSecond(Uint32 interval, void *param _UNUSED_)
+{
+ fps = frame_count;
+ frame_count = 0;
+
+ return interval;
+}
+
+/**
+ * @return the elapsed time in milliseconds
+ * between two tick values.
+ */
+int get_elapsed_time(int start_time)
+{
+ if (start_time <= tick_time)
+ {
+ return (tick_time - start_time) * MILLISECONDS_IN_A_TICK;
+ }
+ else
+ {
+ return (tick_time + (MAX_TICK_VALUE - start_time))
+ * MILLISECONDS_IN_A_TICK;
+ }
+}
+
+
+// This anonymous namespace hides whatever is inside from other modules.
+namespace
+{
+
+class AccountListener : public gcn::ActionListener
+{
+ public:
+ void action(const gcn::ActionEvent &)
+ {
+ Client::setState(STATE_CHAR_SELECT);
+ }
+} accountListener;
+
+class LoginListener : public gcn::ActionListener
+{
+ public:
+ void action(const gcn::ActionEvent &)
+ {
+ Client::setState(STATE_LOGIN);
+ }
+} loginListener;
+
+} // anonymous namespace
+
+
+Client *Client::mInstance = 0;
+
+Client::Client(const Options &options):
+ mOptions(options),
+ mServerConfigDir(""),
+ mRootDir(""),
+ mCurrentDialog(0),
+ mQuitDialog(0),
+ mDesktop(0),
+ mSetupButton(0),
+ mState(STATE_CHOOSE_SERVER),
+ mOldState(STATE_START),
+ mIcon(0),
+ mLogicCounterId(0),
+ mSecondsCounterId(0),
+ mLimitFps(false),
+ mConfigAutoSaved(false),
+ mIsMinimized(false),
+ mGuiAlpha(1.0f)
+{
+ assert(!mInstance);
+ mInstance = this;
+
+ logger = new Logger;
+
+ // Load branding information
+ if (!options.brandingPath.empty())
+ branding.init(options.brandingPath);
+ branding.setDefaultValues(getBrandingDefaults());
+
+ initRootDir();
+ initHomeDir();
+
+ // Configure logger
+ if (!options.logFileName.empty())
+ logger->setLogFile(options.logFileName);
+ else
+ logger->setLogFile(mLocalDataDir + std::string("/manaplus.log"));
+
+ initConfiguration();
+ logger->setDebugLog(config.getBoolValue("debugLog"));
+
+ storeSafeParameters();
+
+ chatLogger = new ChatLogger;
+ if (options.chatLogDir == "")
+ chatLogger->setLogDir(mLocalDataDir + std::string("/logs/"));
+ else
+ chatLogger->setLogDir(options.chatLogDir);
+
+ logger->setLogToStandardOut(config.getBoolValue("logToStandardOut"));
+
+ // Log the mana version
+ logger->log("ManaPlus %s", FULL_VERSION);
+ logger->log("Start configPath: " + config.getConfigPath());
+
+ initScreenshotDir();
+
+ // Initialize SDL
+ logger->log1("Initializing SDL...");
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
+ {
+ logger->error(strprintf("Could not initialize SDL: %s",
+ SDL_GetError()));
+ }
+ atexit(SDL_Quit);
+
+ initPacketLimiter();
+ SDL_EnableUNICODE(1);
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+
+ SDL_WM_SetCaption(branding.getValue("appName", "ManaPlus").c_str(), NULL);
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ if (!resman->setWriteDir(mLocalDataDir))
+ {
+ logger->error(strprintf("%s couldn't be set as home directory! "
+ "Exiting.", mLocalDataDir.c_str()));
+ }
+
+#if defined USE_OPENGL
+ Image::SDLSetEnableAlphaCache(config.getBoolValue("alphaCache")
+ && !config.getIntValue("opengl"));
+ Image::setEnableAlpha(config.getFloatValue("guialpha") != 1.0f
+ || config.getIntValue("opengl"));
+#else
+ Image::SDLSetEnableAlphaCache(config.getBoolValue("alphaCache"));
+ Image::setEnableAlpha(config.getFloatValue("guialpha") != 1.0f);
+#endif
+
+#if defined __APPLE__
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
+ char path[PATH_MAX];
+ if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path,
+ PATH_MAX))
+ {
+ fprintf(stderr, "Can't find Resources directory\n");
+ }
+ CFRelease(resourcesURL);
+ //possible crash
+ strncat(path, "/data", PATH_MAX - 1);
+ resman->addToSearchPath(path, false);
+ mPackageDir = path;
+#else
+ resman->addToSearchPath(PKG_DATADIR "data", false);
+ mPackageDir = PKG_DATADIR "data";
+#endif
+
+ resman->addToSearchPath("data", false);
+
+ // Add branding/data to PhysFS search path
+ if (!options.brandingPath.empty())
+ {
+ std::string path = options.brandingPath;
+
+ // Strip blah.mana from the path
+#ifdef WIN32
+ int loc1 = path.find_last_of('/');
+ int loc2 = path.find_last_of('\\');
+ int loc = static_cast<int>(std::max(loc1, loc2));
+#else
+ int loc = static_cast<int>(path.find_last_of('/'));
+#endif
+ if (loc > 0)
+ resman->addToSearchPath(path.substr(0, loc + 1) + "data", false);
+ }
+
+ // Add the main data directories to our PhysicsFS search path
+ if (!options.dataPath.empty())
+ resman->addToSearchPath(options.dataPath, false);
+
+ // Add the local data directory to PhysicsFS search path
+ resman->addToSearchPath(mLocalDataDir, false);
+
+ //resman->selectSkin();
+
+#ifdef WIN32
+ static SDL_SysWMinfo pInfo;
+ SDL_GetWMInfo(&pInfo);
+ HICON icon = LoadIcon(GetModuleHandle(NULL), "A");
+ if (icon)
+ SetClassLong(pInfo.window, GCL_HICON, (LONG) icon);
+#else
+ mIcon = IMG_Load(resman->getPath(
+ branding.getValue("appIcon", "icons/manaplus.png")).c_str());
+ if (mIcon)
+ {
+ SDL_SetAlpha(mIcon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
+ SDL_WM_SetIcon(mIcon, NULL);
+ }
+#endif
+
+#ifdef USE_OPENGL
+ int useOpenGL = 0;
+ if (!mOptions.noOpenGL)
+ useOpenGL = config.getIntValue("opengl");
+
+ // Setup image loading for the right image format
+ Image::setLoadAsOpenGL(useOpenGL);
+
+ // Create the graphics context
+ switch(useOpenGL)
+ {
+ case 0:
+ graphics = new Graphics;
+ break;
+ case 1:
+ default:
+ graphics = new OpenGLGraphics;
+ break;
+ case 2:
+ graphics = new OpenGL1Graphics;
+ break;
+ };
+
+#else
+ // Create the graphics context
+ graphics = new Graphics;
+#endif
+
+ runCounters = config.getBoolValue("packetcounters");
+
+ const int width = config.getIntValue("screenwidth");
+ const int height = config.getIntValue("screenheight");
+ const int bpp = 0;
+ const bool fullscreen = config.getBoolValue("screen");
+ const bool hwaccel = config.getBoolValue("hwaccel");
+
+ // Try to set the desired video mode
+ if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel))
+ {
+ logger->error(strprintf("Couldn't set %dx%dx%d video mode: %s",
+ width, height, bpp, SDL_GetError()));
+ }
+
+ // Initialize for drawing
+ graphics->_beginDraw();
+
+ Theme::selectSkin();
+// Theme::prepareThemePath();
+
+ // Initialize the item and emote shortcuts.
+ for (int f = 0; f < SHORTCUT_TABS; f ++)
+ itemShortcut[f] = new ItemShortcut(f);
+
+ emoteShortcut = new EmoteShortcut;
+
+ // Initialize the drop shortcuts.
+ dropShortcut = new DropShortcut;
+
+ gui = new Gui(graphics);
+
+ // Initialize sound engine
+ try
+ {
+ if (config.getBoolValue("sound"))
+ sound.init();
+
+ sound.setSfxVolume(config.getIntValue("sfxVolume"));
+ sound.setMusicVolume(config.getIntValue("musicVolume"));
+ }
+ catch (const char *err)
+ {
+ mState = STATE_ERROR;
+ errorMessage = err;
+ logger->log("Warning: %s", err);
+ }
+
+ // Initialize keyboard
+ keyboard.init();
+
+ // Initialise player relations
+ player_relations.init();
+
+ userPalette = new UserPalette;
+ setupWindow = new Setup;
+
+ sound.playMusic(branding.getValue("loginMusic", "Magick - Real.ogg"));
+
+ // Initialize default server
+ mCurrentServer.hostname = options.serverName;
+ mCurrentServer.port = options.serverPort;
+
+ loginData.username = options.username;
+ loginData.password = options.password;
+ loginData.remember = serverConfig.getValue("remember", 0);
+ loginData.registerLogin = false;
+
+ if (mCurrentServer.hostname.empty())
+ {
+ mCurrentServer.hostname =
+ branding.getValue("defaultServer", "").c_str();
+ }
+
+ if (mCurrentServer.port == 0)
+ {
+ mCurrentServer.port = (short) branding.getValue("defaultPort",
+ DEFAULT_PORT);
+ mCurrentServer.type = ServerInfo::parseType(
+ branding.getValue("defaultServerType", "tmwathena"));
+ }
+
+ if (chatLogger)
+ chatLogger->setServerName(mCurrentServer.hostname);
+
+ if (loginData.username.empty() && loginData.remember)
+ loginData.username = serverConfig.getValue("username", "");
+
+ if (mState != STATE_ERROR)
+ mState = STATE_CHOOSE_SERVER;
+
+ // Initialize logic and seconds counters
+ tick_time = 0;
+ mLogicCounterId = SDL_AddTimer(MILLISECONDS_IN_A_TICK, nextTick, NULL);
+ mSecondsCounterId = SDL_AddTimer(1000, nextSecond, NULL);
+
+ const int fpsLimit = (int) config.getIntValue("fpslimit");
+ mLimitFps = fpsLimit > 0;
+
+ // Initialize frame limiting
+ mFpsManager.framecount = 0;
+ mFpsManager.rateticks = 0;
+ mFpsManager.lastticks = 0;
+ mFpsManager.rate = 0;
+
+ SDL_initFramerate(&mFpsManager);
+ logger->log("mFpsManager.framecount: " + toString(mFpsManager.framecount));
+ logger->log("mFpsManager.rateticks: " + toString(mFpsManager.rateticks));
+ logger->log("mFpsManager.lastticks: " + toString(mFpsManager.lastticks));
+ logger->log("mFpsManager.rate: " + toString(mFpsManager.rate));
+ setFramerate(fpsLimit);
+ config.addListener("fpslimit", this);
+ config.addListener("guialpha", this);
+ setGuiAlpha(config.getFloatValue("guialpha"));
+
+ optionChanged("fpslimit");
+
+ // Initialize PlayerInfo
+ PlayerInfo::init();
+}
+
+Client::~Client()
+{
+ logger->log1("Quitting1");
+ config.removeListener("fpslimit", this);
+ config.removeListener("guialpha", this);
+
+ SDL_RemoveTimer(mLogicCounterId);
+ SDL_RemoveTimer(mSecondsCounterId);
+
+ // Unload XML databases
+ ColorDB::unload();
+ EmoteDB::unload();
+ ItemDB::unload();
+ MonsterDB::unload();
+ NPCDB::unload();
+ StatusEffect::unload();
+
+ // Before config.write() since it writes the shortcuts to the config
+ for (int f = 0; f < SHORTCUT_TABS; f ++)
+ {
+ delete itemShortcut[f];
+ itemShortcut[f] = 0;
+ }
+ delete emoteShortcut;
+ emoteShortcut = 0;
+ delete dropShortcut;
+ dropShortcut = 0;
+
+ player_relations.store();
+
+ logger->log1("Quitting2");
+
+ delete gui;
+ gui = 0;
+
+ logger->log1("Quitting3");
+
+ delete graphics;
+ graphics = 0;
+
+ logger->log1("Quitting4");
+
+ // Shutdown libxml
+ xmlCleanupParser();
+
+ logger->log1("Quitting5");
+
+ // Shutdown sound
+ sound.close();
+
+ logger->log1("Quitting6");
+
+ ResourceManager::deleteInstance();
+
+ logger->log1("Quitting8");
+
+ SDL_FreeSurface(mIcon);
+
+ logger->log1("Quitting9");
+
+ delete userPalette;
+ userPalette = 0;
+
+ logger->log1("Quitting10");
+
+ config.write();
+ serverConfig.write();
+
+ logger->log1("Quitting11");
+
+ delete chatLogger;
+ chatLogger = 0;
+
+ delete logger;
+ logger = 0;
+
+ mInstance = 0;
+}
+
+int Client::exec()
+{
+ int lastTickTime = tick_time;
+
+ if (!mumbleManager)
+ mumbleManager = new MumbleManager();
+
+ Game *game = 0;
+ SDL_Event event;
+
+ while (mState != STATE_EXIT)
+ {
+// bool handledEvents = false;
+
+ if (game)
+ {
+ // Let the game handle the events while it is active
+ game->handleInput();
+ }
+ else
+ {
+ // Handle SDL events
+ while (SDL_PollEvent(&event))
+ {
+// handledEvents = true;
+
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ mState = STATE_EXIT;
+ break;
+
+ case SDL_KEYDOWN:
+ default:
+ break;
+ }
+
+ guiInput->pushInput(event);
+ if (player_node && mumbleManager)
+ {
+ mumbleManager->setPos(player_node->getTileX(),
+ player_node->getTileY(), player_node->getDirection());
+ }
+ }
+ }
+
+ if (Net::getGeneralHandler())
+ Net::getGeneralHandler()->flushNetwork();
+
+ while (get_elapsed_time(lastTickTime) > 0)
+ {
+ gui->logic();
+ if (game)
+ game->logic();
+
+ ++lastTickTime;
+ }
+
+ // This is done because at some point tick_time will wrap.
+ lastTickTime = tick_time;
+
+ // Update the screen when application is active, delay otherwise.
+ if (SDL_GetAppState() & SDL_APPACTIVE)
+ {
+ frame_count++;
+ gui->draw();
+ graphics->updateScreen();
+// logger->log("active");
+ }
+ else
+ {
+// logger->log("inactive");
+ SDL_Delay(10);
+ }
+
+ if (mLimitFps)
+ SDL_framerateDelay(&mFpsManager);
+
+ // TODO: Add connect timeouts
+ if (mState == STATE_CONNECT_GAME &&
+ Net::getGameHandler()->isConnected())
+ {
+ Net::getLoginHandler()->disconnect();
+ }
+ else if (mState == STATE_CONNECT_SERVER &&
+ mOldState == STATE_CHOOSE_SERVER)
+ {
+ mServerName = mCurrentServer.hostname;
+ initServerConfig(mCurrentServer.hostname);
+ if (mOptions.username.empty())
+ loginData.username = serverConfig.getValue("username", "");
+ else
+ loginData.username = mOptions.username;
+
+ loginData.remember = serverConfig.getValue("remember", 0);
+
+ Net::connectToServer(mCurrentServer);
+
+ if (mumbleManager)
+ mumbleManager->setServer(mCurrentServer.hostname);
+
+ if (!mConfigAutoSaved)
+ {
+ mConfigAutoSaved = true;
+ config.write();
+ }
+ }
+ else if (mState == STATE_CONNECT_SERVER &&
+ mOldState != STATE_CHOOSE_SERVER &&
+ Net::getLoginHandler()->isConnected())
+ {
+ mState = STATE_LOGIN;
+ }
+ else if (mState == STATE_WORLD_SELECT && mOldState == STATE_UPDATE)
+ {
+ if (Net::getLoginHandler()->getWorlds().size() < 2)
+ mState = STATE_LOGIN;
+ }
+ else if (mOldState == STATE_START ||
+ (mOldState == STATE_GAME && mState != STATE_GAME))
+ {
+ gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
+
+ mDesktop = new Desktop;
+ top->add(mDesktop);
+ mSetupButton = new Button(_("Setup"), "Setup", this);
+ mSetupButton->setPosition(top->getWidth()
+ - mSetupButton->getWidth() - 3, 3);
+ top->add(mSetupButton);
+
+ int screenWidth = config.getIntValue("screenwidth");
+ int screenHeight = config.getIntValue("screenheight");
+
+ mDesktop->setSize(screenWidth, screenHeight);
+ }
+
+ if (mState == STATE_SWITCH_LOGIN && mOldState == STATE_GAME)
+ Net::getGameHandler()->disconnect();
+
+ if (mState != mOldState)
+ {
+ {
+ Mana::Event event(EVENT_STATECHANGE);
+ event.setInt("oldState", mOldState);
+ event.setInt("newState", mState);
+ Mana::Event::trigger(CHANNEL_CLIENT, event);
+ }
+
+ if (mOldState == STATE_GAME)
+ {
+ delete game;
+ game = 0;
+ }
+
+ mOldState = mState;
+
+ // Get rid of the dialog of the previous state
+ delete mCurrentDialog;
+ mCurrentDialog = 0;
+ // State has changed, while the quitDialog was active, it might
+ // not be correct anymore
+ if (mQuitDialog)
+ {
+ mQuitDialog->scheduleDelete();
+ mQuitDialog = 0;
+ }
+
+ switch (mState)
+ {
+ case STATE_CHOOSE_SERVER:
+ logger->log1("State: CHOOSE SERVER");
+
+ // Allow changing this using a server choice dialog
+ // We show the dialog box only if the command-line
+ // options weren't set.
+ if (mOptions.serverName.empty() && mOptions.serverPort == 0
+ && !branding.getValue("onlineServerList", "a").empty())
+ {
+ // Don't allow an alpha opacity
+ // lower than the default value
+ Theme::instance()->setMinimumOpacity(0.8f);
+
+ mCurrentDialog = new ServerDialog(&mCurrentServer,
+ mConfigDir);
+ }
+ else
+ {
+ mState = STATE_CONNECT_SERVER;
+
+ // Reset options so that cancelling or connect
+ // timeout will show the server dialog.
+ mOptions.serverName.clear();
+ mOptions.serverPort = 0;
+ }
+ break;
+
+ case STATE_CONNECT_SERVER:
+ logger->log1("State: CONNECT SERVER");
+ mCurrentDialog = new ConnectionDialog(
+ _("Connecting to server"), STATE_SWITCH_SERVER);
+ break;
+
+ case STATE_LOGIN:
+ logger->log1("State: LOGIN");
+ // Don't allow an alpha opacity
+ // lower than the default value
+ Theme::instance()->setMinimumOpacity(0.8f);
+
+ loginData.updateType
+ = serverConfig.getValue("updateType", 1);
+
+ if (mOptions.username.empty()
+ || mOptions.password.empty())
+ {
+ mCurrentDialog = new LoginDialog(&loginData,
+ mCurrentServer.hostname, &mOptions.updateHost);
+ }
+ else
+ {
+ mState = STATE_LOGIN_ATTEMPT;
+ // Clear the password so that when login fails, the
+ // dialog will show up next time.
+ mOptions.password.clear();
+ }
+ break;
+
+ case STATE_LOGIN_ATTEMPT:
+ logger->log1("State: LOGIN ATTEMPT");
+ accountLogin(&loginData);
+ mCurrentDialog = new ConnectionDialog(
+ _("Logging in"), STATE_SWITCH_SERVER);
+ break;
+
+ case STATE_WORLD_SELECT:
+ logger->log1("State: WORLD SELECT");
+ {
+ Worlds worlds = Net::getLoginHandler()->getWorlds();
+
+ if (worlds.empty())
+ {
+ // Trust that the netcode knows what it's doing
+ mState = STATE_UPDATE;
+ }
+ else if (worlds.size() == 1)
+ {
+ Net::getLoginHandler()->chooseServer(0);
+ mState = STATE_UPDATE;
+ }
+ else
+ {
+ mCurrentDialog = new WorldSelectDialog(worlds);
+ if (mOptions.chooseDefault)
+ {
+ static_cast<WorldSelectDialog*>(mCurrentDialog)
+ ->action(gcn::ActionEvent(0, "ok"));
+ }
+ }
+ }
+ break;
+
+ case STATE_WORLD_SELECT_ATTEMPT:
+ logger->log1("State: WORLD SELECT ATTEMPT");
+ mCurrentDialog = new ConnectionDialog(
+ _("Entering game world"), STATE_WORLD_SELECT);
+ break;
+
+ case STATE_UPDATE:
+ // Determine which source to use for the update host
+ if (!mOptions.updateHost.empty())
+ mUpdateHost = mOptions.updateHost;
+ else
+ mUpdateHost = loginData.updateHost;
+ initUpdatesDir();
+
+ if (mOptions.skipUpdate)
+ {
+ mState = STATE_LOAD_DATA;
+ }
+ else if (loginData.updateType & LoginData::Upd_Skip)
+ {
+ UpdaterWindow::loadLocalUpdates(mLocalDataDir + "/"
+ + mUpdatesDir);
+ mState = STATE_LOAD_DATA;
+ }
+ else
+ {
+ logger->log1("State: UPDATE");
+ mCurrentDialog = new UpdaterWindow(mUpdateHost,
+ mLocalDataDir + "/" + mUpdatesDir,
+ mOptions.dataPath.empty(),
+ loginData.updateType);
+ }
+ break;
+
+ case STATE_LOAD_DATA:
+ {
+ logger->log1("State: LOAD DATA");
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ // If another data path has been set,
+ // we don't load any other files...
+ if (mOptions.dataPath.empty())
+ {
+ // Add customdata directory
+ resman->searchAndAddArchives(
+ "customdata/",
+ "zip",
+ false);
+ }
+
+ if (!mOptions.skipUpdate)
+ {
+ resman->searchAndAddArchives(
+ mUpdatesDir + "/local/",
+ "zip",
+ false);
+
+ resman->addToSearchPath(mLocalDataDir + "/"
+ + mUpdatesDir + "/local/", false);
+ }
+
+ // Read default paths file 'data/paths.xml'
+ paths.init("paths.xml", true);
+ paths.setDefaultValues(getPathsDefaults());
+
+ Mana::Event event(EVENT_STATECHANGE);
+ event.setInt("newState", STATE_LOAD_DATA);
+ event.setInt("oldState", mOldState);
+ Mana::Event::trigger(CHANNEL_CLIENT, event);
+
+ // Load XML databases
+ ColorDB::load();
+ ItemDB::load();
+ Being::load(); // Hairstyles
+ MonsterDB::load();
+ SpecialDB::load();
+ NPCDB::load();
+ EmoteDB::load();
+ StatusEffect::load();
+ Units::loadUnits();
+
+ ActorSprite::load();
+
+ if (mDesktop)
+ mDesktop->reloadWallpaper();
+
+ mState = STATE_GET_CHARACTERS;
+ break;
+ }
+ case STATE_GET_CHARACTERS:
+ logger->log1("State: GET CHARACTERS");
+ Net::getCharHandler()->requestCharacters();
+ mCurrentDialog = new ConnectionDialog(
+ _("Requesting characters"),
+ STATE_SWITCH_SERVER);
+ break;
+
+ case STATE_CHAR_SELECT:
+ logger->log1("State: CHAR SELECT");
+ // Don't allow an alpha opacity
+ // lower than the default value
+ Theme::instance()->setMinimumOpacity(0.8f);
+
+ mCurrentDialog = new CharSelectDialog(&loginData);
+
+ if (!(static_cast<CharSelectDialog*>(mCurrentDialog))
+ ->selectByName(mOptions.character,
+ CharSelectDialog::Choose))
+ {
+ (static_cast<CharSelectDialog*>(mCurrentDialog))
+ ->selectByName(
+ serverConfig.getValue("lastCharacter", ""),
+ mOptions.chooseDefault ?
+ CharSelectDialog::Choose :
+ CharSelectDialog::Focus);
+ }
+
+ break;
+
+ case STATE_CONNECT_GAME:
+ logger->log1("State: CONNECT GAME");
+
+ Net::getGameHandler()->connect();
+ mCurrentDialog = new ConnectionDialog(
+ _("Connecting to the game server"),
+ Net::getNetworkType() == ServerInfo::TMWATHENA ?
+ STATE_CHOOSE_SERVER : STATE_SWITCH_CHARACTER);
+ break;
+
+ case STATE_CHANGE_MAP:
+ logger->log1("State: CHANGE_MAP");
+
+ Net::getGameHandler()->connect();
+ mCurrentDialog = new ConnectionDialog(
+ _("Changing game servers"),
+ STATE_SWITCH_CHARACTER);
+ break;
+
+ case STATE_GAME:
+ if (player_node)
+ {
+ logger->log("Memorizing selected character %s",
+ player_node->getName().c_str());
+ config.setValue("lastCharacter",
+ player_node->getName());
+ if (mumbleManager)
+ mumbleManager->setPlayer(player_node->getName());
+ }
+
+ // Fade out logon-music here too to give the desired effect
+ // of "flowing" into the game.
+ sound.fadeOutMusic(1000);
+
+ // Allow any alpha opacity
+ Theme::instance()->setMinimumOpacity(-1.0f);
+
+ delete mSetupButton;
+ mSetupButton = 0;
+ delete mDesktop;
+ mDesktop = 0;
+
+ mCurrentDialog = NULL;
+
+ logger->log1("State: GAME");
+ game = new Game;
+ break;
+
+ case STATE_LOGIN_ERROR:
+ logger->log1("State: LOGIN ERROR");
+ mCurrentDialog = new OkDialog(_("Error"), errorMessage);
+ mCurrentDialog->addActionListener(&loginListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
+ break;
+
+ case STATE_ACCOUNTCHANGE_ERROR:
+ logger->log1("State: ACCOUNT CHANGE ERROR");
+ mCurrentDialog = new OkDialog(_("Error"), errorMessage);
+ mCurrentDialog->addActionListener(&accountListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
+ break;
+
+ case STATE_REGISTER_PREP:
+ logger->log1("State: REGISTER_PREP");
+ Net::getLoginHandler()->getRegistrationDetails();
+ mCurrentDialog = new ConnectionDialog(
+ _("Requesting registration details"), STATE_LOGIN);
+ break;
+
+ case STATE_REGISTER:
+ logger->log1("State: REGISTER");
+ mCurrentDialog = new RegisterDialog(&loginData);
+ break;
+
+ case STATE_REGISTER_ATTEMPT:
+ logger->log("Username is %s", loginData.username.c_str());
+ Net::getLoginHandler()->registerAccount(&loginData);
+ break;
+
+ case STATE_CHANGEPASSWORD:
+ logger->log1("State: CHANGE PASSWORD");
+ mCurrentDialog = new ChangePasswordDialog(&loginData);
+ break;
+
+ case STATE_CHANGEPASSWORD_ATTEMPT:
+ logger->log1("State: CHANGE PASSWORD ATTEMPT");
+ Net::getLoginHandler()->changePassword(loginData.username,
+ loginData.password,
+ loginData.newPassword);
+ break;
+
+ case STATE_CHANGEPASSWORD_SUCCESS:
+ logger->log1("State: CHANGE PASSWORD SUCCESS");
+ mCurrentDialog = new OkDialog(_("Password Change"),
+ _("Password changed successfully!"));
+ mCurrentDialog->addActionListener(&accountListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
+ loginData.password = loginData.newPassword;
+ loginData.newPassword = "";
+ break;
+
+ case STATE_CHANGEEMAIL:
+ logger->log1("State: CHANGE EMAIL");
+ mCurrentDialog = new ChangeEmailDialog(&loginData);
+ break;
+
+ case STATE_CHANGEEMAIL_ATTEMPT:
+ logger->log1("State: CHANGE EMAIL ATTEMPT");
+ Net::getLoginHandler()->changeEmail(loginData.email);
+ break;
+
+ case STATE_CHANGEEMAIL_SUCCESS:
+ logger->log1("State: CHANGE EMAIL SUCCESS");
+ mCurrentDialog = new OkDialog(_("Email Change"),
+ _("Email changed successfully!"));
+ mCurrentDialog->addActionListener(&accountListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
+ break;
+
+ case STATE_UNREGISTER:
+ logger->log1("State: UNREGISTER");
+ mCurrentDialog = new UnRegisterDialog(&loginData);
+ break;
+
+ case STATE_UNREGISTER_ATTEMPT:
+ logger->log1("State: UNREGISTER ATTEMPT");
+ Net::getLoginHandler()->unregisterAccount(
+ loginData.username, loginData.password);
+ break;
+
+ case STATE_UNREGISTER_SUCCESS:
+ logger->log1("State: UNREGISTER SUCCESS");
+ Net::getLoginHandler()->disconnect();
+
+ mCurrentDialog = new OkDialog(_("Unregister Successful"),
+ _("Farewell, come back any time..."));
+ loginData.clear();
+ //The errorlistener sets the state to STATE_CHOOSE_SERVER
+ mCurrentDialog->addActionListener(&errorListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
+ break;
+
+ case STATE_SWITCH_SERVER:
+ logger->log1("State: SWITCH SERVER");
+
+ Net::getLoginHandler()->disconnect();
+ Net::getGameHandler()->disconnect();
+
+ mState = STATE_CHOOSE_SERVER;
+ break;
+
+ case STATE_SWITCH_LOGIN:
+ logger->log1("State: SWITCH LOGIN");
+
+ Net::getLoginHandler()->logout();
+
+ mState = STATE_LOGIN;
+ break;
+
+ case STATE_SWITCH_CHARACTER:
+ logger->log1("State: SWITCH CHARACTER");
+
+ // Done with game
+ Net::getGameHandler()->disconnect();
+
+ mState = STATE_GET_CHARACTERS;
+ break;
+
+ case STATE_LOGOUT_ATTEMPT:
+ logger->log1("State: LOGOUT ATTEMPT");
+ // TODO
+ break;
+
+ case STATE_WAIT:
+ logger->log1("State: WAIT");
+ break;
+
+ case STATE_EXIT:
+ logger->log1("State: EXIT");
+ Net::unload();
+ break;
+
+ case STATE_FORCE_QUIT:
+ logger->log1("State: FORCE QUIT");
+ if (Net::getGeneralHandler())
+ Net::getGeneralHandler()->unload();
+ mState = STATE_EXIT;
+ break;
+
+ case STATE_ERROR:
+ logger->log1("State: ERROR");
+ logger->log("Error: %s\n", errorMessage.c_str());
+ mCurrentDialog = new OkDialog(_("Error"), errorMessage);
+ mCurrentDialog->addActionListener(&errorListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
+ Net::getGameHandler()->disconnect();
+ break;
+
+ case STATE_AUTORECONNECT_SERVER:
+ //++++++
+ break;
+
+ default:
+ mState = STATE_FORCE_QUIT;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void Client::optionChanged(const std::string &name)
+{
+ if (name == "fpslimit")
+ {
+ const int fpsLimit = config.getIntValue("fpslimit");
+ mLimitFps = fpsLimit > 0;
+ setFramerate(fpsLimit);
+ }
+ else if (name == "guialpha")
+ {
+ setGuiAlpha(config.getFloatValue("guialpha"));
+ }
+}
+
+void Client::action(const gcn::ActionEvent &event)
+{
+ Window *window = 0;
+
+ if (event.getId() == "Setup")
+ window = setupWindow;
+
+ if (window)
+ {
+ window->setVisible(!window->isVisible());
+ if (window->isVisible())
+ window->requestMoveToTop();
+ }
+}
+
+void Client::initRootDir()
+{
+ mRootDir = PHYSFS_getBaseDir();
+ std::string portableName = mRootDir + "portable.xml";
+ struct stat statbuf;
+
+ if (!stat(portableName.c_str(), &statbuf) && S_ISREG(statbuf.st_mode))
+ {
+ std::string dir;
+ Configuration portable;
+ portable.init(portableName);
+
+ logger->log("Portable file: %s", portableName.c_str());
+
+ if (mOptions.localDataDir.empty())
+ {
+ dir = portable.getValue("dataDir", "");
+ if (!dir.empty())
+ {
+ mOptions.localDataDir = mRootDir + dir;
+ logger->log("Portable data dir: %s",
+ mOptions.localDataDir.c_str());
+ }
+ }
+
+ if (mOptions.configDir.empty())
+ {
+ dir = portable.getValue("configDir", "");
+ if (!dir.empty())
+ {
+ mOptions.configDir = mRootDir + dir;
+ logger->log("Portable config dir: %s",
+ mOptions.configDir.c_str());
+ }
+ }
+
+ if (mOptions.screenshotDir.empty())
+ {
+ dir = portable.getValue("screenshotDir", "");
+ if (!dir.empty())
+ {
+ mOptions.screenshotDir = mRootDir + dir;
+ logger->log("Portable screenshot dir: %s",
+ mOptions.screenshotDir.c_str());
+ }
+ }
+ }
+}
+
+/**
+ * Initializes the home directory. On UNIX and FreeBSD, ~/.mana is used. On
+ * Windows and other systems we use the current working directory.
+ */
+void Client::initHomeDir()
+{
+ mLocalDataDir = mOptions.localDataDir;
+
+ if (mLocalDataDir.empty())
+ {
+#ifdef __APPLE__
+ // Use Application Directory instead of .mana
+ mLocalDataDir = std::string(PHYSFS_getUserDir()) +
+ "/Library/Application Support/" +
+ branding.getValue("appName", "Mana");
+#elif defined WIN32
+ mLocalDataDir = getSpecialFolderLocation(CSIDL_LOCAL_APPDATA);
+ if (mLocalDataDir.empty())
+ mLocalDataDir = std::string(PHYSFS_getUserDir());
+ mLocalDataDir += "/Mana";
+#else
+ mLocalDataDir = std::string(PHYSFS_getUserDir()) +
+ ".local/share/mana";
+#endif
+ }
+
+ if (mkdir_r(mLocalDataDir.c_str()))
+ {
+ logger->error(strprintf(_("%s doesn't exist and can't be created! "
+ "Exiting."), mLocalDataDir.c_str()));
+ }
+
+ mConfigDir = mOptions.configDir;
+
+ if (mConfigDir.empty())
+ {
+#ifdef __APPLE__
+ mConfigDir = mLocalDataDir + "/"
+ + branding.getValue("appShort", "mana");
+#elif defined WIN32
+ mConfigDir = getSpecialFolderLocation(CSIDL_APPDATA);
+ if (mConfigDir.empty())
+ mConfigDir = mLocalDataDir;
+ else
+ mConfigDir += "/mana/" + branding.getValue("appShort", "Mana");
+#else
+ mConfigDir = std::string(PHYSFS_getUserDir()) +
+ "/.config/mana/" + branding.getValue("appShort", "mana");
+#endif
+ logger->log("Generating config dir: " + mConfigDir);
+ }
+
+ if (mkdir_r(mConfigDir.c_str()))
+ {
+ logger->error(strprintf(_("%s doesn't exist and can't be created! "
+ "Exiting."), mConfigDir.c_str()));
+ }
+
+ struct stat statbuf;
+ std::string newConfigFile = mConfigDir + "/config.xml";
+ if (stat(newConfigFile.c_str(), &statbuf))
+ {
+ std::string oldConfigFile = std::string(PHYSFS_getUserDir()) +
+ "/.mana/config.xml";
+ if (mRootDir.empty() && !stat(oldConfigFile.c_str(), &statbuf)
+ && S_ISREG(statbuf.st_mode))
+ {
+ std::ifstream oldConfig;
+ std::ofstream newConfig;
+ logger->log1("Copying old TMW settings.");
+
+ oldConfig.open(oldConfigFile.c_str(), std::ios::binary);
+ newConfig.open(newConfigFile.c_str(), std::ios::binary);
+
+ if (!oldConfig.is_open() || !newConfig.is_open())
+ {
+ logger->log1("Unable to copy old settings.");
+ }
+ else
+ {
+ newConfig << oldConfig.rdbuf();
+ newConfig.close();
+ oldConfig.close();
+ }
+ }
+ }
+}
+
+/**
+ * Initializes the home directory. On UNIX and FreeBSD, ~/.mana is used. On
+ * Windows and other systems we use the current working directory.
+ */
+void Client::initServerConfig(std::string serverName)
+{
+ mServerConfigDir = mConfigDir + "/" + serverName;
+
+ if (mkdir_r(mServerConfigDir.c_str()))
+ {
+ logger->error(strprintf(_("%s doesn't exist and can't be created! "
+ "Exiting."), mServerConfigDir.c_str()));
+ }
+ FILE *configFile = 0;
+ std::string configPath;
+
+ configPath = mServerConfigDir + "/config.xml";
+ configFile = fopen(configPath.c_str(), "r");
+ if (!configFile)
+ {
+ configFile = fopen(configPath.c_str(), "wt");
+ logger->log("Creating new server config: " + configPath);
+ }
+ if (configFile)
+ {
+ fclose(configFile);
+ serverConfig.init(configPath);
+ logger->log("serverConfigPath: " + configPath);
+ }
+ initPacketLimiter();
+ initTradeFilter();
+ player_relations.init();
+
+ // Initialize the item and emote shortcuts.
+ for (int f = 0; f < SHORTCUT_TABS; f ++)
+ {
+ delete itemShortcut[f];
+ itemShortcut[f] = new ItemShortcut(f);
+ }
+ delete emoteShortcut;
+ emoteShortcut = new EmoteShortcut;
+
+ // Initialize the drop shortcuts.
+ delete dropShortcut;
+ dropShortcut = new DropShortcut;
+}
+
+/**
+ * Initialize configuration.
+ */
+void Client::initConfiguration()
+{
+ // Fill configuration with defaults
+ config.setValue("hwaccel", false);
+#if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL
+ config.setValue("opengl", 1);
+#else
+ config.setValue("opengl", 0);
+#endif
+ config.setValue("screen", false);
+ config.setValue("sound", true);
+ config.setValue("guialpha", 0.8f);
+ config.setValue("remember", true);
+ config.setValue("sfxVolume", 100);
+ config.setValue("musicVolume", 60);
+ config.setValue("fpslimit", 60);
+ std::string defaultUpdateHost = branding.getValue("defaultUpdateHost", "");
+ config.setValue("updatehost", defaultUpdateHost);
+ config.setValue("customcursor", true);
+ config.setValue("useScreenshotDirectorySuffix", true);
+ config.setValue("ChatLogLength", 128);
+
+ // Checking if the configuration file exists... otherwise create it with
+ // default options.
+ FILE *configFile = 0;
+ std::string configPath;
+// bool oldConfig = false;
+// int emptySize = config.getSize();
+
+ configPath = mConfigDir + "/config.xml";
+
+ configFile = fopen(configPath.c_str(), "r");
+
+ // If we can't read it, it doesn't exist !
+ if (!configFile)
+ {
+ // We reopen the file in write mode and we create it
+ configFile = fopen(configPath.c_str(), "wt");
+ logger->log1("Creating new config");
+// oldConfig = false;
+ }
+ if (!configFile)
+ {
+ logger->log("Can't create %s. Using defaults.", configPath.c_str());
+ }
+ else
+ {
+ fclose(configFile);
+ config.init(configPath);
+ config.setDefaultValues(getConfigDefaults());
+ logger->log("configPath: " + configPath);
+ }
+}
+
+/**
+ * Parse the update host and determine the updates directory
+ * Then verify that the directory exists (creating if needed).
+ */
+void Client::initUpdatesDir()
+{
+ std::stringstream updates;
+
+ // If updatesHost is currently empty, fill it from config file
+ if (mUpdateHost.empty())
+ mUpdateHost = config.getStringValue("updatehost");
+
+ // Don't go out of range int he next check
+ if (mUpdateHost.length() < 2)
+ return;
+
+ // Remove any trailing slash at the end of the update host
+ if (!mUpdateHost.empty() && mUpdateHost.at(mUpdateHost.size() - 1) == '/')
+ mUpdateHost.resize(mUpdateHost.size() - 1);
+
+ // Parse out any "http://" or "ftp://", and set the updates directory
+ size_t pos;
+ pos = mUpdateHost.find("://");
+ if (pos != mUpdateHost.npos)
+ {
+ if (pos + 3 < mUpdateHost.length() && !mUpdateHost.empty())
+ {
+ updates << "updates/" << mUpdateHost.substr(pos + 3);
+ mUpdatesDir = updates.str();
+ }
+ else
+ {
+ logger->log("Error: Invalid update host: %s", mUpdateHost.c_str());
+ errorMessage = strprintf(_("Invalid update host: %s"),
+ mUpdateHost.c_str());
+ mState = STATE_ERROR;
+ }
+ }
+ else
+ {
+ logger->log1("Warning: no protocol was specified for the update host");
+ updates << "updates/" << mUpdateHost;
+ mUpdatesDir = updates.str();
+ }
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ // Verify that the updates directory exists. Create if necessary.
+ if (!resman->isDirectory("/" + mUpdatesDir))
+ {
+ if (!resman->mkdir("/" + mUpdatesDir))
+ {
+#if defined WIN32
+ std::string newDir = mLocalDataDir + "\\" + mUpdatesDir;
+ std::string::size_type loc = newDir.find("/", 0);
+
+ while (loc != std::string::npos)
+ {
+ newDir.replace(loc, 1, "\\");
+ loc = newDir.find("/", loc);
+ }
+
+ if (!CreateDirectory(newDir.c_str(), 0) &&
+ GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ logger->log("Error: %s can't be made, but doesn't exist!",
+ newDir.c_str());
+ errorMessage = _("Error creating updates directory!");
+ mState = STATE_ERROR;
+ }
+#else
+ logger->log("Error: %s/%s can't be made, but doesn't exist!",
+ mLocalDataDir.c_str(), mUpdatesDir.c_str());
+ errorMessage = _("Error creating updates directory!");
+ mState = STATE_ERROR;
+#endif
+ }
+ }
+ std::string updateLocal = "/" + mUpdatesDir + "/local";
+ std::string updateFix = "/" + mUpdatesDir + "/fix";
+ if (!resman->isDirectory(updateLocal))
+ resman->mkdir(updateLocal);
+ if (!resman->isDirectory(updateFix))
+ resman->mkdir(updateFix);
+}
+
+void Client::initScreenshotDir()
+{
+ if (!mOptions.screenshotDir.empty())
+ {
+ mScreenshotDir = mOptions.screenshotDir;
+ if (mkdir_r(mScreenshotDir.c_str()))
+ {
+ logger->log(strprintf(
+ _("Error: %s doesn't exist and can't be created! "
+ "Exiting."), mScreenshotDir.c_str()));
+ }
+ }
+ else if (mScreenshotDir.empty())
+ {
+ std::string configScreenshotDir =
+ config.getStringValue("screenshotDirectory");
+ if (!configScreenshotDir.empty())
+ {
+ mScreenshotDir = configScreenshotDir;
+ }
+ else
+ {
+#ifdef WIN32
+ mScreenshotDir = getSpecialFolderLocation(CSIDL_MYPICTURES);
+ if (mScreenshotDir.empty())
+ mScreenshotDir = getSpecialFolderLocation(CSIDL_DESKTOP);
+#else
+ mScreenshotDir = std::string(PHYSFS_getUserDir()) + "Desktop";
+#endif
+ }
+ //config.setValue("screenshotDirectory", mScreenshotDir);
+ logger->log("screenshotDirectory: " + mScreenshotDir);
+
+ if (config.getBoolValue("useScreenshotDirectorySuffix"))
+ {
+ std::string configScreenshotSuffix =
+ branding.getValue("appShort", "Mana");
+
+ if (!configScreenshotSuffix.empty())
+ {
+ mScreenshotDir += "/" + configScreenshotSuffix;
+// config.setValue("screenshotDirectorySuffix",
+// configScreenshotSuffix);
+ }
+ }
+ }
+}
+
+void Client::accountLogin(LoginData *loginData)
+{
+ logger->log("Username is %s", loginData->username.c_str());
+
+ // Send login infos
+ if (loginData->registerLogin)
+ Net::getLoginHandler()->registerAccount(loginData);
+ else
+ Net::getLoginHandler()->loginAccount(loginData);
+
+ // Clear the password, avoids auto login when returning to login
+ loginData->password = "";
+
+ // TODO This is not the best place to save the config, but at least better
+ // than the login gui window
+ if (loginData->remember)
+ serverConfig.setValue("username", loginData->username);
+ serverConfig.setValue("remember", loginData->remember);
+}
+
+bool Client::copyFile(std::string &configPath, std::string &oldConfigPath)
+{
+ FILE *configFile = 0;
+
+ configFile = fopen(oldConfigPath.c_str(), "r");
+
+ if (configFile != NULL)
+ {
+ fclose(configFile);
+
+ std::ifstream ifs(oldConfigPath.c_str(), std::ios::binary);
+ std::ofstream ofs(configPath.c_str(), std::ios::binary);
+ ofs << ifs.rdbuf();
+ ifs.close();
+ ofs.close();
+ return true;
+ }
+ return false;
+}
+
+bool Client::createConfig(std::string &configPath)
+{
+ std::string oldHomeDir;
+#ifdef __APPLE__
+ // Use Application Directory instead of .mana
+ oldHomeDir = std::string(PHYSFS_getUserDir()) +
+ "/Library/Application Support/" +
+ branding.getValue("appName", "Mana");
+#else
+ oldHomeDir = std::string(PHYSFS_getUserDir()) +
+ "/." + branding.getValue("appShort", "mana");
+#endif
+
+ oldHomeDir += "/config.xml";
+
+ logger->log("Restore config from: " + configPath);
+ return copyFile(configPath, oldHomeDir);
+}
+
+void Client::storeSafeParameters()
+{
+ bool tmpHwaccel;
+ int tmpOpengl;
+ int tmpFpslimit;
+ int tmpAltFpslimit;
+ bool tmpSound;
+ int width;
+ int height;
+ std::string font;
+ std::string boldFont;
+ std::string particleFont;
+ std::string helpFont;
+ bool showBackground;
+ bool enableMumble;
+
+ isSafeMode = config.getBoolValue("safemode");
+ if (isSafeMode)
+ logger->log1("Run in safe mode");
+
+ tmpHwaccel = config.getBoolValue("hwaccel");
+
+#if defined USE_OPENGL
+ tmpOpengl = config.getIntValue("opengl");
+#else
+ tmpOpengl = 0;
+#endif
+ tmpFpslimit = config.getIntValue("fpslimit");
+ tmpAltFpslimit = config.getIntValue("altfpslimit");
+ tmpSound = config.getBoolValue("sound");
+
+ width = config.getIntValue("screenwidth");
+ height = config.getIntValue("screenheight");
+
+ font = config.getStringValue("font");
+ boldFont = config.getStringValue("boldFont");
+ particleFont = config.getStringValue("particleFont");
+ helpFont = config.getStringValue("helpFont");
+
+ showBackground = config.getBoolValue("showBackground");
+ enableMumble = config.getBoolValue("enableMumble");
+
+ config.setValue("hwaccel", false);
+ config.setValue("opengl", 0);
+ config.setValue("fpslimit", 0);
+ config.setValue("altfpslimit", 0);
+ config.setValue("sound", false);
+ config.setValue("safemode", true);
+ config.setValue("screenwidth", 640);
+ config.setValue("screenheight", 480);
+ config.setValue("font", "fonts/dejavusans.ttf");
+ config.setValue("boldFont", "fonts/dejavusans-bold.ttf");
+ config.setValue("particleFont", "fonts/dejavusans.ttf");
+ config.setValue("helpFont", "fonts/dejavusansmono.ttf");
+ config.setValue("showBackground", false);
+ config.setValue("enableMumble", false);
+
+ config.write();
+
+ if (mOptions.safeMode)
+ {
+ isSafeMode = true;
+ return;
+ }
+
+ config.setValue("hwaccel", tmpHwaccel);
+ config.setValue("opengl", tmpOpengl);
+ config.setValue("fpslimit", tmpFpslimit);
+ config.setValue("altfpslimit", tmpAltFpslimit);
+ config.setValue("sound", tmpSound);
+ config.setValue("safemode", false);
+ config.setValue("screenwidth", width);
+ config.setValue("screenheight", height);
+ config.setValue("font", font);
+ config.setValue("boldFont", boldFont);
+ config.setValue("particleFont", particleFont);
+ config.setValue("helpFont", helpFont);
+ config.setValue("showBackground", showBackground);
+ config.setValue("enableMumble", enableMumble);
+}
+
+void Client::initTradeFilter()
+{
+ std::string tradeListName =
+ Client::getServerConfigDirectory() + "/tradefilter.txt";
+
+ std::ofstream tradeFile;
+ struct stat statbuf;
+
+ if (stat(tradeListName.c_str(), &statbuf) || !S_ISREG(statbuf.st_mode))
+ {
+ tradeFile.open(tradeListName.c_str(), std::ios::out);
+ tradeFile << ": sell" << std::endl;
+ tradeFile << ": buy" << std::endl;
+ tradeFile << ": trade" << std::endl;
+ tradeFile << "i sell" << std::endl;
+ tradeFile << "i buy" << std::endl;
+ tradeFile << "i trade" << std::endl;
+ tradeFile << "i trading" << std::endl;
+ tradeFile << "i am buy" << std::endl;
+ tradeFile << "i am sell" << std::endl;
+ tradeFile << "i am trade" << std::endl;
+ tradeFile << "i am trading" << std::endl;
+ tradeFile << "i'm buy" << std::endl;
+ tradeFile << "i'm sell" << std::endl;
+ tradeFile << "i'm trade" << std::endl;
+ tradeFile << "i'm trading" << std::endl;
+ tradeFile.close();
+ }
+}
+
+void Client::initPacketLimiter()
+{
+ //here i setting packet limits. but current server is broken,
+ // and this limits may not help.
+
+ mPacketLimits[PACKET_CHAT].timeLimit = 10 + 5;
+ mPacketLimits[PACKET_CHAT].lastTime = 0;
+ mPacketLimits[PACKET_CHAT].cntLimit = 1;
+ mPacketLimits[PACKET_CHAT].cnt = 0;
+
+ //10
+ mPacketLimits[PACKET_PICKUP].timeLimit = 10 + 5;
+ mPacketLimits[PACKET_PICKUP].lastTime = 0;
+ mPacketLimits[PACKET_PICKUP].cntLimit = 1;
+ mPacketLimits[PACKET_PICKUP].cnt = 0;
+
+ //10 5
+ mPacketLimits[PACKET_DROP].timeLimit = 5;
+ mPacketLimits[PACKET_DROP].lastTime = 0;
+ mPacketLimits[PACKET_DROP].cntLimit = 1;
+ mPacketLimits[PACKET_DROP].cnt = 0;
+
+ //100
+ mPacketLimits[PACKET_NPC_NEXT].timeLimit = 0;
+ mPacketLimits[PACKET_NPC_NEXT].lastTime = 0;
+ mPacketLimits[PACKET_NPC_NEXT].cntLimit = 1;
+ mPacketLimits[PACKET_NPC_NEXT].cnt = 0;
+
+ mPacketLimits[PACKET_NPC_INPUT].timeLimit = 100;
+ mPacketLimits[PACKET_NPC_INPUT].lastTime = 0;
+ mPacketLimits[PACKET_NPC_INPUT].cntLimit = 1;
+ mPacketLimits[PACKET_NPC_INPUT].cnt = 0;
+
+ //50
+ mPacketLimits[PACKET_NPC_TALK].timeLimit = 60;
+ mPacketLimits[PACKET_NPC_TALK].lastTime = 0;
+ mPacketLimits[PACKET_NPC_TALK].cntLimit = 1;
+ mPacketLimits[PACKET_NPC_TALK].cnt = 0;
+
+ //10
+ mPacketLimits[PACKET_EMOTE].timeLimit = 10 + 5;
+ mPacketLimits[PACKET_EMOTE].lastTime = 0;
+ mPacketLimits[PACKET_EMOTE].cntLimit = 1;
+ mPacketLimits[PACKET_EMOTE].cnt = 0;
+
+ //100
+ mPacketLimits[PACKET_SIT].timeLimit = 100;
+ mPacketLimits[PACKET_SIT].lastTime = 0;
+ mPacketLimits[PACKET_SIT].cntLimit = 1;
+ mPacketLimits[PACKET_SIT].cnt = 0;
+
+ mPacketLimits[PACKET_DIRECTION].timeLimit = 50;
+ mPacketLimits[PACKET_DIRECTION].lastTime = 0;
+ mPacketLimits[PACKET_DIRECTION].cntLimit = 1;
+ mPacketLimits[PACKET_DIRECTION].cnt = 0;
+
+ //2+
+ mPacketLimits[PACKET_ATTACK].timeLimit = 2 + 10;
+ mPacketLimits[PACKET_ATTACK].lastTime = 0;
+ mPacketLimits[PACKET_ATTACK].cntLimit = 1;
+ mPacketLimits[PACKET_ATTACK].cnt = 0;
+
+
+ if (!mServerConfigDir.empty())
+ {
+ std::string packetLimitsName =
+ Client::getServerConfigDirectory() + "/packetlimiter.txt";
+
+ std::ifstream inPacketFile;
+ struct stat statbuf;
+
+ if (stat(packetLimitsName.c_str(), &statbuf)
+ || !S_ISREG(statbuf.st_mode))
+ {
+ // wtiting new file
+ writePacketLimits(packetLimitsName);
+ }
+ else
+ { // reading existent file
+ inPacketFile.open(packetLimitsName.c_str(), std::ios::in);
+ char line[101];
+
+ if (!inPacketFile.getline(line, 100))
+ return;
+
+ int ver = atoi(line);
+
+ for (int f = 0; f < PACKET_SIZE; f ++)
+ {
+ if (!inPacketFile.getline(line, 100))
+ break;
+
+ if (!(ver == 1 && (f == PACKET_DROP || f == PACKET_NPC_NEXT)))
+ mPacketLimits[f].timeLimit = atoi(line);
+ }
+ inPacketFile.close();
+ if (ver == 1)
+ writePacketLimits(packetLimitsName);
+ }
+ }
+}
+
+void Client::writePacketLimits(std::string packetLimitsName)
+{
+ std::ofstream outPacketFile;
+ outPacketFile.open(packetLimitsName.c_str(), std::ios::out);
+ outPacketFile << "2" << std::endl;
+ for (int f = 0; f < PACKET_SIZE; f ++)
+ {
+ outPacketFile << toString(mPacketLimits[f].timeLimit)
+ << std::endl;
+ }
+
+ outPacketFile.close();
+}
+
+bool Client::checkPackets(int type)
+{
+ if (type > PACKET_SIZE)
+ return false;
+
+ if (!serverConfig.getValueBool("enableBuggyServers", true))
+ return true;
+
+ int timeLimit = instance()->mPacketLimits[type].timeLimit;
+
+ if (!timeLimit)
+ return true;
+
+ int time = tick_time;
+ int lastTime = instance()->mPacketLimits[type].lastTime;
+ int cnt = instance()->mPacketLimits[type].cnt;
+ int cntLimit = instance()->mPacketLimits[type].cntLimit;
+
+ if (lastTime > tick_time)
+ {
+// instance()->mPacketLimits[type].lastTime = time;
+// instance()->mPacketLimits[type].cnt = 0;
+
+ return true;
+ }
+ else if (lastTime + timeLimit > time)
+ {
+ if (cnt >= cntLimit)
+ {
+ return false;
+ }
+ else
+ {
+// instance()->mPacketLimits[type].cnt ++;
+ return true;
+ }
+ }
+// instance()->mPacketLimits[type].lastTime = time;
+// instance()->mPacketLimits[type].cnt = 1;
+ return true;
+}
+
+bool Client::limitPackets(int type)
+{
+ if (type > PACKET_SIZE)
+ return false;
+
+ if (!serverConfig.getValueBool("enableBuggyServers", true))
+ return true;
+
+ int timeLimit = instance()->mPacketLimits[type].timeLimit;
+
+ if (!timeLimit)
+ return true;
+
+ int time = tick_time;
+ int lastTime = instance()->mPacketLimits[type].lastTime;
+ int cnt = instance()->mPacketLimits[type].cnt;
+ int cntLimit = instance()->mPacketLimits[type].cntLimit;
+
+ if (lastTime > tick_time)
+ {
+ instance()->mPacketLimits[type].lastTime = time;
+ instance()->mPacketLimits[type].cnt = 0;
+
+ return true;
+ }
+ else if (lastTime + timeLimit > time)
+ {
+ if (cnt >= cntLimit)
+ {
+ return false;
+ }
+ else
+ {
+ instance()->mPacketLimits[type].cnt ++;
+ return true;
+ }
+ }
+ instance()->mPacketLimits[type].lastTime = time;
+ instance()->mPacketLimits[type].cnt = 1;
+ return true;
+}
+
+const std::string Client::getServerConfigDirectory()
+{
+ return instance()->mServerConfigDir;
+}
+
+void Client::setGuiAlpha(float n)
+{
+ instance()->mGuiAlpha = n;
+}
+
+float Client::getGuiAlpha()
+{
+ return instance()->mGuiAlpha;
+}
+
+void Client::setFramerate(int fpsLimit)
+{
+ if (!fpsLimit || !instance()->mLimitFps)
+ return;
+
+ SDL_setFramerate(&instance()->mFpsManager, fpsLimit);
+}
diff --git a/src/client.h b/src/client.h
new file mode 100644
index 000000000..c853411d3
--- /dev/null
+++ b/src/client.h
@@ -0,0 +1,317 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#include "configlistener.h"
+
+#include "net/serverinfo.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <SDL.h>
+#include <SDL_framerate.h>
+
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Button;
+class Desktop;
+class LoginData;
+class Window;
+class QuitDialog;
+
+/**
+ * Set the milliseconds value of a tick time.
+ */
+static const int MILLISECONDS_IN_A_TICK = 10;
+
+//manaserv uses 9601
+//static const short DEFAULT_PORT = 9601;
+static const short DEFAULT_PORT = 6901;
+
+extern volatile int fps;
+extern volatile int tick_time;
+extern volatile int cur_time;
+extern bool isSafeMode;
+
+class ErrorListener : public gcn::ActionListener
+{
+ public:
+ void action(const gcn::ActionEvent &event);
+};
+
+extern std::string errorMessage;
+extern ErrorListener errorListener;
+extern LoginData loginData;
+
+/**
+ * Returns elapsed time. (Warning: supposes the delay is always < 100 seconds)
+ */
+int get_elapsed_time(int start_time);
+
+/**
+ * All client states.
+ */
+enum State
+{
+ STATE_ERROR = -1,
+ STATE_START = 0,
+ STATE_CHOOSE_SERVER,
+ STATE_CONNECT_SERVER,
+ STATE_LOGIN,
+ STATE_LOGIN_ATTEMPT,
+ STATE_WORLD_SELECT, // 5
+ STATE_WORLD_SELECT_ATTEMPT,
+ STATE_UPDATE,
+ STATE_LOAD_DATA,
+ STATE_GET_CHARACTERS,
+ STATE_CHAR_SELECT, // 10
+ STATE_CONNECT_GAME,
+ STATE_GAME,
+ STATE_CHANGE_MAP, // Switch map-server/gameserver
+ STATE_LOGIN_ERROR,
+ STATE_ACCOUNTCHANGE_ERROR, // 15
+ STATE_REGISTER_PREP,
+ STATE_REGISTER,
+ STATE_REGISTER_ATTEMPT,
+ STATE_CHANGEPASSWORD,
+ STATE_CHANGEPASSWORD_ATTEMPT, // 20
+ STATE_CHANGEPASSWORD_SUCCESS,
+ STATE_CHANGEEMAIL,
+ STATE_CHANGEEMAIL_ATTEMPT,
+ STATE_CHANGEEMAIL_SUCCESS,
+ STATE_UNREGISTER, // 25
+ STATE_UNREGISTER_ATTEMPT,
+ STATE_UNREGISTER_SUCCESS,
+ STATE_SWITCH_SERVER,
+ STATE_SWITCH_LOGIN,
+ STATE_SWITCH_CHARACTER, // 30
+ STATE_LOGOUT_ATTEMPT,
+ STATE_WAIT,
+ STATE_EXIT,
+ STATE_FORCE_QUIT,
+ STATE_AUTORECONNECT_SERVER = 1000
+};
+
+enum PacketTypes
+{
+ PACKET_CHAT = 0,
+ PACKET_PICKUP = 1,
+ PACKET_DROP = 2,
+ PACKET_NPC_NEXT = 3,
+ PACKET_NPC_TALK = 4,
+ PACKET_NPC_INPUT = 5,
+ PACKET_EMOTE = 6,
+ PACKET_SIT = 7,
+ PACKET_DIRECTION = 8,
+ PACKET_ATTACK = 9,
+ PACKET_SIZE
+};
+
+struct PacketLimit
+{
+ int lastTime;
+ int timeLimit;
+ int cnt;
+ int cntLimit;
+};
+
+/**
+ * The core part of the client. This class initializes all subsystems, runs
+ * the event loop, and shuts everything down again.
+ */
+class Client : public ConfigListener, public gcn::ActionListener
+{
+public:
+ /**
+ * A structure holding the values of various options that can be passed
+ * from the command line.
+ */
+ struct Options
+ {
+ Options():
+ printHelp(false),
+ printVersion(false),
+ skipUpdate(false),
+ chooseDefault(false),
+ noOpenGL(false),
+ safeMode(false),
+ serverPort(0)
+ {}
+
+ bool printHelp;
+ bool printVersion;
+ bool skipUpdate;
+ bool chooseDefault;
+ bool noOpenGL;
+ std::string username;
+ std::string password;
+ std::string character;
+ std::string brandingPath;
+ std::string updateHost;
+ std::string dataPath;
+ std::string homeDir;
+ std::string logFileName;
+ std::string chatLogDir;
+ std::string configDir;
+ std::string localDataDir;
+ std::string screenshotDir;
+ bool safeMode;
+
+ std::string serverName;
+ short serverPort;
+ };
+
+ Client(const Options &options);
+ ~Client();
+
+ /**
+ * Provides access to the client instance.
+ */
+ static Client *instance()
+ { return mInstance; }
+
+ int exec();
+
+ static void setState(State state)
+ { instance()->mState = state; }
+
+ static State getState()
+ { return instance()->mState; }
+
+ static const std::string &getPackageDirectory()
+ { return instance()->mPackageDir; }
+
+ static const std::string &getConfigDirectory()
+ { return instance()->mConfigDir; }
+
+ static const std::string &getLocalDataDirectory()
+ { return instance()->mLocalDataDir; }
+
+ static const std::string &getScreenshotDirectory()
+ { return instance()->mScreenshotDir; }
+
+ static const std::string getServerConfigDirectory();
+
+ static bool getIsMinimized()
+ { return instance()->mIsMinimized; }
+
+ static void setIsMinimized(bool n)
+ { instance()->mIsMinimized = n; }
+
+ static bool getInputFocused()
+ { return instance()->mInputFocused; }
+
+ static void setInputFocused(bool n)
+ { instance()->mInputFocused = n; }
+
+ static bool getMouseFocused()
+ { return instance()->mMouseFocused; }
+
+ static void setMouseFocused(bool n)
+ { instance()->mMouseFocused = n; }
+
+ static std::string getUpdatesDir()
+ { return instance()->mUpdatesDir; }
+
+ static std::string getServerName()
+ { return instance()->mServerName; }
+
+ static void setGuiAlpha(float n);
+
+ static float getGuiAlpha();
+
+ static void setFramerate(int fpsLimit);
+ void optionChanged(const std::string &name);
+ void action(const gcn::ActionEvent &event);
+ void initTradeFilter();
+
+ void initPacketLimiter();
+
+ void writePacketLimits(std::string packetLimitsName);
+
+ static bool limitPackets(int type);
+
+ static bool checkPackets(int type);
+
+ PacketLimit mPacketLimits[PACKET_SIZE + 1];
+
+private:
+ void initRootDir();
+ void initHomeDir();
+ void initConfiguration();
+ void initUpdatesDir();
+ void initScreenshotDir();
+ void initServerConfig(std::string serverName);
+
+ bool copyFile(std::string &configPath, std::string &oldConfigPath);
+ bool createConfig(std::string &configPath);
+
+ void accountLogin(LoginData *loginData);
+
+ void storeSafeParameters();
+
+ static Client *mInstance;
+
+ Options mOptions;
+
+ std::string mPackageDir;
+ std::string mConfigDir;
+ std::string mLocalDataDir;
+ std::string mUpdateHost;
+ std::string mUpdatesDir;
+ std::string mScreenshotDir;
+ std::string mServerConfigDir;
+ std::string mRootDir;
+ std::string mServerName;
+
+ ServerInfo mCurrentServer;
+
+ Window *mCurrentDialog;
+ QuitDialog *mQuitDialog;
+ Desktop *mDesktop;
+ Button *mSetupButton;
+
+ State mState;
+ State mOldState;
+
+ SDL_Surface *mIcon;
+
+ SDL_TimerID mLogicCounterId;
+ SDL_TimerID mSecondsCounterId;
+
+ bool mLimitFps;
+ bool mConfigAutoSaved;
+ bool mIsMinimized;
+ bool mInputFocused;
+ bool mMouseFocused;
+ float mGuiAlpha;
+ FPSmanager mFpsManager;
+};
+
+#endif // CLIENT_H
diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp
new file mode 100644
index 000000000..727374f6b
--- /dev/null
+++ b/src/commandhandler.cpp
@@ -0,0 +1,1124 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "commandhandler.h"
+
+#include "actorspritemanager.h"
+#include "channelmanager.h"
+#include "channel.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "main.h"
+
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/outfitwindow.h"
+#include "gui/shopwindow.h"
+#include "gui/trade.h"
+#include "gui/truetypefont.h"
+
+#include "gui/widgets/channeltab.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/whispertab.h"
+
+#include "net/adminhandler.h"
+#include "net/beinghandler.h"
+#include "net/chathandler.h"
+#include "net/gamehandler.h"
+#include "net/guildhandler.h"
+#include "net/net.h"
+#include "net/partyhandler.h"
+#include "net/tradehandler.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern std::string tradePartnerName;
+
+CommandHandler::CommandHandler()
+{
+}
+
+void CommandHandler::handleCommands(const std::string &command, ChatTab *tab)
+{
+ // here need add splitting commands
+ handleCommand(command, tab);
+}
+
+void CommandHandler::handleCommand(const std::string &command, ChatTab *tab)
+{
+ std::string::size_type pos = command.find(' ');
+ std::string type(command, 0, pos);
+ std::string args(command, pos == std::string::npos
+ ? command.size() : pos + 1);
+
+ if (command == "closeall")
+ {
+ handleCloseAll(args, tab);
+ }
+ else if (type == "ignoreall")
+ {
+ handleIgnoreAll(args, tab);
+ }
+ else if (type == "help") // Do help before tabs so they can't override it
+ {
+ handleHelp(args, tab);
+ }
+ else if (type == "announce")
+ {
+ handleAnnounce(args, tab);
+ }
+ else if (type == "where")
+ {
+ handleWhere(args, tab);
+ }
+ else if (type == "who")
+ {
+ handleWho(args, tab);
+ }
+ else if (type == "msg" || type == "whisper" || type == "w")
+ {
+ handleMsg(args, tab);
+ }
+ else if (type == "query" || type == "q")
+ {
+ handleQuery(args, tab);
+ }
+ else if (type == "ignore")
+ {
+ handleIgnore(args, tab);
+ }
+ else if (type == "unignore")
+ {
+ handleUnignore(args, tab);
+ }
+ else if (type == "friend" || type == "befriend")
+ {
+ handleFriend(args, tab);
+ }
+ else if (type == "disregard")
+ {
+ handleDisregard(args, tab);
+ }
+ else if (type == "neutral")
+ {
+ handleNeutral(args, tab);
+ }
+ else if (type == "erase")
+ {
+ handleErase(args, tab);
+ }
+ else if (type == "join")
+ {
+ handleJoin(args, tab);
+ }
+ else if (type == "list")
+ {
+ handleListChannels(args, tab);
+ }
+ else if (type == "clear")
+ {
+ handleClear(args, tab);
+ }
+ else if (type == "createparty")
+ {
+ handleCreateParty(args, tab);
+ }
+ else if (type == "createguild")
+ {
+ handleCreateGuild(args, tab);
+ }
+ else if (type == "party")
+ {
+ handleParty(args, tab);
+ }
+ else if (type == "me")
+ {
+ handleMe(args, tab);
+ }
+ else if (type == "toggle")
+ {
+ handleToggle(args, tab);
+ }
+ else if (type == "present")
+ {
+ handlePresent(args, tab);
+ }
+ else if (type == "quit")
+ {
+ handleQuit(args, tab);
+ }
+ else if (type == "all")
+ {
+ handleShowAll(args, tab);
+ }
+ else if (type == "move")
+ {
+ handleMove(args, tab);
+ }
+ else if (type == "target")
+ {
+ handleTarget(args, tab);
+ }
+ else if (type == "outfit")
+ {
+ handleOutfit(args, tab);
+ }
+ else if (type == "emote")
+ {
+ handleEmote(args, tab);
+ }
+ else if (type == "away")
+ {
+ handleAway(args, tab);
+ }
+ else if (type == "follow")
+ {
+ handleFollow(args, tab);
+ }
+ else if (type == "heal")
+ {
+ handleHeal(args, tab);
+ }
+ else if (type == "navigate")
+ {
+ handleNavigate(args, tab);
+ }
+ else if (type == "imitation")
+ {
+ handleImitation(args, tab);
+ }
+ else if (type == "mail")
+ {
+ handleMail(args, tab);
+ }
+ else if (type == "trade")
+ {
+ handleTrade(args, tab);
+ }
+ else if (type == "priceload")
+ {
+ handlePriceLoad(args, tab);
+ }
+ else if (type == "pricesave")
+ {
+ handlePriceSave(args, tab);
+ }
+ else if (type == "cacheinfo")
+ {
+ handleCacheInfo(args, tab);
+ }
+ else if (type == "disconnect")
+ {
+ handleDisconnect(args, tab);
+ }
+ else if (type == "undress")
+ {
+ handleUndress(args, tab);
+ }
+ else if (type == "attack")
+ {
+ handleAttack(args, tab);
+ }
+ else if (type == "dirs")
+ {
+ handleDirs(args, tab);
+ }
+ else if (type == "info")
+ {
+ handleInfo(args, tab);
+ }
+ else if (type == "wait")
+ {
+ handleWait(args, tab);
+ }
+ else if (tab->handleCommand(type, args))
+ {
+ // Nothing to do
+ }
+ else if (type == "hack")
+ {
+ handleHack(args, tab);
+ }
+ else
+ {
+ tab->chatLog(_("Unknown command."));
+ }
+}
+
+char CommandHandler::parseBoolean(const std::string &value)
+{
+ std::string opt = value.substr(0, 1);
+
+ if (opt == "1" ||
+ opt == "y" || opt == "Y" ||
+ opt == "t" || opt == "T")
+ return 1;
+ else if (opt == "0" ||
+ opt == "n" || opt == "N" ||
+ opt == "f" || opt == "F")
+ return 0;
+ else
+ return -1;
+}
+
+void CommandHandler::handleAnnounce(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ Net::getAdminHandler()->announce(args);
+}
+
+void CommandHandler::handleHelp(const std::string &args, ChatTab *tab)
+{
+ if (args == "")
+ {
+ tab->chatLog(_("-- Help --"));
+ tab->chatLog(_("/help > Display this help"));
+
+ tab->chatLog(_("/where > Display map name"));
+ tab->chatLog(_("/who > Display number of online users"));
+ tab->chatLog(_("/me > Tell something about yourself"));
+
+ tab->chatLog(_("/clear > Clears this window"));
+
+ tab->chatLog(_("/msg > Send a private message to a user"));
+ tab->chatLog(_("/whisper > Alias of msg"));
+ tab->chatLog(_("/w > Alias of msg"));
+ tab->chatLog(_("/query > Makes a tab for private messages "
+ "with another user"));
+ tab->chatLog(_("/q > Alias of query"));
+
+ tab->chatLog(_("/away > Tell the other whispering players "
+ "you're away from keyboard."));
+
+ tab->chatLog(_("/ignore > ignore a player"));
+ tab->chatLog(_("/unignore > stop ignoring a player"));
+ tab->chatLog(_("/ignoreall > Ignore all opened whisper tabs"));
+ tab->chatLog(_("/erase > Erase a player"));
+ tab->chatLog(_("/befriend > Be friend a player"));
+ tab->chatLog(_("/desregard > Disregard a player"));
+ tab->chatLog(_("/neutral > Neutral a player"));
+
+ tab->chatLog(_("/list > Display all public channels"));
+ tab->chatLog(_("/join > Join or create a channel"));
+
+ tab->chatLog(_("/createparty > Create a new party"));
+ tab->chatLog(_("/createguild > Create a new guild"));
+ tab->chatLog(_("/party > Invite a user to party"));
+
+ tab->chatLog(_("/toggle > Determine whether <return> "
+ "toggles the chat log"));
+ tab->chatLog(_("/present > Get list of players present "
+ "(sent to chat log, if logging)"));
+
+ tab->chatLog(_("/announce > Global announcement (GM only)"));
+
+ tab->chatLog(_("/closeall > Close all opened whisper tabs"));
+
+ tab->chatLog(_("/all > Show all visible beings in debug tab"));
+
+ tab->chatLog(_("/move > Move to given position"));
+ tab->chatLog(_("/navigate > Draw path to given position"));
+ tab->chatLog(_("/target > Set target to being"));
+ tab->chatLog(_("/outfit > Wear outfit by index"));
+ tab->chatLog(_("/emote > Show emote by index"));
+ tab->chatLog(_("/follow > Follow player"));
+ tab->chatLog(_("/imitation > Imitate player"));
+ tab->chatLog(_("/heal > Heal player"));
+ tab->chatLog(_("/mail > Send offline message to player"));
+
+ tab->showHelp(); // Allow the tab to show it's help
+
+ tab->chatLog(_("For more information, type /help <command>."));
+ }
+ else if (args == "help") // Do this before tabs so they can't change it
+ {
+ tab->chatLog(_("Command: /help"));
+ tab->chatLog(_("This command displays a list "
+ "of all commands available."));
+ tab->chatLog(_("Command: /help <command>"));
+ tab->chatLog(_("This command displays help on <command>."));
+ }
+ else if (tab->handleCommand("help", args))
+ {
+ // Nothing to do
+ }
+ else if (args == "announce")
+ {
+ tab->chatLog(_("Command: /announce <msg>"));
+ tab->chatLog(_("*** only available to a GM ***"));
+ tab->chatLog(_("This command sends the message <msg> to "
+ "all players currently online."));
+ }
+ else if (args == "clear")
+ {
+ tab->chatLog(_("Command: /clear"));
+ tab->chatLog(_("This command clears the chat log of previous chat."));
+ }
+ else if (args == "ignore")
+ {
+ tab->chatLog(_("Command: /ignore <player>"));
+ tab->chatLog(_("This command ignores the given player regardless of "
+ "current relations."));
+ }
+ else if (args == "join")
+ {
+ tab->chatLog(_("Command: /join <channel>"));
+ tab->chatLog(_("This command makes you enter <channel>."));
+ tab->chatLog(_("If <channel> doesn't exist, it's created."));
+ }
+ else if (args == "list")
+ {
+ tab->chatLog(_("Command: /list"));
+ tab->chatLog(_("This command shows a list of all channels."));
+ }
+ else if (args == "me")
+ {
+ tab->chatLog(_("Command: /me <message>"));
+ tab->chatLog(_("This command tell others you are (doing) <msg>."));
+ }
+ else if (args == "msg" || args == "whisper" || args == "w")
+ {
+ tab->chatLog(_("Command: /msg <nick> <message>"));
+ tab->chatLog(_("Command: /whisper <nick> <message>"));
+ tab->chatLog(_("Command: /w <nick> <message>"));
+ tab->chatLog(_("This command sends the text <message> to <nick>."));
+ tab->chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ }
+ else if (args == "query" || args == "q")
+ {
+ tab->chatLog(_("Command: /query <nick>"));
+ tab->chatLog(_("Command: /q <nick>"));
+ tab->chatLog(_("This command tries to make a tab for whispers between"
+ "you and <nick>."));
+ }
+ else if (args == "away")
+ {
+ tab->chatLog(_("Command: /away <afk reason>"));
+ tab->chatLog(_("This command tells "
+ "you're away from keyboard with the given reason."));
+ tab->chatLog(_("Command: /away"));
+ tab->chatLog(_("This command clears the away status and message."));
+ }
+ else if (args == "createparty")
+ {
+ tab->chatLog(_("Command: /createparty <name>"));
+ tab->chatLog(_("This command creates a new party called <name>."));
+ }
+ else if (args == "createguild")
+ {
+ tab->chatLog(_("Command: /createguild <name>"));
+ tab->chatLog(_("This command creates a new guild called <name>."));
+ }
+ else if (args == "party")
+ {
+ tab->chatLog(_("Command: /party <nick>"));
+ tab->chatLog(_("This command invites <nick> to party with you."));
+ tab->chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ }
+ else if (args == "present")
+ {
+ tab->chatLog(_("Command: /present"));
+ tab->chatLog(_("This command gets a list of players within hearing "
+ "and sends it to chat log."));
+ }
+ else if (args == "toggle")
+ {
+ tab->chatLog(_("Command: /toggle <state>"));
+ tab->chatLog(_("This command sets whether the return key should "
+ "toggle the chat log, or whether the chat log turns off "
+ "automatically."));
+ tab->chatLog(_("<state> can be one of \"1\", \"yes\", \"true\" to "
+ "turn the toggle on, or \"0\", \"no\", \"false\" to turn the "
+ "toggle off."));
+ tab->chatLog(_("Command: /toggle"));
+ tab->chatLog(_("This command displays the return toggle status."));
+ }
+ else if (args == "unignore")
+ {
+ tab->chatLog(_("Command: /unignore <player>"));
+ tab->chatLog(_("This command stops ignoring the given player if they "
+ "are being ignored"));
+ }
+ else if (args == "where")
+ {
+ tab->chatLog(_("Command: /where"));
+ tab->chatLog(_("This command displays the name of the current map."));
+ }
+ else if (args == "who")
+ {
+ tab->chatLog(_("Command: /who"));
+ tab->chatLog(_("This command displays the number of players currently "
+ "online."));
+ }
+ else
+ {
+ tab->chatLog(_("Unknown command."));
+ tab->chatLog(_("Type /help for a list of commands."));
+ }
+}
+
+void CommandHandler::handleWhere(const std::string &args _UNUSED_,
+ ChatTab *tab)
+{
+ std::ostringstream where;
+ where << Game::instance()->getCurrentMapName() << ", coordinates: "
+ << ((player_node->getPixelX() - 16) / 32) << ", "
+ << ((player_node->getPixelY() - 32) / 32);
+
+ tab->chatLog(where.str(), BY_SERVER);
+}
+
+void CommandHandler::handleWho(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ Net::getChatHandler()->who();
+}
+
+void CommandHandler::handleMsg(const std::string &args, ChatTab *tab)
+{
+ std::string recvnick = "";
+ std::string msg = "";
+
+ if (args.substr(0, 1) == "\"")
+ {
+ const std::string::size_type pos = args.find('"', 1);
+ if (pos != std::string::npos)
+ {
+ recvnick = args.substr(1, pos - 1);
+ if (pos + 2 < args.length())
+ msg = args.substr(pos + 2, args.length());
+ }
+ }
+ else
+ {
+ const std::string::size_type pos = args.find(" ");
+ if (pos != std::string::npos)
+ {
+ recvnick = args.substr(0, pos);
+ if (pos + 1 < args.length())
+ msg = args.substr(pos + 1, args.length());
+ }
+ else
+ {
+ recvnick = std::string(args);
+ msg = "";
+ }
+ }
+
+ trim(msg);
+
+ if (msg.length() > 0)
+ {
+ std::string playerName = player_node->getName();
+ std::string tempNick = recvnick;
+
+ toLower(playerName);
+ toLower(tempNick);
+
+ if (tempNick.compare(playerName) == 0 || args.empty())
+ return;
+
+ chatWindow->whisper(recvnick, msg, BY_PLAYER);
+ }
+ else
+ tab->chatLog(_("Cannot send empty whispers!"), BY_SERVER);
+}
+
+void CommandHandler::handleQuery(const std::string &args, ChatTab *tab)
+{
+ if (chatWindow && chatWindow->addWhisperTab(args, true))
+ return;
+
+ tab->chatLog(strprintf(_("Cannot create a whisper tab for nick \"%s\"! "
+ "It either already exists, or is you."),
+ args.c_str()), BY_SERVER);
+}
+
+void CommandHandler::handleClear(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (chatWindow)
+ chatWindow->clearTab();
+}
+
+void CommandHandler::handleJoin(const std::string &args, ChatTab *tab)
+{
+ if (!tab)
+ return;
+
+ std::string::size_type pos = args.find(' ');
+ std::string name(args, 0, pos);
+ std::string password(args, pos + 1);
+ tab->chatLog(strprintf(_("Requesting to join channel %s."), name.c_str()));
+ Net::getChatHandler()->enterChannel(name, password);
+}
+
+void CommandHandler::handleListChannels(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ Net::getChatHandler()->channelList();
+}
+
+void CommandHandler::handleCreateParty(const std::string &args, ChatTab *tab)
+{
+ if (!tab)
+ return;
+
+ if (args.empty())
+ tab->chatLog(_("Party name is missing."), BY_SERVER);
+ else
+ Net::getPartyHandler()->create(args);
+}
+
+void CommandHandler::handleCreateGuild(const std::string &args, ChatTab *tab)
+{
+ if (!tab)
+ return;
+
+ if (args.empty())
+ tab->chatLog(_("Guild name is missing."), BY_SERVER);
+ else
+ Net::getGuildHandler()->create(args);
+}
+
+void CommandHandler::handleParty(const std::string &args, ChatTab *tab)
+{
+ if (!tab)
+ return;
+
+ if (args != "")
+ Net::getPartyHandler()->invite(args);
+ else
+ tab->chatLog(_("Please specify a name."), BY_SERVER);
+}
+
+void CommandHandler::handleMe(const std::string &args, ChatTab *tab)
+{
+ if (!tab)
+ {
+ Net::getChatHandler()->me(args);
+ return;
+ }
+
+ const std::string str = strprintf("*%s*", args.c_str());
+ switch (tab->getType())
+ {
+ case ChatTab::TAB_PARTY:
+ {
+ Net::getPartyHandler()->chat(str);
+ break;
+ }
+ case ChatTab::TAB_GUILD:
+ {
+ if (!player_node)
+ return;
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ Net::getGuildHandler()->chat(guild->getId(), str);
+ break;
+ }
+ default:
+ Net::getChatHandler()->me(args);
+ break;
+ }
+}
+
+void CommandHandler::handleToggle(const std::string &args, ChatTab *tab)
+{
+ if (args.empty())
+ {
+ if (chatWindow && tab)
+ {
+ tab->chatLog(chatWindow->getReturnTogglesChat() ?
+ _("Return toggles chat.") : _("Message closes chat."));
+ }
+ return;
+ }
+
+ char opt = parseBoolean(args);
+
+ switch (opt)
+ {
+ case 1:
+ if (tab)
+ tab->chatLog(_("Return now toggles chat."));
+ if (chatWindow)
+ chatWindow->setReturnTogglesChat(true);
+ return;
+ case 0:
+ if (tab)
+ tab->chatLog(_("Message now closes chat."));
+ if (chatWindow)
+ chatWindow->setReturnTogglesChat(false);
+ return;
+ case -1:
+ if (tab)
+ tab->chatLog(strprintf(BOOLEAN_OPTIONS, "toggle"));
+ return;
+ default:
+ return;
+ }
+}
+
+void CommandHandler::handlePresent(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (chatWindow)
+ chatWindow->doPresent();
+}
+
+void CommandHandler::handleIgnore(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ changeRelation(args, PlayerRelation::IGNORED, "ignored", tab);
+}
+
+void CommandHandler::handleFriend(const std::string &args, ChatTab *tab)
+{
+ changeRelation(args, PlayerRelation::FRIEND, _("friend"), tab);
+}
+
+void CommandHandler::handleDisregard(const std::string &args, ChatTab *tab)
+{
+ changeRelation(args, PlayerRelation::DISREGARDED, _("disregarded"), tab);
+}
+
+void CommandHandler::handleNeutral(const std::string &args, ChatTab *tab)
+{
+ changeRelation(args, PlayerRelation::NEUTRAL, _("neutral"), tab);
+}
+
+void CommandHandler::changeRelation(const std::string &args,
+ PlayerRelation::Relation relation,
+ const std::string &relationText,
+ ChatTab *tab)
+{
+ if (args.empty())
+ {
+ if (tab)
+ tab->chatLog(_("Please specify a name."), BY_SERVER);
+ return;
+ }
+
+ if (player_relations.getRelation(args) == relation)
+ {
+ if (tab)
+ {
+ tab->chatLog(strprintf(_("Player already %s!"),
+ relationText.c_str()), BY_SERVER);
+ }
+ return;
+ }
+ else
+ {
+ player_relations.setRelation(args, relation);
+ }
+
+ if (player_relations.getRelation(args) == relation)
+ {
+ if (tab)
+ {
+ tab->chatLog(strprintf(_("Player successfully %s!"),
+ relationText.c_str()), BY_SERVER);
+ }
+ }
+ else
+ {
+ if (tab)
+ {
+ tab->chatLog(strprintf(_("Player could not be %s!"),
+ relationText.c_str()), BY_SERVER);
+ }
+ }
+}
+
+void CommandHandler::handleUnignore(const std::string &args, ChatTab *tab)
+{
+ if (args.empty())
+ {
+ if (tab)
+ tab->chatLog(_("Please specify a name."), BY_SERVER);
+ return;
+ }
+
+ if (player_relations.getRelation(args) == PlayerRelation::IGNORED)
+ {
+ player_relations.removePlayer(args);
+ }
+ else
+ {
+ if (tab)
+ tab->chatLog(_("Player wasn't ignored!"), BY_SERVER);
+ return;
+ }
+
+ if (tab)
+ {
+ if (player_relations.getRelation(args) != PlayerRelation::IGNORED)
+ tab->chatLog(_("Player no longer ignored!"), BY_SERVER);
+ else
+ tab->chatLog(_("Player could not be unignored!"), BY_SERVER);
+ }
+}
+
+
+void CommandHandler::handleErase(const std::string &args, ChatTab *tab)
+{
+ if (args.empty())
+ {
+ if (tab)
+ tab->chatLog(_("Please specify a name."), BY_SERVER);
+ return;
+ }
+
+ if (player_relations.getRelation(args) == PlayerRelation::ERASED)
+ {
+ if (tab)
+ tab->chatLog(_("Player already erased!"), BY_SERVER);
+ return;
+ }
+ else
+ {
+ player_relations.setRelation(args, PlayerRelation::ERASED);
+ }
+
+ if (tab)
+ {
+ if (player_relations.getRelation(args) == PlayerRelation::ERASED)
+ tab->chatLog(_("Player successfully erased!"), BY_SERVER);
+ else
+ tab->chatLog(_("Player could not be erased!"), BY_SERVER);
+ }
+}
+
+void CommandHandler::handleQuit(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+// quit();
+}
+
+void CommandHandler::handleShowAll(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (actorSpriteManager)
+ actorSpriteManager->printAllToChat();
+}
+
+void CommandHandler::handleMove(const std::string &args, ChatTab *tab _UNUSED_)
+{
+ int x = 0;
+ int y = 0;
+
+ if (player_node && parse2Int(args, &x, &y))
+ player_node->moveTo(x, y);
+}
+
+void CommandHandler::handleNavigate(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (!player_node)
+ return;
+
+ int x = 0;
+ int y = 0;
+
+ if (parse2Int(args, &x, &y))
+ player_node->navigateTo(x, y);
+ else
+ player_node->naviageClean();
+}
+
+bool CommandHandler::parse2Int(const std::string &args, int *x, int *y)
+{
+ bool isValid = false;
+ const std::string::size_type pos = args.find(" ");
+ if (pos != std::string::npos)
+ {
+ if (pos + 1 < args.length())
+ {
+ *x = atoi(args.substr(0, pos).c_str());
+ *y = atoi(args.substr(pos + 1, args.length()).c_str());
+ isValid = true;
+ }
+ }
+ return isValid;
+}
+
+void CommandHandler::handleTarget(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (!actorSpriteManager || !player_node)
+ return;
+
+ Being* target = actorSpriteManager->findNearestByName(args);
+ if (target)
+ player_node->setTarget(target);
+}
+
+void CommandHandler::handleCloseAll(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (chatWindow)
+ chatWindow->removeAllWhispers();
+}
+
+void CommandHandler::handleIgnoreAll(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (chatWindow)
+ chatWindow->ignoreAllWhispers();
+}
+
+void CommandHandler::handleOutfit(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (outfitWindow)
+ {
+ if (!args.empty())
+ {
+ const std::string op = args.substr(0, 1);
+ if (op == "n")
+ outfitWindow->wearNextOutfit(true);
+ else if (op == "p")
+ outfitWindow->wearPreviousOutfit(true);
+ else
+ outfitWindow->wearOutfit(atoi(args.c_str()) - 1, false, true);
+ }
+ else
+ {
+ outfitWindow->wearOutfit(atoi(args.c_str()) - 1, false, true);
+ }
+ }
+}
+
+void CommandHandler::handleEmote(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (player_node)
+ player_node->emote(static_cast<Uint8>(atoi(args.c_str())));
+}
+
+void CommandHandler::handleAway(const std::string &args, ChatTab *tab _UNUSED_)
+{
+ if (player_node)
+ player_node->setAway(args);
+}
+
+void CommandHandler::handleFollow(const std::string &args, ChatTab *tab)
+{
+ if (!player_node)
+ return;
+
+ if (!args.empty())
+ {
+ player_node->setFollow(args);
+ }
+ else if (tab)
+ {
+ if (tab->getType() == ChatTab::TAB_WHISPER)
+ {
+ WhisperTab *wTab = static_cast<WhisperTab*>(tab);
+ if (wTab)
+ player_node->setFollow(wTab->getNick());
+ }
+ }
+}
+
+void CommandHandler::handleImitation(const std::string &args, ChatTab *tab)
+{
+ if (!player_node)
+ return;
+
+ if (!args.empty())
+ {
+ player_node->setImitate(args);
+ }
+ else if (tab && tab->getType() == ChatTab::TAB_WHISPER)
+ {
+ WhisperTab *wTab = static_cast<WhisperTab*>(tab);
+ if (wTab)
+ player_node->setImitate(wTab->getNick());
+ }
+ else
+ {
+ player_node->setImitate("");
+ }
+}
+
+void CommandHandler::handleHeal(const std::string &args, ChatTab *tab _UNUSED_)
+{
+ if (!actorSpriteManager)
+ return;
+
+ if (!args.empty())
+ {
+ Being *being = actorSpriteManager->findBeingByName(
+ args, Being::PLAYER);
+ if (being)
+ actorSpriteManager->heal(player_node, being);
+ }
+ else
+ {
+ actorSpriteManager->heal(player_node, player_node);
+ }
+}
+
+void CommandHandler::handleHack(const std::string &args, ChatTab *tab _UNUSED_)
+{
+ Net::getChatHandler()->sendRaw(args);
+}
+
+void CommandHandler::handleMail(const std::string &args, ChatTab *tab _UNUSED_)
+{
+ Net::getChatHandler()->privateMessage("AuctionBot", "!mail " + args);
+}
+
+void CommandHandler::handlePriceLoad(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (shopWindow)
+ shopWindow->loadList();
+}
+
+void CommandHandler::handlePriceSave(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (shopWindow)
+ shopWindow->saveList();
+}
+
+void CommandHandler::handleDisconnect(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ Net::getGameHandler()->disconnect2();
+}
+
+void CommandHandler::handleUndress(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (!actorSpriteManager)
+ return;
+
+ Being* target = actorSpriteManager->findNearestByName(args);
+ if (target)
+ Net::getBeingHandler()->undress(target);
+}
+
+void CommandHandler::handleAttack(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (!player_node || !actorSpriteManager)
+ return;
+
+ Being* target = actorSpriteManager->findNearestByName(args);
+ if (target)
+ player_node->setTarget(target);
+ player_node->attack2(player_node->getTarget(), true);
+}
+
+void CommandHandler::handleTrade(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (!actorSpriteManager)
+ return;
+
+ Being *being = actorSpriteManager->findBeingByName(args, Being::PLAYER);
+ if (being)
+ {
+ Net::getTradeHandler()->request(being);
+ tradePartnerName = being->getName();
+ if (tradeWindow)
+ tradeWindow->clear();
+ }
+}
+
+void CommandHandler::handleDirs(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (!player_node || !debugChatTab)
+ return;
+
+ debugChatTab->chatLog("config directory: "
+ + Client::getConfigDirectory());
+ debugChatTab->chatLog("logs directory: "
+ + Client::getLocalDataDirectory());
+ debugChatTab->chatLog("screenshots directory: "
+ + Client::getScreenshotDirectory());
+}
+
+void CommandHandler::handleInfo(const std::string &args _UNUSED_,
+ ChatTab *tab)
+{
+ switch (tab->getType())
+ {
+ case ChatTab::TAB_GUILD:
+ {
+ if (!player_node)
+ return;
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ Net::getGuildHandler()->info(guild->getId());
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void CommandHandler::handleWait(const std::string &args,
+ ChatTab *tab _UNUSED_)
+{
+ if (player_node)
+ player_node->waitFor(args);
+}
+
+void CommandHandler::handleCacheInfo(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ if (!chatWindow || !debugChatTab)
+ return;
+
+ TrueTypeFont *font = dynamic_cast<TrueTypeFont *>(chatWindow->getFont());
+ if (!font)
+ return;
+
+ std::list<TextChunk> *cache = font->getCache();
+ if (!cache)
+ return;
+
+ debugChatTab->chatLog("font cache size");
+ std::string str;
+ for (int f = 0; f < 256; f ++)
+ {
+ if (!cache[f].empty())
+ str += strprintf("%d: %u, ", f, (unsigned int)cache[f].size());
+ }
+ debugChatTab->chatLog(str);
+#ifdef DEBUG_FONT_COUNTERS
+ debugChatTab->chatLog("");
+ debugChatTab->chatLog("Created: " + toString(font->getCreateCounter()));
+ debugChatTab->chatLog("Deleted: " + toString(font->getDeleteCounter()));
+#endif
+}
diff --git a/src/commandhandler.h b/src/commandhandler.h
new file mode 100644
index 000000000..5a4d9f220
--- /dev/null
+++ b/src/commandhandler.h
@@ -0,0 +1,281 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef COMMANDHANDLER_H
+#define COMMANDHANDLER_H
+
+#include "playerrelations.h"
+
+#include <string>
+
+class ChatTab;
+
+extern ChatTab *localChatTab;
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+#define BOOLEAN_OPTIONS _("Options to /%s are \"yes\", \"no\", \"true\", "\
+"\"false\", \"1\", \"0\".")
+
+/**
+ * A class to parse and handle user commands
+ */
+class CommandHandler
+{
+ public:
+ /**
+ * Constructor
+ */
+ CommandHandler();
+
+ /**
+ * Destructor
+ */
+ ~CommandHandler() {}
+
+ /**
+ * Parse and handle the given command.
+ */
+ void handleCommand(const std::string &command,
+ ChatTab *tab = localChatTab);
+
+ void handleCommands(const std::string &command,
+ ChatTab *tab = localChatTab);
+
+ static char parseBoolean(const std::string &value);
+
+ protected:
+ friend class ChatTab;
+ friend class WhisperTab;
+
+ /**
+ * Handle an announce command.
+ */
+ void handleAnnounce(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a help command.
+ */
+ void handleHelp(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a where command.
+ */
+ void handleWhere(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a who command.
+ */
+ void handleWho(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a msg command.
+ */
+ void handleMsg(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a msg tab request.
+ */
+ void handleQuery(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a join command.
+ */
+ void handleJoin(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a listchannels command.
+ */
+ void handleListChannels(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a clear command.
+ */
+ void handleClear(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a createparty command.
+ */
+ void handleCreateParty(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a createguild command.
+ */
+ void handleCreateGuild(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a party command.
+ */
+ void handleParty(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a me command.
+ */
+ void handleMe(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a toggle command.
+ */
+ void handleToggle(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle a present command.
+ */
+ void handlePresent(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle an ignore command.
+ */
+ void handleIgnore(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle an unignore command.
+ */
+ void handleUnignore(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle an friend command.
+ */
+ void handleFriend(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle an disregard command.
+ */
+ void handleDisregard(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle an neutral command.
+ */
+ void handleNeutral(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle an erase command.
+ */
+ void handleErase(const std::string &args, ChatTab *tab);
+
+ /**
+ * Change relation.
+ */
+ void changeRelation(const std::string &args,
+ PlayerRelation::Relation relation,
+ const std::string &relationText, ChatTab *tab);
+
+ /**
+ * Handle a quit command.
+ */
+ void handleQuit(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle show all command.
+ */
+ void handleShowAll(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle move command.
+ */
+ void handleMove(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle target command.
+ */
+ void handleTarget(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle closeall command.
+ */
+ void handleCloseAll(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle ignoreall command.
+ */
+ void handleIgnoreAll(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle outfit command.
+ */
+ void handleOutfit(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle emote command.
+ */
+ void handleEmote(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle away command.
+ */
+ void handleAway(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle follow command.
+ */
+ void handleFollow(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle imitation command.
+ */
+ void handleImitation(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle heal command.
+ */
+ void handleHeal(const std::string &args, ChatTab *tab);
+
+ /**
+ * Handle navigate command.
+ */
+ void handleNavigate(const std::string &args, ChatTab *tab);
+
+ void handleMail(const std::string &args, ChatTab *tab _UNUSED_);
+
+ void handleHack(const std::string &args, ChatTab *tab);
+
+ void handlePriceLoad(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_);
+
+ void handlePriceSave(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_);
+
+ void handleTrade(const std::string &args, ChatTab *tab _UNUSED_);
+
+ void handleDisconnect(const std::string &args, ChatTab *tab _UNUSED_);
+
+ void handleUndress(const std::string &args, ChatTab *tab _UNUSED_);
+
+ void handleAttack(const std::string &args, ChatTab *tab _UNUSED_);
+
+ void handleDirs(const std::string &args, ChatTab *tab);
+
+ void handleInfo(const std::string &args, ChatTab *tab);
+
+ void handleWait(const std::string &args, ChatTab *tab);
+
+ void handleCacheInfo(const std::string &args, ChatTab *tab _UNUSED_);
+
+ bool parse2Int(const std::string &args, int *x, int *y);
+};
+
+extern CommandHandler *commandHandler;
+
+#endif // COMMANDHANDLER_H
diff --git a/src/compoundsprite.cpp b/src/compoundsprite.cpp
new file mode 100644
index 000000000..9bbc328ac
--- /dev/null
+++ b/src/compoundsprite.cpp
@@ -0,0 +1,408 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "compoundsprite.h"
+
+#include "game.h"
+#include "graphics.h"
+#ifdef USE_OPENGL
+#include "openglgraphics.h"
+#include "opengl1graphics.h"
+#endif
+#include "map.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+#include <SDL.h>
+
+#define BUFFER_WIDTH 100
+#define BUFFER_HEIGHT 100
+
+CompoundSprite::CompoundSprite():
+ mImage(0),
+ mAlphaImage(0),
+ mOffsetX(0), mOffsetY(0),
+ mNeedsRedraw(false)
+{
+ mAlpha = 1.0f;
+}
+
+CompoundSprite::~CompoundSprite()
+{
+ SpriteIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ delete (*it);
+
+ clear();
+
+ delete mImage;
+ mImage = 0;
+ delete mAlphaImage;
+ mAlphaImage = 0;
+}
+
+bool CompoundSprite::reset()
+{
+ bool ret = false;
+
+ SpriteIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ ret |= (*it)->reset();
+ }
+
+ mNeedsRedraw |= ret;
+ return ret;
+}
+
+bool CompoundSprite::play(std::string action)
+{
+ bool ret = false;
+
+ SpriteIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ ret |= (*it)->play(action);
+ }
+
+ mNeedsRedraw |= ret;
+ return ret;
+}
+
+bool CompoundSprite::update(int time)
+{
+ bool ret = false;
+
+ SpriteIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ ret |= (*it)->update(time);
+ }
+
+ mNeedsRedraw |= ret;
+ return ret;
+}
+
+bool CompoundSprite::draw(Graphics* graphics, int posX, int posY) const
+{
+ if (mNeedsRedraw)
+ redraw();
+
+ if (mAlpha == 1.0f && mImage)
+ {
+ return graphics->drawImage(mImage, posX + mOffsetX, posY + mOffsetY);
+ }
+ else if (mAlpha && mAlphaImage)
+ {
+ mAlphaImage->setAlpha(mAlpha);
+
+ return graphics->drawImage(mAlphaImage,
+ posX + mOffsetX, posY + mOffsetY);
+ }
+ else
+ {
+ drawSprites(graphics, posX, posY);
+ }
+
+ return false;
+}
+
+void CompoundSprite::drawSprites(Graphics* graphics, int posX, int posY) const
+{
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ {
+ (*it)->setAlpha(mAlpha);
+ (*it)->draw(graphics, posX, posY);
+ }
+ }
+}
+
+void CompoundSprite::drawSpritesSDL(Graphics* graphics,
+ int posX, int posY) const
+{
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ (*it)->draw(graphics, posX, posY);
+ }
+}
+
+int CompoundSprite::getWidth() const
+{
+ Sprite *base = NULL;
+
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if ((base = (*it)))
+ break;
+ }
+
+ if (base)
+ return base->getWidth();
+
+ return 0;
+}
+
+int CompoundSprite::getHeight() const
+{
+ Sprite *base = NULL;
+
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if ((base = (*it)))
+ break;
+ }
+
+ if (base)
+ return base->getHeight();
+
+ return 0;
+}
+
+const Image* CompoundSprite::getImage() const
+{
+ return mImage;
+}
+
+bool CompoundSprite::setDirection(SpriteDirection direction)
+{
+ bool ret = false;
+
+ SpriteIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ ret |= (*it)->setDirection(direction);
+ }
+
+ mNeedsRedraw |= ret;
+ return ret;
+}
+
+int CompoundSprite::getNumberOfLayers() const
+{
+ if (mImage || mAlphaImage)
+ return 1;
+ else
+ return size();
+}
+
+unsigned int CompoundSprite::getCurrentFrame() const
+{
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ return (*it)->getCurrentFrame();
+ }
+
+ return 0;
+}
+
+unsigned int CompoundSprite::getFrameCount() const
+{
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ return (*it)->getFrameCount();
+ }
+
+ return 0;
+}
+
+void CompoundSprite::addSprite(Sprite* sprite)
+{
+ push_back(sprite);
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::setSprite(int layer, Sprite* sprite)
+{
+ // Skip if it won't change anything
+ if (at(layer) == sprite)
+ return;
+
+ if (at(layer))
+ delete at(layer);
+ at(layer) = sprite;
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::removeSprite(int layer)
+{
+ // Skip if it won't change anything
+ if (at(layer) == NULL)
+ return;
+
+ delete at(layer);
+ at(layer) = 0;
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::clear()
+{
+ // Skip if it won't change anything
+ if (empty())
+ return;
+
+ std::vector<Sprite*>::clear();
+ mNeedsRedraw = true;
+}
+
+void CompoundSprite::ensureSize(size_t layerCount)
+{
+ // Skip if it won't change anything
+ if (size() >= layerCount)
+ return;
+
+ resize(layerCount, NULL);
+ mNeedsRedraw = true;
+}
+
+/**
+ * Returns the curent frame in the current animation of the given layer.
+ */
+unsigned int CompoundSprite::getCurrentFrame(unsigned int layer)
+{
+ if (layer >= size())
+ return 0;
+
+ Sprite *s = getSprite(layer);
+ if (s)
+ return s->getCurrentFrame();
+
+ return 0;
+}
+
+/**
+ * Returns the frame count in the current animation of the given layer.
+ */
+unsigned int CompoundSprite::getFrameCount(unsigned int layer)
+{
+ if (layer >= size())
+ return 0;
+
+ Sprite *s = getSprite(layer);
+ if (s)
+ return s->getFrameCount();
+
+ return 0;
+}
+
+void CompoundSprite::redraw() const
+{
+#ifdef USE_OPENGL
+ // TODO OpenGL support
+ if (Image::mUseOpenGL)
+ {
+ mNeedsRedraw = false;
+ return;
+ }
+#endif
+
+ if (size() <= 1)
+ return;
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ int rmask = 0xff000000;
+ int gmask = 0x00ff0000;
+ int bmask = 0x0000ff00;
+ int amask = 0x000000ff;
+#else
+ int rmask = 0x000000ff;
+ int gmask = 0x0000ff00;
+ int bmask = 0x00ff0000;
+ int amask = 0xff000000;
+#endif
+
+ SDL_Surface *surface = SDL_CreateRGBSurface(SDL_HWSURFACE,
+ BUFFER_WIDTH, BUFFER_HEIGHT, 32, rmask, gmask, bmask, amask);
+
+ if (!surface)
+ return;
+
+ Graphics *graphics = new Graphics();
+ graphics->setBlitMode(Graphics::BLIT_GFX);
+ graphics->setTarget(surface);
+ graphics->_beginDraw();
+
+ int tileX = 32 / 2;
+ int tileY = 32;
+
+ Game *game = Game::instance();
+ if (game)
+ {
+ Map *map = game->getCurrentMap();
+ if (map)
+ {
+ tileX = map->getTileWidth() / 2;
+ tileY = map->getTileWidth();
+ }
+ }
+
+ int posX = BUFFER_WIDTH / 2 - tileX;
+ int posY = BUFFER_HEIGHT - tileY;
+
+ mOffsetX = tileX - BUFFER_WIDTH / 2;
+ mOffsetY = tileY - BUFFER_HEIGHT;
+
+ drawSpritesSDL(graphics, posX, posY);
+
+/*
+ SpriteConstIterator it, it_end;
+ for (it = begin(), it_end = end(); it != it_end; it++)
+ {
+ if (*it)
+ (*it)->draw(graphics, posX, posY);
+ }
+*/
+
+ delete graphics;
+ graphics = 0;
+
+ SDL_Surface *surfaceA = SDL_CreateRGBSurface(SDL_HWSURFACE,
+ BUFFER_WIDTH, BUFFER_HEIGHT, 32, rmask, gmask, bmask, amask);
+
+ SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
+ SDL_BlitSurface(surface, NULL, surfaceA, NULL);
+
+ delete mImage;
+ delete mAlphaImage;
+
+ mImage = Image::load(surface);
+ SDL_FreeSurface(surface);
+
+ mAlphaImage = Image::load(surfaceA);
+ SDL_FreeSurface(surfaceA);
+
+ mNeedsRedraw = false;
+}
diff --git a/src/compoundsprite.h b/src/compoundsprite.h
new file mode 100644
index 000000000..0e688c907
--- /dev/null
+++ b/src/compoundsprite.h
@@ -0,0 +1,112 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef COMPOUNDSPRITE_H
+#define COMPOUNDSPRITE_H
+
+#include "sprite.h"
+
+#include <vector>
+
+class Image;
+
+class CompoundSprite : public Sprite, private std::vector<Sprite*>
+{
+public:
+ typedef CompoundSprite::iterator SpriteIterator;
+ typedef CompoundSprite::const_iterator SpriteConstIterator;
+
+ CompoundSprite();
+
+ ~CompoundSprite();
+
+ virtual bool reset();
+
+ virtual bool play(std::string action);
+
+ virtual bool update(int time);
+
+ virtual bool draw(Graphics* graphics, int posX, int posY) const;
+
+ /**
+ * Gets the width in pixels of the first sprite in the list.
+ */
+ virtual int getWidth() const;
+
+ /**
+ * Gets the height in pixels of the first sprite in the list.
+ */
+ virtual int getHeight() const;
+
+ virtual const Image* getImage() const;
+
+ virtual bool setDirection(SpriteDirection direction);
+
+ int getNumberOfLayers() const;
+
+ unsigned int getCurrentFrame() const;
+
+ unsigned int getFrameCount() const;
+
+ size_t size() const
+ { return std::vector<Sprite*>::size(); }
+
+ void addSprite(Sprite* sprite);
+
+ void setSprite(int layer, Sprite* sprite);
+
+ Sprite *getSprite(int layer) const
+ { return at(layer); }
+
+ void removeSprite(int layer);
+
+ void clear();
+
+ void ensureSize(size_t layerCount);
+
+ virtual void drawSprites(Graphics* graphics,
+ int posX, int posY) const;
+
+ virtual void drawSpritesSDL(Graphics* graphics,
+ int posX, int posY) const;
+
+ /**
+ * Returns the curent frame in the current animation of the given layer.
+ */
+ virtual unsigned int getCurrentFrame(unsigned int layer);
+
+ /**
+ * Returns the frame count in the current animation of the given layer.
+ */
+ virtual unsigned int getFrameCount(unsigned int layer);
+
+private:
+
+ void redraw() const;
+
+ mutable Image *mImage;
+ mutable Image *mAlphaImage;
+
+ mutable int mOffsetX, mOffsetY;
+
+ mutable bool mNeedsRedraw;
+};
+
+#endif // COMPOUNDSPRITE_H
diff --git a/src/configlistener.h b/src/configlistener.h
new file mode 100644
index 000000000..923b31151
--- /dev/null
+++ b/src/configlistener.h
@@ -0,0 +1,48 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CONFIGLISTENER_H
+#define CONFIGLISTENER_H
+
+#include <string>
+
+/**
+ * The listener interface for receiving notifications about changes to
+ * configuration options.
+ *
+ * \ingroup CORE
+ */
+class ConfigListener
+{
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~ConfigListener() {}
+
+ /**
+ * Called when an option changed. The config listener will have to be
+ * registered to the option name first.
+ */
+ virtual void optionChanged(const std::string &name) = 0;
+};
+
+#endif
diff --git a/src/configuration.cpp b/src/configuration.cpp
new file mode 100644
index 000000000..1e79d1e54
--- /dev/null
+++ b/src/configuration.cpp
@@ -0,0 +1,438 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "configuration.h"
+
+#include "configlistener.h"
+#include "log.h"
+
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <libxml/encoding.h>
+
+#ifdef DEBUG_CONFIG
+#define GETLOG() if (logger) {logger->log("config get: " + key); }
+#else
+#define GETLOG()
+#endif
+
+void ConfigurationObject::setValue(const std::string &key,
+ const std::string &value)
+{
+ mOptions[key] = value;
+}
+
+void ConfigurationObject::deleteKey(const std::string &key)
+{
+ mOptions.erase(key);
+}
+
+void Configuration::setValue(const std::string &key, const std::string &value)
+{
+ ConfigurationObject::setValue(key, value);
+
+ // Notify listeners
+ ListenerMapIterator list = mListenerMap.find(key);
+ if (list != mListenerMap.end())
+ {
+ Listeners listeners = list->second;
+ for (ListenerIterator i = listeners.begin(); i != listeners.end(); i++)
+ (*i)->optionChanged(key);
+ }
+}
+
+std::string ConfigurationObject::getValue(const std::string &key,
+ const std::string &deflt) const
+{
+ GETLOG();
+ Options::const_iterator iter = mOptions.find(key);
+ return ((iter != mOptions.end()) ? iter->second : deflt);
+}
+
+int ConfigurationObject::getValue(const std::string &key, int deflt) const
+{
+ GETLOG();
+ Options::const_iterator iter = mOptions.find(key);
+ return (iter != mOptions.end()) ? atoi(iter->second.c_str()) : deflt;
+}
+
+int ConfigurationObject::getValueInt(const std::string &key, int deflt) const
+{
+ GETLOG();
+ Options::const_iterator iter = mOptions.find(key);
+ return (iter != mOptions.end()) ? atoi(iter->second.c_str()) : deflt;
+}
+
+bool ConfigurationObject::getValueBool(const std::string &key,
+ bool deflt) const
+{
+ GETLOG();
+ Options::const_iterator iter = mOptions.find(key);
+ if (iter != mOptions.end())
+ return atoi(iter->second.c_str()) != 0 ? true : false;
+ else
+ return deflt;
+}
+
+unsigned ConfigurationObject::getValue(const std::string &key,
+ unsigned deflt) const
+{
+ GETLOG();
+ Options::const_iterator iter = mOptions.find(key);
+ return (iter != mOptions.end()) ? static_cast<unsigned>(
+ atol(iter->second.c_str())) : deflt;
+}
+
+double ConfigurationObject::getValue(const std::string &key,
+ double deflt) const
+{
+ GETLOG();
+ Options::const_iterator iter = mOptions.find(key);
+ return (iter != mOptions.end()) ? atof(iter->second.c_str()) : deflt;
+}
+
+void ConfigurationObject::deleteList(const std::string &name)
+{
+ for (ConfigurationList::const_iterator
+ it = mContainerOptions[name].begin();
+ it != mContainerOptions[name].end(); it++)
+ {
+ delete *it;
+ }
+
+ mContainerOptions[name].clear();
+}
+
+void ConfigurationObject::clear()
+{
+ for (std::map<std::string, ConfigurationList>::const_iterator
+ it = mContainerOptions.begin();
+ it != mContainerOptions.end(); it++)
+ {
+ deleteList(it->first);
+ }
+ mOptions.clear();
+}
+
+ConfigurationObject::~ConfigurationObject()
+{
+ clear();
+}
+
+void Configuration::cleanDefaults()
+{
+ if (mDefaultsData)
+ {
+ for (DefaultsData::const_iterator iter = mDefaultsData->begin();
+ iter != mDefaultsData->end(); iter++)
+ {
+ delete(iter->second);
+ }
+ mDefaultsData->clear();
+ delete mDefaultsData;
+ mDefaultsData = 0;
+ }
+}
+
+Configuration::~Configuration()
+{
+ cleanDefaults();
+}
+
+void Configuration::setDefaultValues(DefaultsData *defaultsData)
+{
+ cleanDefaults();
+ mDefaultsData = defaultsData;
+}
+
+int Configuration::getIntValue(const std::string &key) const
+{
+ GETLOG();
+ int defaultValue = 0;
+ Options::const_iterator iter = mOptions.find(key);
+ if (iter == mOptions.end())
+ {
+ if (mDefaultsData)
+ {
+ DefaultsData::const_iterator itdef = mDefaultsData->find(key);
+
+ if (itdef != mDefaultsData->end() && itdef->second
+ && itdef->second->getType() == Mana::VariableData::DATA_INT)
+ {
+ defaultValue = ((Mana::IntData*)itdef->second)->getData();
+ }
+ else
+ {
+ logger->log("%s: No integer value in registry for key %s",
+ mConfigPath.c_str(), key.c_str());
+ }
+ }
+ }
+ else
+ {
+ defaultValue = atoi(iter->second.c_str());
+ }
+ return defaultValue;
+}
+
+std::string Configuration::getStringValue(const std::string &key) const
+{
+ GETLOG();
+ std::string defaultValue = "";
+ Options::const_iterator iter = mOptions.find(key);
+ if (iter == mOptions.end())
+ {
+ if (mDefaultsData)
+ {
+ DefaultsData::const_iterator itdef = mDefaultsData->find(key);
+
+ if (itdef != mDefaultsData->end() && itdef->second
+ && itdef->second->getType() == Mana::VariableData::DATA_STRING)
+ {
+ defaultValue = ((Mana::StringData*)itdef->second)->getData();
+ }
+ else
+ {
+ logger->log("%s: No string value in registry for key %s",
+ mConfigPath.c_str(), key.c_str());
+ }
+ }
+ }
+ else
+ {
+ defaultValue = iter->second;
+ }
+ return defaultValue;
+}
+
+
+float Configuration::getFloatValue(const std::string &key) const
+{
+ GETLOG();
+ float defaultValue = 0.0f;
+ Options::const_iterator iter = mOptions.find(key);
+ if (iter == mOptions.end())
+ {
+ if (mDefaultsData)
+ {
+ DefaultsData::const_iterator itdef = mDefaultsData->find(key);
+
+ if (itdef != mDefaultsData->end() && itdef->second
+ && itdef->second->getType() == Mana::VariableData::DATA_FLOAT)
+ {
+ defaultValue = static_cast<float>(
+ ((Mana::FloatData*)itdef->second)->getData());
+ }
+ else
+ {
+ logger->log("%s: No float value in registry for key %s",
+ mConfigPath.c_str(), key.c_str());
+ }
+ }
+ }
+ else
+ {
+ defaultValue = atof(iter->second.c_str());
+ }
+ return defaultValue;
+}
+
+bool Configuration::getBoolValue(const std::string &key) const
+{
+ GETLOG();
+ bool defaultValue = false;
+ Options::const_iterator iter = mOptions.find(key);
+ if (iter == mOptions.end())
+ {
+ if (mDefaultsData)
+ {
+ DefaultsData::const_iterator itdef = mDefaultsData->find(key);
+
+ if (itdef != mDefaultsData->end() && itdef->second
+ && itdef->second->getType() == Mana::VariableData::DATA_BOOL)
+ {
+ defaultValue = ((Mana::BoolData*)itdef->second)->getData();
+ }
+ else
+ {
+ logger->log("%s: No boolean value in registry for key %s",
+ mConfigPath.c_str(), key.c_str());
+ }
+ }
+ }
+ else
+ {
+ defaultValue = getBoolFromString(iter->second);
+ }
+
+ return defaultValue;
+}
+
+void ConfigurationObject::initFromXML(xmlNodePtr parent_node)
+{
+ clear();
+
+ for_each_xml_child_node(node, parent_node)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "list"))
+ {
+ // list option handling
+
+ std::string name = XML::getProperty(node, "name", std::string());
+
+ for_each_xml_child_node(subnode, node)
+ {
+ if (xmlStrEqual(subnode->name, BAD_CAST name.c_str())
+ && subnode->type == XML_ELEMENT_NODE)
+ {
+ ConfigurationObject *cobj = new ConfigurationObject;
+
+ cobj->initFromXML(subnode); // recurse
+
+ mContainerOptions[name].push_back(cobj);
+ }
+ }
+
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "option"))
+ {
+ // single option handling
+
+ std::string name = XML::getProperty(node, "name", std::string());
+ std::string value = XML::getProperty(node, "value", std::string());
+
+ if (!name.empty())
+ mOptions[name] = value;
+ } // otherwise ignore
+ }
+}
+
+void Configuration::init(const std::string &filename, bool useResManager)
+{
+ mDefaultsData = 0;
+ XML::Document doc(filename, useResManager);
+
+ if (useResManager)
+ mConfigPath = "PhysFS://" + filename;
+ else
+ mConfigPath = filename;
+
+ if (!doc.rootNode())
+ {
+ logger->log("Couldn't open configuration file: %s", filename.c_str());
+ return;
+ }
+
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "configuration"))
+ {
+ logger->log("Warning: No configuration file (%s)", filename.c_str());
+ return;
+ }
+
+ initFromXML(rootNode);
+}
+
+void ConfigurationObject::writeToXML(xmlTextWriterPtr writer)
+{
+ for (Options::const_iterator i = mOptions.begin(), i_end = mOptions.end();
+ i != i_end; ++i)
+ {
+ xmlTextWriterStartElement(writer, BAD_CAST "option");
+ xmlTextWriterWriteAttribute(writer,
+ BAD_CAST "name", BAD_CAST i->first.c_str());
+
+ xmlTextWriterWriteAttribute(writer,
+ BAD_CAST "value", BAD_CAST i->second.c_str());
+ xmlTextWriterEndElement(writer);
+ }
+
+ for (std::map<std::string, ConfigurationList>::const_iterator
+ it = mContainerOptions.begin();
+ it != mContainerOptions.end(); it++)
+ {
+ const char *name = it->first.c_str();
+
+ xmlTextWriterStartElement(writer, BAD_CAST "list");
+ xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST name);
+
+ // recurse on all elements
+ for (ConfigurationList::const_iterator elt_it = it->second.begin();
+ elt_it != it->second.end(); elt_it++)
+ {
+ xmlTextWriterStartElement(writer, BAD_CAST name);
+ (*elt_it)->writeToXML(writer);
+ xmlTextWriterEndElement(writer);
+ }
+
+ xmlTextWriterEndElement(writer);
+ }
+}
+
+void Configuration::write()
+{
+ // Do not attempt to write to file that cannot be opened for writing
+ FILE *testFile = fopen(mConfigPath.c_str(), "w");
+ if (!testFile)
+ {
+ logger->log("Configuration::write() couldn't open %s for writing",
+ mConfigPath.c_str());
+ return;
+ }
+ else
+ {
+ fclose(testFile);
+ }
+
+ xmlTextWriterPtr writer = xmlNewTextWriterFilename(mConfigPath.c_str(), 0);
+
+ if (!writer)
+ {
+ logger->log1("Configuration::write() error while creating writer");
+ return;
+ }
+
+ logger->log1("Configuration::write() writing configuration...");
+
+ xmlTextWriterSetIndent(writer, 1);
+ xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
+// xmlTextWriterStartDocument(writer, NULL, "utf8", NULL);
+ xmlTextWriterStartElement(writer, BAD_CAST "configuration");
+
+ writeToXML(writer);
+
+ xmlTextWriterEndDocument(writer);
+ xmlFreeTextWriter(writer);
+}
+
+void Configuration::addListener(
+ const std::string &key, ConfigListener *listener)
+{
+ mListenerMap[key].push_front(listener);
+}
+
+void Configuration::removeListener(
+ const std::string &key, ConfigListener *listener)
+{
+ mListenerMap[key].remove(listener);
+} \ No newline at end of file
diff --git a/src/configuration.h b/src/configuration.h
new file mode 100644
index 000000000..d8999500a
--- /dev/null
+++ b/src/configuration.h
@@ -0,0 +1,302 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CONFIGURATION_H
+#define CONFIGURATION_H
+
+#include "utils/stringutils.h"
+#include "defaults.h"
+
+#include <libxml/xmlwriter.h>
+
+#include <cassert>
+#include <list>
+#include <map>
+#include <string>
+
+class ConfigListener;
+class ConfigurationObject;
+
+/**
+ * Configuration list manager interface; responsible for
+ * serializing/deserializing configuration choices in containers.
+ *
+ * \param T Type of the container elements to serialise
+ * \param CONT Type of the container we (de)serialise
+ */
+template <class T, class CONT>
+class ConfigurationListManager
+{
+ public:
+ /**
+ * Writes a value into a configuration object
+ *
+ * \param value The value to write out
+ * \param obj The configuation object to write to
+ * \return obj, or otherwise NULL to indicate that this option should
+ * be skipped
+ */
+ virtual ConfigurationObject
+ *writeConfigItem(T value, ConfigurationObject *obj) = 0;
+
+ /**
+ * Reads a value from a configuration object
+ *
+ * \param obj The configuration object to read from
+ * \param container The container to insert the object to
+ */
+ virtual CONT readConfigItem(ConfigurationObject *obj,
+ CONT container) = 0;
+
+ virtual ~ConfigurationListManager() {}
+};
+
+/**
+ * Configuration object, mapping values to names and possibly containing
+ * lists of further configuration objects
+ *
+ * \ingroup CORE
+ */
+class ConfigurationObject
+{
+ friend class Configuration;
+
+ public:
+ virtual ~ConfigurationObject();
+
+ /**
+ * Sets an option using a string value.
+ *
+ * \param key Option identifier.
+ * \param value Value.
+ */
+ virtual void setValue(const std::string &key,
+ const std::string &value);
+
+ void deleteKey(const std::string &key);
+
+ /**
+ * Gets a value as string.
+ *
+ * \param key Option identifier.
+ * \param deflt Default option if not there or error.
+ */
+ std::string getValue(const std::string &key,
+ const std::string &deflt) const;
+
+ int getValue(const std::string &key, int deflt) const;
+
+ int getValueInt(const std::string &key, int deflt) const;
+
+ bool getValueBool(const std::string &key, bool deflt) const;
+
+ unsigned getValue(const std::string &key, unsigned deflt) const;
+
+ double getValue(const std::string &key, double deflt) const;
+
+ /**
+ * Re-sets all data in the configuration
+ */
+ virtual void clear();
+
+ /**
+ * Serialises a container into a list of configuration options
+ *
+ * \param IT Iterator type over CONT
+ * \param T Elements that IT iterates over
+ * \param CONT The associated container type
+ *
+ * \param name Name of the list the elements should be stored under
+ * \param begin Iterator start
+ * \param end Iterator end
+ * \param manager An object capable of serialising T items
+ */
+ template <class IT, class T, class CONT>
+ void setList(const std::string &name, IT begin, IT end,
+ ConfigurationListManager<T, CONT> *manager)
+ {
+ if (!manager)
+ return;
+
+ ConfigurationObject *nextobj = new ConfigurationObject;
+ deleteList(name);
+ ConfigurationList *list = &(mContainerOptions[name]);
+
+ for (IT it = begin; it != end; it++)
+ {
+ ConfigurationObject *wrobj
+ = manager->writeConfigItem(*it, nextobj);
+ if (wrobj)
+ { // wrote something
+ assert (wrobj == nextobj);
+ nextobj = new ConfigurationObject;
+ list->push_back(wrobj);
+ }
+ else
+ {
+ nextobj->clear(); // you never know...
+ }
+ }
+
+ delete nextobj;
+ nextobj = 0;
+ }
+
+ /**
+ * Serialises a container into a list of configuration options
+ *
+ * \param IT Iterator type over CONT
+ * \param T Elements that IT iterates over
+ * \param CONT The associated container type
+ *
+ * \param name Name of the list the elements should be read from under
+ * \param empty Initial (empty) container to write to
+ * \param manager An object capable of deserialising items into CONT
+ */
+ template<class T, class CONT>
+ CONT getList(const std::string &name, CONT empty,
+ ConfigurationListManager<T, CONT> *manager)
+ {
+ ConfigurationList *list = &(mContainerOptions[name]);
+ CONT container = empty;
+
+ for (ConfigurationList::const_iterator it = list->begin();
+ it != list->end(); it++)
+ {
+ container = manager->readConfigItem(*it, container);
+ }
+
+ return container;
+ }
+
+ protected:
+ virtual void initFromXML(xmlNodePtr node);
+ virtual void writeToXML(xmlTextWriterPtr writer);
+
+ void deleteList(const std::string &name);
+
+ typedef std::map<std::string, std::string> Options;
+ Options mOptions;
+
+ typedef std::list<ConfigurationObject *> ConfigurationList;
+ std::map<std::string, ConfigurationList> mContainerOptions;
+};
+
+/**
+ * Configuration handler for reading (and writing).
+ *
+ * \ingroup CORE
+ */
+class Configuration : public ConfigurationObject
+{
+ public:
+ ~Configuration();
+
+ /**
+ * Reads config file and parse all options into memory.
+ *
+ * @param filename path to config file
+ * @param useResManager Make use of the resource manager.
+ */
+ void init(const std::string &filename, bool useResManager = false);
+
+ /**
+ * Set the default values for each keys.
+ *
+ * @param defaultsData data used as defaults.
+ */
+ void setDefaultValues(DefaultsData *defaultsData);
+
+ /**
+ * Writes the current settings back to the config file.
+ */
+ void write();
+
+ /**
+ * Adds a listener to the listen list of the specified config option.
+ */
+ void addListener(const std::string &key, ConfigListener *listener);
+
+ /**
+ * Removes a listener from the listen list of the specified config
+ * option.
+ */
+ void removeListener(const std::string &key, ConfigListener *listener);
+
+ void setValue(const std::string &key, const std::string &value);
+
+ inline void setValue(const std::string &key, const char *value)
+ { setValue(key, std::string(value)); }
+
+ inline void setValue(const std::string &key, float value)
+ { setValue(key, toString(value)); }
+
+ inline void setValue(const std::string &key, double value)
+ { setValue(key, toString(value)); }
+
+ inline void setValue(const std::string &key, int value)
+ { setValue(key, toString(value)); }
+
+ inline void setValueInt(const std::string &key, int value)
+ { setValue(key, toString(value)); }
+
+ inline void setValue(const std::string &key, unsigned value)
+ { setValue(key, toString(value)); }
+
+ inline void setValue(const std::string &key, bool value)
+ { setValue(key, value ? "1" : "0"); }
+
+ const std::string getConfigPath() const
+ { return mConfigPath; }
+
+ /**
+ * returns a value corresponding to the given key.
+ * The default value returned in based on fallbacks registry.
+ * @see defaults.h
+ */
+ int getIntValue(const std::string &key) const;
+ float getFloatValue(const std::string &key) const;
+ std::string getStringValue(const std::string &key) const;
+ bool getBoolValue(const std::string &key) const;
+
+ private:
+ /**
+ * Clean up the default values member.
+ */
+ void cleanDefaults();
+
+ typedef std::list<ConfigListener*> Listeners;
+ typedef Listeners::iterator ListenerIterator;
+ typedef std::map<std::string, Listeners> ListenerMap;
+ typedef ListenerMap::iterator ListenerMapIterator;
+ ListenerMap mListenerMap;
+
+ std::string mConfigPath; /**< Location of config file */
+ DefaultsData *mDefaultsData; /**< Defaults of value
+ for a given key */
+};
+
+extern Configuration branding;
+extern Configuration config;
+extern Configuration serverConfig;
+extern Configuration paths;
+
+#endif
diff --git a/src/defaults.cpp b/src/defaults.cpp
new file mode 100644
index 000000000..0628aa72c
--- /dev/null
+++ b/src/defaults.cpp
@@ -0,0 +1,253 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "defaults.h"
+
+#include "utils/stringutils.h"
+
+#include "being.h"
+#include "graphics.h"
+#include "client.h"
+
+#include <stdlib.h>
+
+using namespace Mana;
+
+VariableData* createData(int defData)
+{
+ return new IntData(defData);
+}
+
+VariableData* createData(double defData)
+{
+ return new FloatData(defData);
+}
+
+VariableData* createData(float defData)
+{
+ return new FloatData(defData);
+}
+
+VariableData* createData(const std::string &defData)
+{
+ return new StringData(defData);
+}
+
+VariableData* createData(const char* defData)
+{
+ return new StringData(defData);
+}
+
+VariableData* createData(bool defData)
+{
+ return new BoolData(defData);
+}
+
+#define AddDEF(defaultsData, key, value) \
+ defaultsData->insert(std::pair<std::string, VariableData*> \
+ (key, createData(value)));
+
+
+DefaultsData* getConfigDefaults()
+{
+ DefaultsData* configData = new DefaultsData;
+ // Init main config defaults
+ AddDEF(configData, "OverlayDetail", 2);
+ AddDEF(configData, "speechBubblecolor", "000000");
+ AddDEF(configData, "speechBubbleAlpha", 1.0f);
+ AddDEF(configData, "MostUsedServerName0", "server.themanaworld.org");
+ AddDEF(configData, "visiblenames", true);
+ AddDEF(configData, "speech", static_cast<int>(Being::TEXT_OVERHEAD));
+ AddDEF(configData, "showgender", true);
+ AddDEF(configData, "showlevel", false);
+ AddDEF(configData, "showMonstersTakedDamage", true);
+ AddDEF(configData, "highlightAttackRange", false);
+ AddDEF(configData, "highlightMapPortals", true);
+ AddDEF(configData, "highlightMonsterAttackRange", false);
+ AddDEF(configData, "chatMaxCharLimit", 300);
+ AddDEF(configData, "lowTraffic", true);
+ AddDEF(configData, "invertMoveDirection", 0);
+ AddDEF(configData, "crazyMoveType", 1);
+ AddDEF(configData, "attackWeaponType", 1);
+ AddDEF(configData, "quickDropCounter", 1);
+ AddDEF(configData, "pickUpType", 2);
+ AddDEF(configData, "magicAttackType", 0);
+ AddDEF(configData, "attackType", 1);
+ AddDEF(configData, "followMode", 0);
+ AddDEF(configData, "imitationMode", 0);
+ AddDEF(configData, "syncPlayerMove", false);
+ AddDEF(configData, "drawPath", false);
+ AddDEF(configData, "moveToTargetType", 0);
+ AddDEF(configData, "crazyMoveProgram", "mumrsonmdmlon");
+ AddDEF(configData, "disableGameModifiers", false);
+ AddDEF(configData, "targetDeadPlayers", false);
+ AddDEF(configData, "afkMessage", "I am away from keyboard");
+ AddDEF(configData, "particleMaxCount", 3000);
+ AddDEF(configData, "particleFastPhysics", 0);
+ AddDEF(configData, "particleEmitterSkip", 1);
+ AddDEF(configData, "particleeffects", true);
+ AddDEF(configData, "logToStandardOut", false);
+ AddDEF(configData, "opengl", 0);
+ AddDEF(configData, "screenwidth", defaultScreenWidth);
+ AddDEF(configData, "screenheight", defaultScreenHeight);
+ AddDEF(configData, "screen", false);
+ AddDEF(configData, "hwaccel", false);
+ AddDEF(configData, "sound", false);
+ AddDEF(configData, "sfxVolume", 100);
+ AddDEF(configData, "musicVolume", 60);
+ AddDEF(configData, "remember", false);
+ AddDEF(configData, "username", "");
+ AddDEF(configData, "lastCharacter", "");
+ AddDEF(configData, "fpslimit", 60);
+ AddDEF(configData, "altfpslimit", 5);
+ AddDEF(configData, "updatehost", "");
+ AddDEF(configData, "screenshotDirectory", "");
+ AddDEF(configData, "useScreenshotDirectorySuffix", true);
+ AddDEF(configData, "screenshotDirectorySuffix", "");
+ AddDEF(configData, "EnableSync", false);
+ AddDEF(configData, "joystickEnabled", false);
+ AddDEF(configData, "upTolerance", 100);
+ AddDEF(configData, "downTolerance", 100);
+ AddDEF(configData, "leftTolerance", 100);
+ AddDEF(configData, "rightTolerance", 100);
+ AddDEF(configData, "logNpcInGui", true);
+ AddDEF(configData, "download-music", false);
+ AddDEF(configData, "guialpha", 0.8f);
+ AddDEF(configData, "ChatLogLength", 0);
+ AddDEF(configData, "enableChatLog", false);
+ AddDEF(configData, "whispertab", true);
+ AddDEF(configData, "customcursor", true);
+ AddDEF(configData, "showownname", true);
+ AddDEF(configData, "showpickupparticle", false);
+ AddDEF(configData, "showpickupchat", true);
+ AddDEF(configData, "fontSize", 11);
+ AddDEF(configData, "ReturnToggles", false);
+ AddDEF(configData, "ScrollLaziness", 16);
+ AddDEF(configData, "ScrollRadius", 0);
+ AddDEF(configData, "ScrollCenterOffsetX", 0);
+ AddDEF(configData, "ScrollCenterOffsetY", 0);
+ AddDEF(configData, "onlineServerList", "");
+ AddDEF(configData, "theme", "");
+ AddDEF(configData, "enableMumble", false);
+ AddDEF(configData, "playBattleSound", true);
+ AddDEF(configData, "playGuiSound", true);
+ AddDEF(configData, "playMusic", true);
+ AddDEF(configData, "packetcounters", true);
+ AddDEF(configData, "safemode", false);
+ AddDEF(configData, "font", "fonts/dejavusans.ttf");
+ AddDEF(configData, "boldFont", "fonts/dejavusans-bold.ttf");
+ AddDEF(configData, "particleFont", "fonts/dejavusans.ttf");
+ AddDEF(configData, "helpFont", "fonts/dejavusansmono.ttf");
+ AddDEF(configData, "showBackground", true);
+ AddDEF(configData, "enableTradeTab", true);
+ AddDEF(configData, "logToChat", false);
+ AddDEF(configData, "cyclePlayers", true);
+ AddDEF(configData, "cycleMonsters", false);
+ AddDEF(configData, "floorItemsHighlight", true);
+ AddDEF(configData, "enableBotCheker", true);
+ AddDEF(configData, "removeColors", true);
+ AddDEF(configData, "showMagicInDebug", false);
+ AddDEF(configData, "allowCommandsInChatTabs", true);
+ AddDEF(configData, "serverMsgInDebug", false);
+ AddDEF(configData, "hideShopMessages", true);
+ AddDEF(configData, "showChatHistory", true);
+ AddDEF(configData, "showChatColorsList", true);
+ AddDEF(configData, "chatMaxLinesLimit", 20);
+ AddDEF(configData, "chatColor", 0);
+ AddDEF(configData, "hideShield", true);
+ AddDEF(configData, "showJob", false);
+ AddDEF(configData, "updateOnlineList", true);
+ AddDEF(configData, "targetOnlyReachable", true);
+ AddDEF(configData, "errorsInDebug", true);
+ AddDEF(configData, "tradebot", true);
+ AddDEF(configData, "debugLog", false);
+ AddDEF(configData, "drawHotKeys", true);
+ AddDEF(configData, "serverAttack", true);
+ AddDEF(configData, "autofixPos", true);
+ AddDEF(configData, "alphaCache", false);
+ AddDEF(configData, "attackMoving", true);
+ AddDEF(configData, "quickStats", true);
+ AddDEF(configData, "warpParticle", false);
+ AddDEF(configData, "autoShop", false);
+ AddDEF(configData, "enableBattleTab", false);
+ AddDEF(configData, "showBattleEvents", false);
+ AddDEF(configData, "showMobHP", true);
+ return configData;
+}
+
+DefaultsData* getBrandingDefaults()
+{
+ DefaultsData* brandingData = new DefaultsData;
+ // Init config defaults
+ AddDEF(brandingData, "wallpapersPath", "");
+ AddDEF(brandingData, "wallpapersFile", "");
+ AddDEF(brandingData, "appName", "Mana");
+ AddDEF(brandingData, "appIcon", "icons/mana.png");
+ AddDEF(brandingData, "loginMusic", "Magick - Real.ogg");
+ AddDEF(brandingData, "defaultServer", "");
+ AddDEF(brandingData, "defaultPort", DEFAULT_PORT);
+ AddDEF(brandingData, "defaultServerType", "tmwathena");
+ AddDEF(brandingData, "onlineServerList",
+ "http://manasource.org/serverlist.xml");
+ AddDEF(brandingData, "appShort", "mana");
+ AddDEF(brandingData, "defaultUpdateHost", "");
+ AddDEF(brandingData, "helpPath", "");
+ AddDEF(brandingData, "onlineServerList", "");
+ AddDEF(brandingData, "theme", "");
+ AddDEF(brandingData, "font", "fonts/dejavusans.ttf");
+ AddDEF(brandingData, "boldFont", "fonts/dejavusans-bold.ttf");
+ AddDEF(brandingData, "particleFont", "fonts/dejavusans.ttf");
+ AddDEF(brandingData, "helpFont", "fonts/dejavusansmono.ttf");
+
+ AddDEF(brandingData, "guiPath", "graphics/gui/");
+ AddDEF(brandingData, "guiThemePath", "themes/");
+ AddDEF(brandingData, "fontsPath", "fonts/");
+ return brandingData;
+}
+
+DefaultsData* getPathsDefaults()
+{
+ DefaultsData *pathsData = new DefaultsData;
+ // Init paths.xml defaults
+ AddDEF(pathsData, "itemIcons", "graphics/items/");
+ AddDEF(pathsData, "unknownItemFile", "unknown-item.png");
+ AddDEF(pathsData, "sprites", "graphics/sprites/");
+ AddDEF(pathsData, "spriteErrorFile", "error.xml");
+
+ AddDEF(pathsData, "particles", "graphics/particles/");
+ AddDEF(pathsData, "levelUpEffectFile", "levelup.particle.xml");
+ AddDEF(pathsData, "portalEffectFile", "warparea.particle.xml");
+
+ AddDEF(pathsData, "minimaps", "graphics/minimaps/");
+ AddDEF(pathsData, "maps", "maps/");
+
+ AddDEF(pathsData, "sfx", "sfx/");
+ AddDEF(pathsData, "attackSfxFile", "fist-swish.ogg");
+ AddDEF(pathsData, "music", "music/");
+
+ AddDEF(pathsData, "wallpapers", "graphics/images/");
+ AddDEF(pathsData, "wallpaperFile", "login_wallpaper.png");
+
+ AddDEF(pathsData, "help", "help/");
+
+ return pathsData;
+}
+
+#undef AddDEF
diff --git a/src/defaults.h b/src/defaults.h
new file mode 100644
index 000000000..9b45ff777
--- /dev/null
+++ b/src/defaults.h
@@ -0,0 +1,42 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef DEFAULTS_H
+#define DEFAULTS_H
+
+#include <map>
+#include <string>
+#include "variabledata.h"
+
+using namespace Mana;
+
+typedef std::map<std::string, Mana::VariableData*> DefaultsData;
+
+VariableData* createData(int defData);
+VariableData* createData(double defData);
+VariableData* createData(float defData);
+VariableData* createData(const std::string &defData);
+VariableData* createData(const char* defData);
+VariableData* createData(bool defData);
+DefaultsData* getConfigDefaults();
+DefaultsData* getBrandingDefaults();
+DefaultsData* getPathsDefaults();
+
+#endif
diff --git a/src/dropshortcut.cpp b/src/dropshortcut.cpp
new file mode 100644
index 000000000..763a7aadd
--- /dev/null
+++ b/src/dropshortcut.cpp
@@ -0,0 +1,172 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "dropshortcut.h"
+
+#include "configuration.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+
+#include "gui/chat.h"
+#include "gui/widgets/chattab.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "utils/stringutils.h"
+
+DropShortcut *dropShortcut;
+
+DropShortcut::DropShortcut():
+ mItemSelected(-1)
+{
+ for (int i = 0; i < DROP_SHORTCUT_ITEMS; i++)
+ mItems[i] = -1;
+
+ load();
+ mLastDropIndex = 0;
+}
+
+DropShortcut::~DropShortcut()
+{
+// save();
+}
+
+void DropShortcut::load(bool oldConfig)
+{
+ Configuration *cfg;
+ if (oldConfig)
+ cfg = &config;
+ else
+ cfg = &serverConfig;
+
+ for (int i = 0; i < DROP_SHORTCUT_ITEMS; i++)
+ {
+ int itemId = (int) cfg->getValue("drop" + toString(i), -1);
+
+ if (itemId != -1)
+ mItems[i] = itemId;
+ }
+}
+
+void DropShortcut::save()
+{
+ for (int i = 0; i < DROP_SHORTCUT_ITEMS; i++)
+ {
+ const int itemId = mItems[i] ? mItems[i] : -1;
+ serverConfig.setValue("drop" + toString(i), itemId);
+ }
+}
+
+void DropShortcut::dropFirst()
+{
+ if (!player_node)
+ return;
+
+ if (!Client::limitPackets(PACKET_DROP))
+ return;
+
+ int itemId;
+ itemId = getItem(0);
+
+ if (itemId > 0)
+ {
+ Item *item = PlayerInfo::getInventory()->findItem(itemId);
+ if (item && item->getQuantity())
+ {
+ if (player_node->isServerBuggy())
+ {
+ Net::getInventoryHandler()->dropItem(item,
+ player_node->getQuickDropCounter());
+ }
+ else
+ {
+ for (int i = 0; i < player_node->getQuickDropCounter(); i++)
+ Net::getInventoryHandler()->dropItem(item, 1);
+ }
+ }
+ }
+}
+
+void DropShortcut::dropItems(int cnt)
+{
+ if (!player_node)
+ return;
+
+ int n = 0;
+ for (int f = 0; f < 9; f++)
+ {
+ for (int i = 0; i < player_node->getQuickDropCounter(); i++)
+ {
+ if (!Client::limitPackets(PACKET_DROP))
+ return;
+ if (dropItem())
+ n++;
+ }
+ if (n >= cnt)
+ break;
+ }
+}
+
+bool DropShortcut::dropItem(int cnt)
+{
+ int itemId = 0;
+ while (mLastDropIndex < DROP_SHORTCUT_ITEMS && itemId < 1)
+ {
+ itemId = getItem(mLastDropIndex);
+ mLastDropIndex++;
+ }
+ if (itemId > 0)
+ {
+ Item *item = PlayerInfo::getInventory()->findItem(itemId);
+ if (item && item->getQuantity() > 0)
+ {
+ Net::getInventoryHandler()->dropItem(item, cnt);
+ return true;
+ }
+ }
+ if (mLastDropIndex >= DROP_SHORTCUT_ITEMS)
+ mLastDropIndex = 0;
+
+ if (itemId < 1)
+ {
+ while (mLastDropIndex < DROP_SHORTCUT_ITEMS && itemId < 1)
+ {
+ itemId = getItem(mLastDropIndex);
+ mLastDropIndex++;
+ }
+ if (itemId > 0)
+ {
+ Item *item = PlayerInfo::getInventory()->findItem(itemId);
+ if (item && item->getQuantity() > 0)
+ {
+ Net::getInventoryHandler()->dropItem(item, cnt);
+ return true;
+ }
+ }
+ if (mLastDropIndex >= DROP_SHORTCUT_ITEMS)
+ mLastDropIndex = 0;
+ }
+ return false;
+}
diff --git a/src/dropshortcut.h b/src/dropshortcut.h
new file mode 100644
index 000000000..5a020879e
--- /dev/null
+++ b/src/dropshortcut.h
@@ -0,0 +1,155 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DROPSHORTCUT_H
+#define DROPSHORTCUT_H
+
+#define DROP_SHORTCUT_ITEMS 16
+
+class Item;
+
+/**
+ * The class which keeps track of the item shortcuts.
+ */
+class DropShortcut
+{
+ public:
+ /**
+ * Constructor.
+ */
+ DropShortcut();
+
+ /**
+ * Destructor.
+ */
+ ~DropShortcut();
+
+ /**
+ * Load the configuration information.
+ */
+ void load(bool oldConfig = false);
+
+ /**
+ * Save the configuration information.
+ */
+ void save();
+
+ /**
+ * Returns the shortcut item ID specified by the index.
+ *
+ * @param index Index of the shortcut item.
+ */
+ int getItem(int index) const
+ { return mItems[index]; }
+
+ /**
+ * Returns the amount of shortcut items.
+ */
+ int getItemCount() const
+ { return DROP_SHORTCUT_ITEMS; }
+
+ /**
+ * Returns the item ID that is currently selected.
+ */
+ int getItemSelected() const
+ { return mItemSelected; }
+
+ /**
+ * Adds the selected item ID to the items specified by the index.
+ *
+ * @param index Index of the items.
+ */
+ void setItem(int index)
+ { mItems[index] = mItemSelected; save(); }
+
+ /**
+ * Adds an item to the items store specified by the index.
+ *
+ * @param index Index of the item.
+ * @param itemId ID of the item.
+ */
+ void setItems(int index, int itemId)
+ { mItems[index] = itemId; save(); }
+
+ /**
+ * Set the item that is selected.
+ *
+ * @param itemId The ID of the item that is to be assigned.
+ */
+ void setItemSelected(int itemId)
+ { mItemSelected = itemId; }
+
+ /**
+ * A flag to check if the item is selected.
+ */
+ bool isItemSelected() const
+ { return mItemSelected > -1; }
+
+ /**
+ * Remove a item from the shortcut.
+ */
+ void removeItem(int index)
+ { mItems[index] = -1; save(); }
+
+ /**
+ * Try to use the item specified by the index.
+ *
+ * @param index Index of the item shortcut.
+ */
+ void useItem(int index);
+
+ /**
+ * Equip a item from the shortcut.
+ */
+ void equipItem(int index);
+
+ /**
+ * UnEquip a item from the shortcut.
+ */
+ void unequipItem(int index);
+
+ /**
+ * Drop first item.
+ */
+ void dropFirst();
+
+ /**
+ * Drop all items in cicle.
+ */
+ void dropItems(int cnt = 1);
+
+ private:
+
+ /**
+ * Drop item in cicle.
+ */
+ bool dropItem(int cnt = 1);
+
+ int mItems[DROP_SHORTCUT_ITEMS]; /**< The items stored. */
+ int mItemSelected; /**< The item held by cursor. */
+
+ int mLastDropIndex;
+};
+
+extern DropShortcut *dropShortcut;
+
+#endif
diff --git a/src/effectmanager.cpp b/src/effectmanager.cpp
new file mode 100644
index 000000000..e7722b4a9
--- /dev/null
+++ b/src/effectmanager.cpp
@@ -0,0 +1,107 @@
+/*
+ * An effects manager
+ * Copyright (C) 2008 Fate <fate.tmw@googlemail.com>
+ * Copyright (C) 2008 Chuck Miller <shadowmil@gmail.com>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "being.h"
+#include "effectmanager.h"
+#include "log.h"
+#include "particle.h"
+#include "sound.h"
+
+#include "utils/xml.h"
+
+EffectManager::EffectManager()
+{
+ XML::Document doc("effects.xml");
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "being-effects"))
+ {
+ logger->log1("Error loading being effects file: effects.xml");
+ return;
+ }
+ else
+ {
+ logger->log1("Effects are now loading");
+ }
+
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "effect"))
+ {
+ EffectDescription ed;
+ ed.id = XML::getProperty(node, "id", -1);
+ ed.GFX = XML::getProperty(node, "particle", "");
+ ed.SFX = XML::getProperty(node, "audio", "");
+ mEffects.push_back(ed);
+ }
+ }
+}
+
+EffectManager::~EffectManager()
+{
+}
+
+bool EffectManager::trigger(int id, Being* being)
+{
+ if (!being || !particleEngine)
+ return false;
+
+ bool rValue = false;
+ for (std::list<EffectDescription>::iterator i = mEffects.begin();
+ i != mEffects.end(); ++i)
+ {
+ if ((*i).id == id)
+ {
+ rValue = true;
+ if (!(*i).GFX.empty())
+ {
+ Particle *selfFX = particleEngine->addEffect((*i).GFX, 0, 0);
+ being->controlParticle(selfFX);
+ }
+ if (!(*i).SFX.empty())
+ sound.playSfx((*i).SFX);
+ break;
+ }
+ }
+ return rValue;
+}
+
+bool EffectManager::trigger(int id, int x, int y)
+{
+ if (!particleEngine)
+ return false;
+
+ bool rValue = false;
+ for (std::list<EffectDescription>::iterator i = mEffects.begin();
+ i != mEffects.end(); ++i)
+ {
+ if ((*i).id == id)
+ {
+ rValue = true;
+ if (!(*i).GFX.empty() && particleEngine)
+ particleEngine->addEffect((*i).GFX, x, y);
+ if (!(*i).SFX.empty())
+ sound.playSfx((*i).SFX);
+ break;
+ }
+ }
+ return rValue;
+}
diff --git a/src/effectmanager.h b/src/effectmanager.h
new file mode 100644
index 000000000..ef1e0f275
--- /dev/null
+++ b/src/effectmanager.h
@@ -0,0 +1,61 @@
+/*
+ * An effects manager
+ * Copyright (C) 2008 Fate <fate.tmw@googlemail.com>
+ * Copyright (C) 2008 Chuck Miller <shadowmil@gmail.com>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EFFECT_MANAGER_H
+#define EFFECT_MANAGER_H
+
+#include <list>
+#include <string>
+
+class Being;
+
+class EffectManager
+{
+ public:
+ struct EffectDescription
+ {
+ int id;
+ std::string GFX;
+ std::string SFX;
+ };
+
+ EffectManager();
+ ~EffectManager();
+
+ /**
+ * Triggers a effect with the id, at
+ * the specified being.
+ */
+ bool trigger(int id, Being* being);
+
+ /**
+ * Triggers a effect with the id, at
+ * the specified x and y coordinate.
+ */
+ bool trigger(int id, int x, int y);
+
+ private:
+ std::list<EffectDescription> mEffects;
+};
+
+extern EffectManager *effectManager;
+
+#endif // EFFECT_MANAGER_H
diff --git a/src/emoteshortcut.cpp b/src/emoteshortcut.cpp
new file mode 100644
index 000000000..59477fdf6
--- /dev/null
+++ b/src/emoteshortcut.cpp
@@ -0,0 +1,89 @@
+/*
+ * Extended support for activating emotes
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "emoteshortcut.h"
+
+#include "configuration.h"
+#include "localplayer.h"
+
+#include "utils/stringutils.h"
+
+#include "resources/emotedb.h"
+
+EmoteShortcut *emoteShortcut;
+
+EmoteShortcut::EmoteShortcut():
+ mEmoteSelected(0)
+{
+// load();
+ for (int i = 0; i < SHORTCUT_EMOTES; i++)
+ mEmotes[i] = 0;
+}
+
+EmoteShortcut::~EmoteShortcut()
+{
+ save();
+}
+
+void EmoteShortcut::load()
+{
+ for (int i = 0, j = 0; i <= EmoteDB::getLast() && j < SHORTCUT_EMOTES; i++)
+ {
+ const AnimatedSprite* sprite = EmoteDB::getAnimation(i, true);
+ if (sprite)
+ {
+ mEmotes[j] = i + 1;
+ j ++;
+ }
+ }
+
+/*
+ for (int i = 0; i < SHORTCUT_EMOTES; i++)
+ {
+ unsigned char emoteId = static_cast<unsigned char>(
+ serverConfig.getValue("emoteshortcut" + toString(i), i + 1));
+ mEmotes[i] = emoteId;
+// mEmotes[i] = i + 1;
+ }
+*/
+}
+
+void EmoteShortcut::save()
+{
+ for (int i = 0; i < SHORTCUT_EMOTES; i++)
+ {
+ unsigned char emoteId = mEmotes[i] ? mEmotes[i]
+ : static_cast<unsigned char>(0);
+ serverConfig.setValue("emoteshortcut" + toString(i),
+ static_cast<unsigned int>(emoteId));
+ }
+}
+
+void EmoteShortcut::useEmote(int index)
+{
+ if (!player_node)
+ return;
+
+ if (index > 0 && index <= SHORTCUT_EMOTES)
+ {
+ if (mEmotes[index - 1] > 0)
+ player_node->emote(mEmotes[index - 1]);
+ }
+}
diff --git a/src/emoteshortcut.h b/src/emoteshortcut.h
new file mode 100644
index 000000000..0e06bb633
--- /dev/null
+++ b/src/emoteshortcut.h
@@ -0,0 +1,125 @@
+/*
+ * Extended support for activating emotes
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EMOTESHORTCUT_H
+#define EMOTESHORTCUT_H
+
+#define SHORTCUT_EMOTES 42
+
+/**
+ * The class which keeps track of the emote shortcuts.
+ */
+class EmoteShortcut
+{
+ public:
+ /**
+ * Constructor.
+ */
+ EmoteShortcut();
+
+ /**
+ * Destructor.
+ */
+ ~EmoteShortcut();
+
+ /**
+ * Load the configuration information.
+ */
+ void load();
+
+ /**
+ * Returns the shortcut Emote ID specified by the index.
+ *
+ * @param index Index of the shortcut Emote.
+ */
+ unsigned char getEmote(int index) const
+ { return mEmotes[index]; }
+
+ /**
+ * Returns the amount of shortcut Emotes.
+ */
+ unsigned int getEmoteCount() const
+ { return SHORTCUT_EMOTES; }
+
+ /**
+ * Returns the emote ID that is currently selected.
+ */
+ unsigned char getEmoteSelected() const
+ { return mEmoteSelected; }
+
+ /**
+ * Adds the selected emote ID to the emotes specified by the index.
+ *
+ * @param index Index of the emotes.
+ */
+ void setEmote(int index)
+ { mEmotes[index] = mEmoteSelected; }
+
+ /**
+ * Adds a emoticon to the emotes store specified by the index.
+ *
+ * @param index Index of the emote.
+ * @param emoteId ID of the emote.
+ */
+ void setEmotes(int index, unsigned char emoteId)
+ { mEmotes[index] = emoteId; }
+
+ /**
+ * Set the Emote that is selected.
+ *
+ * @param emoteId The ID of the emote that is to be assigned.
+ */
+ void setEmoteSelected(unsigned char emoteId)
+ { mEmoteSelected = emoteId; }
+
+ /**
+ * A flag to check if the Emote is selected.
+ */
+ bool isEmoteSelected() const
+ { return mEmoteSelected; }
+
+ /**
+ * Remove a Emote from the shortcut.
+ */
+ void removeEmote(int index)
+ { if (index >= 0 && index < SHORTCUT_EMOTES) mEmotes[index] = 0; }
+
+ /**
+ * Try to use the Emote specified by the index.
+ *
+ * @param index Index of the emote shortcut.
+ */
+ void useEmote(int index);
+
+ private:
+ /**
+ * Save the configuration information.
+ */
+ void save();
+
+ unsigned char mEmotes[SHORTCUT_EMOTES]; /**< The emote stored. */
+ unsigned char mEmoteSelected; /**< The emote held
+ by cursor. */
+
+};
+
+extern EmoteShortcut *emoteShortcut;
+
+#endif
diff --git a/src/enet/ChangeLog b/src/enet/ChangeLog
new file mode 100644
index 000000000..45f14db6a
--- /dev/null
+++ b/src/enet/ChangeLog
@@ -0,0 +1,86 @@
+ENet 1.3.0 (June 5, 2010):
+
+* enet_host_create() now requires the channel limit to be specified as
+a parameter
+* enet_host_connect() now accepts a data parameter which is supplied
+to the receiving receiving host in the event data field for a connect event
+* added an adaptive order-2 PPM range coder as a built-in compressor option
+which can be set with enet_host_compress_with_range_coder()
+* added support for packet compression configurable with a callback
+* improved session number handling to not rely on the packet checksum
+field, saving 4 bytes per packet unless the checksum option is used
+* removed the dependence on the rand callback for session number handling
+
+Caveats: This version is not protocol compatible with the 1.2 series or
+earlier. The enet_host_connect and enet_host_create API functions require
+supplying additional parameters.
+
+ENet 1.2.2 (June 5, 2010):
+
+* checksum functionality is now enabled by setting a checksum callback
+inside ENetHost instead of being a configure script option
+* added totalSentData, totalSentPackets, totalReceivedData, and
+totalReceivedPackets counters inside ENetHost for getting usage
+statistics
+* added enet_host_channel_limit() for limiting the maximum number of
+channels allowed by connected peers
+* now uses dispatch queues for event dispatch rather than potentially
+unscalable array walking
+* added no_memory callback that is called when a malloc attempt fails,
+such that if no_memory returns rather than aborts (the default behavior),
+then the error is propagated to the return value of the API calls
+* now uses packed attribute for protocol structures on platforms with
+strange alignment rules
+* improved autoconf build system contributed by Nathan Brink allowing
+for easier building as a shared library
+
+Caveats: If you were using the compile-time option that enabled checksums,
+make sure to set the checksum callback inside ENetHost to enet_crc32 to
+regain the old behavior. The ENetCallbacks structure has added new fields,
+so make sure to clear the structure to zero before use if
+using enet_initialize_with_callbacks().
+
+ENet 1.2.1 (November 12, 2009):
+
+* fixed bug that could cause disconnect events to be dropped
+* added thin wrapper around select() for portable usage
+* added ENET_SOCKOPT_REUSEADDR socket option
+* factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create()
+* added contributed Code::Blocks build file
+
+ENet 1.2 (February 12, 2008):
+
+* fixed bug in VERIFY_CONNECT acknowledgement that could cause connect
+attempts to occasionally timeout
+* fixed acknowledgements to check both the outgoing and sent queues
+when removing acknowledged packets
+* fixed accidental bit rot in the MSVC project file
+* revised sequence number overflow handling to address some possible
+disconnect bugs
+* added enet_host_check_events() for getting only local queued events
+* factored out socket option setting into enet_socket_set_option() so
+that socket options are now set separately from enet_socket_create()
+
+Caveats: While this release is superficially protocol compatible with 1.1,
+differences in the sequence number overflow handling can potentially cause
+random disconnects.
+
+ENet 1.1 (June 6, 2007):
+
+* optional CRC32 just in case someone needs a stronger checksum than UDP
+provides (--enable-crc32 configure option)
+* the size of packet headers are half the size they used to be (so less
+overhead when sending small packets)
+* enet_peer_disconnect_later() that waits till all queued outgoing
+packets get sent before issuing an actual disconnect
+* freeCallback field in individual packets for notification of when a
+packet is about to be freed
+* ENET_PACKET_FLAG_NO_ALLOCATE for supplying pre-allocated data to a
+packet (can be used in concert with freeCallback to support some custom
+allocation schemes that the normal memory allocation callbacks would
+normally not allow)
+* enet_address_get_host_ip() for printing address numbers
+* promoted the enet_socket_*() functions to be part of the API now
+* a few stability/crash fixes
+
+
diff --git a/src/enet/LICENSE b/src/enet/LICENSE
new file mode 100644
index 000000000..df0f91e98
--- /dev/null
+++ b/src/enet/LICENSE
@@ -0,0 +1,7 @@
+Copyright (c) 2002-2010 Lee Salzman
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/src/enet/README b/src/enet/README
new file mode 100644
index 000000000..7f7a0ad01
--- /dev/null
+++ b/src/enet/README
@@ -0,0 +1,15 @@
+Please visit the ENet homepage at http://enet.bespin.org for installation
+and usage instructions.
+
+If you obtained this package from CVS, the quick description on how to build
+is:
+
+# Generate the build system.
+
+autoreconf -vfi
+
+# Compile and install the library.
+
+./configure && make && make install
+
+
diff --git a/src/enet/callbacks.c b/src/enet/callbacks.c
new file mode 100644
index 000000000..f94128256
--- /dev/null
+++ b/src/enet/callbacks.c
@@ -0,0 +1,47 @@
+/**
+ @file callbacks.c
+ @brief ENet callback functions
+*/
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+static ENetCallbacks callbacks = { malloc, free, abort };
+
+int
+enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
+{
+ if (version < ENET_VERSION_CREATE (1, 3, 0))
+ return -1;
+
+ if (inits -> malloc != NULL || inits -> free != NULL)
+ {
+ if (inits -> malloc == NULL || inits -> free == NULL)
+ return -1;
+
+ callbacks.malloc = inits -> malloc;
+ callbacks.free = inits -> free;
+ }
+
+ if (inits -> no_memory != NULL)
+ callbacks.no_memory = inits -> no_memory;
+
+ return enet_initialize ();
+}
+
+void *
+enet_malloc (size_t size)
+{
+ void * memory = callbacks.malloc (size);
+
+ if (memory == NULL)
+ callbacks.no_memory ();
+
+ return memory;
+}
+
+void
+enet_free (void * memory)
+{
+ callbacks.free (memory);
+}
+
diff --git a/src/enet/callbacks.h b/src/enet/callbacks.h
new file mode 100644
index 000000000..340a4a989
--- /dev/null
+++ b/src/enet/callbacks.h
@@ -0,0 +1,27 @@
+/**
+ @file callbacks.h
+ @brief ENet callbacks
+*/
+#ifndef __ENET_CALLBACKS_H__
+#define __ENET_CALLBACKS_H__
+
+#include <stdlib.h>
+
+typedef struct _ENetCallbacks
+{
+ void * (ENET_CALLBACK * malloc) (size_t size);
+ void (ENET_CALLBACK * free) (void * memory);
+ void (ENET_CALLBACK * no_memory) (void);
+} ENetCallbacks;
+
+/** @defgroup callbacks ENet internal callbacks
+ @{
+ @ingroup private
+*/
+extern void * enet_malloc (size_t);
+extern void enet_free (void *);
+
+/** @} */
+
+#endif /* __ENET_CALLBACKS_H__ */
+
diff --git a/src/enet/compress.c b/src/enet/compress.c
new file mode 100644
index 000000000..784489a78
--- /dev/null
+++ b/src/enet/compress.c
@@ -0,0 +1,654 @@
+/**
+ @file compress.c
+ @brief An adaptive order-2 PPM range coder
+*/
+#define ENET_BUILDING_LIB 1
+#include <string.h>
+#include "enet/enet.h"
+
+typedef struct _ENetSymbol
+{
+ /* binary indexed tree of symbols */
+ enet_uint8 value;
+ enet_uint8 count;
+ enet_uint16 under;
+ enet_uint16 left, right;
+
+ /* context defined by this symbol */
+ enet_uint16 symbols;
+ enet_uint16 escapes;
+ enet_uint16 total;
+ enet_uint16 parent;
+} ENetSymbol;
+
+/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */
+enum
+{
+ ENET_RANGE_CODER_TOP = 1<<24,
+ ENET_RANGE_CODER_BOTTOM = 1<<16,
+
+ ENET_CONTEXT_SYMBOL_DELTA = 3,
+ ENET_CONTEXT_SYMBOL_MINIMUM = 1,
+ ENET_CONTEXT_ESCAPE_MINIMUM = 1,
+
+ ENET_SUBCONTEXT_ORDER = 2,
+ ENET_SUBCONTEXT_SYMBOL_DELTA = 2,
+ ENET_SUBCONTEXT_ESCAPE_DELTA = 5
+};
+
+/* context exclusion roughly halves compression speed, so disable for now */
+#undef ENET_CONTEXT_EXCLUSION
+
+typedef struct _ENetRangeCoder
+{
+ /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */
+ ENetSymbol symbols[4096];
+} ENetRangeCoder;
+
+void *
+enet_range_coder_create (void)
+{
+ ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder));
+ if (rangeCoder == NULL)
+ return NULL;
+
+ return rangeCoder;
+}
+
+void
+enet_range_coder_destroy (void * context)
+{
+ ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+ if (rangeCoder == NULL)
+ return;
+
+ enet_free (rangeCoder);
+}
+
+#define ENET_SYMBOL_CREATE(symbol, value_, count_) \
+{ \
+ symbol = & rangeCoder -> symbols [nextSymbol ++]; \
+ symbol -> value = value_; \
+ symbol -> count = count_; \
+ symbol -> under = count_; \
+ symbol -> left = 0; \
+ symbol -> right = 0; \
+ symbol -> symbols = 0; \
+ symbol -> escapes = 0; \
+ symbol -> total = 0; \
+ symbol -> parent = 0; \
+}
+
+#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \
+{ \
+ ENET_SYMBOL_CREATE (context, 0, 0); \
+ (context) -> escapes = escapes_; \
+ (context) -> total = escapes_ + 256*minimum; \
+ (context) -> symbols = 0; \
+}
+
+static enet_uint16
+enet_symbol_rescale (ENetSymbol * symbol)
+{
+ enet_uint16 total = 0;
+ for (;;)
+ {
+ symbol -> count -= symbol->count >> 1;
+ symbol -> under = symbol -> count;
+ if (symbol -> left)
+ symbol -> under += enet_symbol_rescale (symbol + symbol -> left);
+ total += symbol -> under;
+ if (! symbol -> right) break;
+ symbol += symbol -> right;
+ }
+ return total;
+}
+
+#define ENET_CONTEXT_RESCALE(context, minimum) \
+{ \
+ (context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \
+ (context) -> escapes -= (context) -> escapes >> 1; \
+ (context) -> total += (context) -> escapes + 256*minimum; \
+}
+
+#define ENET_RANGE_CODER_OUTPUT(value) \
+{ \
+ if (outData >= outEnd) \
+ return 0; \
+ * outData ++ = value; \
+}
+
+#define ENET_RANGE_CODER_ENCODE(under, count, total) \
+{ \
+ encodeRange /= (total); \
+ encodeLow += (under) * encodeRange; \
+ encodeRange *= (count); \
+ for (;;) \
+ { \
+ if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \
+ { \
+ if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
+ encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
+ } \
+ ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
+ encodeRange <<= 8; \
+ encodeLow <<= 8; \
+ } \
+}
+
+#define ENET_RANGE_CODER_FLUSH \
+{ \
+ while (encodeLow) \
+ { \
+ ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
+ encodeLow <<= 8; \
+ } \
+}
+
+#define ENET_RANGE_CODER_FREE_SYMBOLS \
+{ \
+ if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \
+ { \
+ nextSymbol = 0; \
+ ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \
+ predicted = 0; \
+ order = 0; \
+ } \
+}
+
+#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \
+{ \
+ under_ = value*minimum; \
+ count_ = minimum; \
+ if (! (context) -> symbols) \
+ { \
+ ENET_SYMBOL_CREATE (symbol_, value_, update); \
+ (context) -> symbols = symbol_ - (context); \
+ } \
+ else \
+ { \
+ ENetSymbol * node = (context) + (context) -> symbols; \
+ for (;;) \
+ { \
+ if (value_ < node -> value) \
+ { \
+ node -> under += update; \
+ if (node -> left) { node += node -> left; continue; } \
+ ENET_SYMBOL_CREATE (symbol_, value_, update); \
+ node -> left = symbol_ - node; \
+ } \
+ else \
+ if (value_ > node -> value) \
+ { \
+ under_ += node -> under; \
+ if (node -> right) { node += node -> right; continue; } \
+ ENET_SYMBOL_CREATE (symbol_, value_, update); \
+ node -> right = symbol_ - node; \
+ } \
+ else \
+ { \
+ count_ += node -> count; \
+ under_ += node -> under - node -> count; \
+ node -> under += update; \
+ node -> count += update; \
+ symbol_ = node; \
+ } \
+ break; \
+ } \
+ } \
+}
+
+#ifdef ENET_CONTEXT_EXCLUSION
+static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#define ENET_CONTEXT_WALK(context, body) \
+{ \
+ const ENetSymbol * node = (context) + (context) -> symbols; \
+ const ENetSymbol * stack [256]; \
+ size_t stackSize = 0; \
+ while (node -> left) \
+ { \
+ stack [stackSize ++] = node; \
+ node += node -> left; \
+ } \
+ for (;;) \
+ { \
+ body; \
+ if (node -> right) \
+ { \
+ node += node -> right; \
+ while (node -> left) \
+ { \
+ stack [stackSize ++] = node; \
+ node += node -> left; \
+ } \
+ } \
+ else \
+ if (stackSize <= 0) \
+ break; \
+ else \
+ node = stack [-- stackSize]; \
+ } \
+}
+
+#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \
+ENET_CONTEXT_WALK(context, { \
+ if (node -> value != value_) \
+ { \
+ enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \
+ if (node -> value < value_) \
+ under -= parentCount; \
+ total -= parentCount; \
+ } \
+})
+#endif
+
+size_t
+enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit)
+{
+ ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+ enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
+ const enet_uint8 * inData, * inEnd;
+ enet_uint32 encodeLow = 0, encodeRange = ~0;
+ ENetSymbol * root;
+ enet_uint16 predicted = 0;
+ size_t order = 0, nextSymbol = 0;
+
+ if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0)
+ return 0;
+
+ inData = (const enet_uint8 *) inBuffers -> data;
+ inEnd = & inData [inBuffers -> dataLength];
+ inBuffers ++;
+ inBufferCount --;
+
+ ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+ for (;;)
+ {
+ ENetSymbol * subcontext, * symbol;
+#ifdef ENET_CONTEXT_EXCLUSION
+ const ENetSymbol * childContext = & emptyContext;
+#endif
+ enet_uint8 value;
+ enet_uint16 count, under, * parent = & predicted, total;
+ if (inData >= inEnd)
+ {
+ if (inBufferCount <= 0)
+ break;
+ inData = (const enet_uint8 *) inBuffers -> data;
+ inEnd = & inData [inBuffers -> dataLength];
+ inBuffers ++;
+ inBufferCount --;
+ }
+ value = * inData ++;
+
+ for (subcontext = & rangeCoder -> symbols [predicted];
+ subcontext != root;
+#ifdef ENET_CONTEXT_EXCLUSION
+ childContext = subcontext,
+#endif
+ subcontext = & rangeCoder -> symbols [subcontext -> parent])
+ {
+ ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
+ * parent = symbol - rangeCoder -> symbols;
+ parent = & symbol -> parent;
+ total = subcontext -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+ if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
+ ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0);
+#endif
+ if (count > 0)
+ {
+ ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total);
+ }
+ else
+ {
+ if (subcontext -> escapes > 0 && subcontext -> escapes < total)
+ ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total);
+ subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
+ subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
+ }
+ subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
+ if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+ ENET_CONTEXT_RESCALE (subcontext, 0);
+ if (count > 0) goto nextInput;
+ }
+
+ ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM);
+ * parent = symbol - rangeCoder -> symbols;
+ parent = & symbol -> parent;
+ total = root -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+ if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
+ ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM);
+#endif
+ ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total);
+ root -> total += ENET_CONTEXT_SYMBOL_DELTA;
+ if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+ ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+ nextInput:
+ if (order >= ENET_SUBCONTEXT_ORDER)
+ predicted = rangeCoder -> symbols [predicted].parent;
+ else
+ order ++;
+ ENET_RANGE_CODER_FREE_SYMBOLS;
+ }
+
+ ENET_RANGE_CODER_FLUSH;
+
+ return (size_t) (outData - outStart);
+}
+
+#define ENET_RANGE_CODER_SEED \
+{ \
+ if (inData < inEnd) decodeCode |= * inData ++ << 24; \
+ if (inData < inEnd) decodeCode |= * inData ++ << 16; \
+ if (inData < inEnd) decodeCode |= * inData ++ << 8; \
+ if (inData < inEnd) decodeCode |= * inData ++; \
+}
+
+#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total)))
+
+#define ENET_RANGE_CODER_DECODE(under, count, total) \
+{ \
+ decodeLow += (under) * decodeRange; \
+ decodeRange *= (count); \
+ for (;;) \
+ { \
+ if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \
+ { \
+ if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
+ decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
+ } \
+ decodeCode <<= 8; \
+ if (inData < inEnd) \
+ decodeCode |= * inData ++; \
+ decodeRange <<= 8; \
+ decodeLow <<= 8; \
+ } \
+}
+
+#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \
+{ \
+ under_ = 0; \
+ count_ = minimum; \
+ if (! (context) -> symbols) \
+ { \
+ createRoot; \
+ } \
+ else \
+ { \
+ ENetSymbol * node = (context) + (context) -> symbols; \
+ for (;;) \
+ { \
+ enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \
+ visitNode; \
+ if (code >= after) \
+ { \
+ under_ += node -> under; \
+ if (node -> right) { node += node -> right; continue; } \
+ createRight; \
+ } \
+ else \
+ if (code < after - before) \
+ { \
+ node -> under += update; \
+ if (node -> left) { node += node -> left; continue; } \
+ createLeft; \
+ } \
+ else \
+ { \
+ value_ = node -> value; \
+ count_ += node -> count; \
+ under_ = after - before; \
+ node -> under += update; \
+ node -> count += update; \
+ symbol_ = node; \
+ } \
+ break; \
+ } \
+ } \
+}
+
+#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
+ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0)
+
+#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
+ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \
+ { \
+ value_ = code / minimum; \
+ under_ = code - code%minimum; \
+ ENET_SYMBOL_CREATE (symbol_, value_, update); \
+ (context) -> symbols = symbol_ - (context); \
+ }, \
+ exclude (node -> value, after, before), \
+ { \
+ value_ = node->value + 1 + (code - after)/minimum; \
+ under_ = code - (code - after)%minimum; \
+ ENET_SYMBOL_CREATE (symbol_, value_, update); \
+ node -> right = symbol_ - node; \
+ }, \
+ { \
+ value_ = node->value - 1 - (after - before - code - 1)/minimum; \
+ under_ = code - (after - before - code - 1)%minimum; \
+ ENET_SYMBOL_CREATE (symbol_, value_, update); \
+ node -> left = symbol_ - node; \
+ }) \
+
+#ifdef ENET_CONTEXT_EXCLUSION
+typedef struct _ENetExclude
+{
+ enet_uint8 value;
+ enet_uint16 under;
+} ENetExclude;
+
+#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \
+{ \
+ enet_uint16 under = 0; \
+ nextExclude = excludes; \
+ ENET_CONTEXT_WALK (context, { \
+ under += rangeCoder -> symbols [node -> parent].count + minimum; \
+ nextExclude -> value = node -> value; \
+ nextExclude -> under = under; \
+ nextExclude ++; \
+ }); \
+ total -= under; \
+}
+
+#define ENET_CONTEXT_EXCLUDED(value_, after, before) \
+{ \
+ size_t low = 0, high = nextExclude - excludes; \
+ for(;;) \
+ { \
+ size_t mid = (low + high) >> 1; \
+ const ENetExclude * exclude = & excludes [mid]; \
+ if (value_ < exclude -> value) \
+ { \
+ if (low + 1 < high) \
+ { \
+ high = mid; \
+ continue; \
+ } \
+ if (exclude > excludes) \
+ after -= exclude [-1].under; \
+ } \
+ else \
+ { \
+ if (value_ > exclude -> value) \
+ { \
+ if (low + 1 < high) \
+ { \
+ low = mid; \
+ continue; \
+ } \
+ } \
+ else \
+ before = 0; \
+ after -= exclude -> under; \
+ } \
+ break; \
+ } \
+}
+#endif
+
+#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before)
+
+size_t
+enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit)
+{
+ ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+ enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
+ const enet_uint8 * inEnd = & inData [inLimit];
+ enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0;
+ ENetSymbol * root;
+ enet_uint16 predicted = 0;
+ size_t order = 0, nextSymbol = 0;
+#ifdef ENET_CONTEXT_EXCLUSION
+ ENetExclude excludes [256];
+ ENetExclude * nextExclude = excludes;
+#endif
+
+ if (rangeCoder == NULL || inLimit <= 0)
+ return 0;
+
+ ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+ ENET_RANGE_CODER_SEED;
+
+ for (;;)
+ {
+ ENetSymbol * subcontext, * symbol, * patch;
+#ifdef ENET_CONTEXT_EXCLUSION
+ const ENetSymbol * childContext = & emptyContext;
+#endif
+ enet_uint8 value = 0;
+ enet_uint16 code, under, count, bottom, * parent = & predicted, total;
+
+ for (subcontext = & rangeCoder -> symbols [predicted];
+ subcontext != root;
+#ifdef ENET_CONTEXT_EXCLUSION
+ childContext = subcontext,
+#endif
+ subcontext = & rangeCoder -> symbols [subcontext -> parent])
+ {
+ if (subcontext -> escapes <= 0)
+ continue;
+ total = subcontext -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+ if (childContext -> total > 0)
+ ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0);
+#endif
+ if (subcontext -> escapes >= total)
+ continue;
+ code = ENET_RANGE_CODER_READ (total);
+ if (code < subcontext -> escapes)
+ {
+ ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total);
+ continue;
+ }
+ code -= subcontext -> escapes;
+#ifdef ENET_CONTEXT_EXCLUSION
+ if (childContext -> total > 0)
+ {
+ ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED);
+ }
+ else
+#endif
+ {
+ ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED);
+ }
+ bottom = symbol - rangeCoder -> symbols;
+ ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total);
+ subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
+ if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+ ENET_CONTEXT_RESCALE (subcontext, 0);
+ goto patchContexts;
+ }
+
+ total = root -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+ if (childContext -> total > 0)
+ ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM);
+#endif
+ code = ENET_RANGE_CODER_READ (total);
+ if (code < root -> escapes)
+ {
+ ENET_RANGE_CODER_DECODE (0, root -> escapes, total);
+ break;
+ }
+ code -= root -> escapes;
+#ifdef ENET_CONTEXT_EXCLUSION
+ if (childContext -> total > 0)
+ {
+ ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED);
+ }
+ else
+#endif
+ {
+ ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED);
+ }
+ bottom = symbol - rangeCoder -> symbols;
+ ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total);
+ root -> total += ENET_CONTEXT_SYMBOL_DELTA;
+ if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+ ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+ patchContexts:
+ for (patch = & rangeCoder -> symbols [predicted];
+ patch != subcontext;
+ patch = & rangeCoder -> symbols [patch -> parent])
+ {
+ ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
+ * parent = symbol - rangeCoder -> symbols;
+ parent = & symbol -> parent;
+ if (count <= 0)
+ {
+ patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
+ patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
+ }
+ patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
+ if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+ ENET_CONTEXT_RESCALE (patch, 0);
+ }
+ * parent = bottom;
+
+ ENET_RANGE_CODER_OUTPUT (value);
+
+ if (order >= ENET_SUBCONTEXT_ORDER)
+ predicted = rangeCoder -> symbols [predicted].parent;
+ else
+ order ++;
+ ENET_RANGE_CODER_FREE_SYMBOLS;
+ }
+
+ return (size_t) (outData - outStart);
+}
+
+/** @defgroup host ENet host functions
+ @{
+*/
+
+/** Sets the packet compressor the host should use to the default range coder.
+ @param host host to enable the range coder for
+ @returns 0 on success, < 0 on failure
+*/
+int
+enet_host_compress_with_range_coder (ENetHost * host)
+{
+ ENetCompressor compressor;
+ memset (& compressor, 0, sizeof (compressor));
+ compressor.context = enet_range_coder_create();
+ if (compressor.context == NULL)
+ return -1;
+ compressor.compress = enet_range_coder_compress;
+ compressor.decompress = enet_range_coder_decompress;
+ compressor.destroy = enet_range_coder_destroy;
+ enet_host_compress (host, & compressor);
+ return 0;
+}
+
+/** @} */
+
+
diff --git a/src/enet/design.txt b/src/enet/design.txt
new file mode 100644
index 000000000..9a88dba9f
--- /dev/null
+++ b/src/enet/design.txt
@@ -0,0 +1,117 @@
+* Why ENet?
+
+ ENet evolved specifically as a UDP networking layer for the multiplayer
+first person shooter Cube. Cube necessitated low latency communcation with
+data sent out very frequently, so TCP was an unsuitable choice due to its
+high latency and stream orientation. UDP, however, lacks many sometimes
+necessary features from TCP such as reliability, sequencing, unrestricted
+packet sizes, and connection management. So UDP by itself was not suitable
+as a network protocol either. No suitable freely available networking
+libraries existed at the time of ENet's creation to fill this niche.
+
+ UDP and TCP could have been used together in Cube to benefit somewhat
+from both of their features, however, the resulting combinations of protocols
+still leaves much to be desired. TCP lacks multiple streams of communication
+without resorting to opening many sockets and complicates delineation of
+packets due to its buffering behavior. UDP lacks sequencing, connection
+management, management of bandwidth resources, and imposes limitations on
+the size of packets. A significant investment is required to integrate these
+two protocols, and the end result is worse off in features and performance
+than the uniform protocol presented by ENet.
+
+ ENet thus attempts to address these issues and provide a single, uniform
+protocol layered over UDP to the developer with the best features of UDP and
+TCP as well as some useful features neither provide, with a much cleaner
+integration than any resulting from a mixture of UDP and TCP.
+
+* Connection management
+
+ ENet provides a simple connection interface over which to communicate
+with a foreign host. The liveness of the connection is actively monitored
+by pinging the foreign host at frequent intervals, and also monitors the
+network conditions from the local host to the foreign host such as the
+mean round trip time and packet loss in this fashion.
+
+* Sequencing
+
+ Rather than a single byte stream that complicates the delineation
+of packets, ENet presents connections as multiple, properly sequenced packet
+streams that simplify the transfer of various types of data.
+
+ ENet provides sequencing for all packets by assigning to each sent
+packet a sequence number that is incremented as packets are sent. ENet
+guarentees that no packet with a higher sequence number will be delivered
+before a packet with a lower sequence number, thus ensuring packets are
+delivered exactly in the order they are sent.
+
+ For unreliable packets, ENet will simply discard the lower sequence
+number packet if a packet with a higher sequence number has already been
+delivered. This allows the packets to be dispatched immediately as they
+arrive, and reduce latency of unreliable packets to an absolute minimum.
+For reliable packets, if a higher sequence number packet arrives, but the
+preceding packets in the sequence have not yet arrived, ENet will stall
+delivery of the higher sequence number packets until its predecessors
+have arrived.
+
+* Channels
+
+ Since ENet will stall delivery of reliable packets to ensure proper
+sequencing, and consequently any packets of higher sequence number whether
+reliable or unreliable, in the event the reliable packet's predecessors
+have not yet arrived, this can introduce latency into the delivery of other
+packets which may not need to be as strictly ordered with respect to the
+packet that stalled their delivery.
+
+ To combat this latency and reduce the ordering restrictions on packets,
+ENet provides multiple channels of communication over a given connection.
+Each channel is independently sequenced, and so the delivery status of
+a packet in one channel will not stall the delivery of other packets
+in another channel.
+
+* Reliability
+
+ ENet provides optional reliability of packet delivery by ensuring the
+foreign host acknowledges receipt of all reliable packets. ENet will attempt
+to resend the packet up to a reasonable amount of times, if no acknowledgement
+of the packet's receipt happens within a specified timeout. Retry timeouts
+are progressive and become more lenient with every failed attempt to allow
+for temporary turbulence in network conditions.
+
+* Fragmentation and reassembly
+
+ ENet will send and deliver packets regardless of size. Large packets are
+fragmented into many smaller packets of suitable size, and reassembled on
+the foreign host to recover the original packet for delivery. The process
+is entirely transparent to the developer.
+
+* Aggregation
+
+ ENet aggregates all protocol commands, including acknowledgements and
+packet transfer, into larger protocol packets to ensure the proper utilization
+of the connection and to limit the opportunities for packet loss that might
+otherwise result in further delivery latency.
+
+* Adaptability
+
+ ENet provides an in-flight data window for reliable packets to ensure
+connections are not overwhelmed by volumes of packets. It also provides a
+static bandwidth allocation mechanism to ensure the total volume of packets
+sent and received to a host don't exceed the host's capabilities. Further,
+ENet also provides a dynamic throttle that responds to deviations from normal
+network connections to rectify various types of network congestion by further
+limiting the volume of packets sent.
+
+* Portability
+
+ ENet works on Windows and any other Unix or Unix-like platform providing
+a BSD sockets interface. The library has a small and stable code base that
+can easily be extended to support other platforms and integrates easily.
+
+* Freedom
+
+ ENet demands no royalties and doesn't carry a viral license that would
+restrict you in how you might use it in your programs. ENet is licensed under
+a short-and-sweet MIT-style license, which gives you the freedom to do anything
+you want with it (well, almost anything).
+
+
diff --git a/src/enet/enet.h b/src/enet/enet.h
new file mode 100644
index 000000000..2f656d6cb
--- /dev/null
+++ b/src/enet/enet.h
@@ -0,0 +1,540 @@
+/**
+ @file enet.h
+ @brief ENet public header file
+*/
+#ifndef __ENET_ENET_H__
+#define __ENET_ENET_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+
+#ifdef WIN32
+#include "enet/win32.h"
+#else
+#include "enet/unix.h"
+#endif
+
+#include "enet/types.h"
+#include "enet/protocol.h"
+#include "enet/list.h"
+#include "enet/callbacks.h"
+
+#define ENET_VERSION_MAJOR 1
+#define ENET_VERSION_MINOR 3
+#define ENET_VERSION_PATCH 0
+#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
+#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
+
+typedef enet_uint32 ENetVersion;
+
+typedef enum _ENetSocketType
+{
+ ENET_SOCKET_TYPE_STREAM = 1,
+ ENET_SOCKET_TYPE_DATAGRAM = 2
+} ENetSocketType;
+
+typedef enum _ENetSocketWait
+{
+ ENET_SOCKET_WAIT_NONE = 0,
+ ENET_SOCKET_WAIT_SEND = (1 << 0),
+ ENET_SOCKET_WAIT_RECEIVE = (1 << 1)
+} ENetSocketWait;
+
+typedef enum _ENetSocketOption
+{
+ ENET_SOCKOPT_NONBLOCK = 1,
+ ENET_SOCKOPT_BROADCAST = 2,
+ ENET_SOCKOPT_RCVBUF = 3,
+ ENET_SOCKOPT_SNDBUF = 4,
+ ENET_SOCKOPT_REUSEADDR = 5
+} ENetSocketOption;
+
+enum
+{
+ ENET_HOST_ANY = 0, /**< specifies the default server host */
+ ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */
+
+ ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
+};
+
+/**
+ * Portable internet address structure.
+ *
+ * The host must be specified in network byte-order, and the port must be in host
+ * byte-order. The constant ENET_HOST_ANY may be used to specify the default
+ * server host. The constant ENET_HOST_BROADCAST may be used to specify the
+ * broadcast address (255.255.255.255). This makes sense for enet_host_connect,
+ * but not for enet_host_create. Once a server responds to a broadcast, the
+ * address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
+ */
+typedef struct _ENetAddress
+{
+ enet_uint32 host;
+ enet_uint16 port;
+} ENetAddress;
+
+/**
+ * Packet flag bit constants.
+ *
+ * The host must be specified in network byte-order, and the port must be in
+ * host byte-order. The constant ENET_HOST_ANY may be used to specify the
+ * default server host.
+
+ @sa ENetPacket
+*/
+typedef enum _ENetPacketFlag
+{
+ /** packet must be received by the target peer and resend attempts should be
+ * made until the packet is delivered */
+ ENET_PACKET_FLAG_RELIABLE = (1 << 0),
+ /** packet will not be sequenced with other packets
+ * not supported for reliable packets
+ */
+ ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
+ /** packet will not allocate data, and user must supply it instead */
+ ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
+} ENetPacketFlag;
+
+struct _ENetPacket;
+typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
+
+/**
+ * ENet packet structure.
+ *
+ * An ENet data packet that may be sent to or received from a peer. The shown
+ * fields should only be read and never modified. The data field contains the
+ * allocated data for the packet. The dataLength fields specifies the length
+ * of the allocated data. The flags field is either 0 (specifying no flags),
+ * or a bitwise-or of any combination of the following flags:
+ *
+ * ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
+ * and resend attempts should be made until the packet is delivered
+ *
+ * ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets
+ * (not supported for reliable packets)
+ *
+ * ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
+
+ @sa ENetPacketFlag
+ */
+typedef struct _ENetPacket
+{
+ size_t referenceCount; /**< internal use only */
+ enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */
+ enet_uint8 * data; /**< allocated data for packet */
+ size_t dataLength; /**< length of data */
+ ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
+} ENetPacket;
+
+typedef struct _ENetAcknowledgement
+{
+ ENetListNode acknowledgementList;
+ enet_uint32 sentTime;
+ ENetProtocol command;
+} ENetAcknowledgement;
+
+typedef struct _ENetOutgoingCommand
+{
+ ENetListNode outgoingCommandList;
+ enet_uint16 reliableSequenceNumber;
+ enet_uint16 unreliableSequenceNumber;
+ enet_uint32 sentTime;
+ enet_uint32 roundTripTimeout;
+ enet_uint32 roundTripTimeoutLimit;
+ enet_uint32 fragmentOffset;
+ enet_uint16 fragmentLength;
+ enet_uint16 sendAttempts;
+ ENetProtocol command;
+ ENetPacket * packet;
+} ENetOutgoingCommand;
+
+typedef struct _ENetIncomingCommand
+{
+ ENetListNode incomingCommandList;
+ enet_uint16 reliableSequenceNumber;
+ enet_uint16 unreliableSequenceNumber;
+ ENetProtocol command;
+ enet_uint32 fragmentCount;
+ enet_uint32 fragmentsRemaining;
+ enet_uint32 * fragments;
+ ENetPacket * packet;
+} ENetIncomingCommand;
+
+typedef enum _ENetPeerState
+{
+ ENET_PEER_STATE_DISCONNECTED = 0,
+ ENET_PEER_STATE_CONNECTING = 1,
+ ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
+ ENET_PEER_STATE_CONNECTION_PENDING = 3,
+ ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4,
+ ENET_PEER_STATE_CONNECTED = 5,
+ ENET_PEER_STATE_DISCONNECT_LATER = 6,
+ ENET_PEER_STATE_DISCONNECTING = 7,
+ ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8,
+ ENET_PEER_STATE_ZOMBIE = 9
+} ENetPeerState;
+
+#ifndef ENET_BUFFER_MAXIMUM
+#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
+#endif
+
+enum
+{
+ ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
+ ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
+ ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
+ ENET_HOST_DEFAULT_MTU = 1400,
+
+ ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500,
+ ENET_PEER_DEFAULT_PACKET_THROTTLE = 32,
+ ENET_PEER_PACKET_THROTTLE_SCALE = 32,
+ ENET_PEER_PACKET_THROTTLE_COUNTER = 7,
+ ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
+ ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
+ ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000,
+ ENET_PEER_PACKET_LOSS_SCALE = (1 << 16),
+ ENET_PEER_PACKET_LOSS_INTERVAL = 10000,
+ ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024,
+ ENET_PEER_TIMEOUT_LIMIT = 32,
+ ENET_PEER_TIMEOUT_MINIMUM = 5000,
+ ENET_PEER_TIMEOUT_MAXIMUM = 30000,
+ ENET_PEER_PING_INTERVAL = 500,
+ ENET_PEER_UNSEQUENCED_WINDOWS = 64,
+ ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024,
+ ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32,
+ ENET_PEER_RELIABLE_WINDOWS = 16,
+ ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000,
+ ENET_PEER_FREE_RELIABLE_WINDOWS = 8
+};
+
+typedef struct _ENetChannel
+{
+ enet_uint16 outgoingReliableSequenceNumber;
+ enet_uint16 outgoingUnreliableSequenceNumber;
+ enet_uint16 usedReliableWindows;
+ enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
+ enet_uint16 incomingReliableSequenceNumber;
+ ENetList incomingReliableCommands;
+ ENetList incomingUnreliableCommands;
+} ENetChannel;
+
+/**
+ * An ENet peer which data packets may be sent or received from.
+ *
+ * No fields should be modified unless otherwise specified.
+ */
+typedef struct _ENetPeer
+{
+ ENetListNode dispatchList;
+ struct _ENetHost * host;
+ enet_uint16 outgoingPeerID;
+ enet_uint16 incomingPeerID;
+ enet_uint32 connectID;
+ enet_uint8 outgoingSessionID;
+ enet_uint8 incomingSessionID;
+ ENetAddress address; /**< Internet address of the peer */
+ void * data; /**< Application private data, may be freely modified */
+ ENetPeerState state;
+ ENetChannel * channels;
+ size_t channelCount; /**< Number of channels allocated for communication with peer */
+ enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */
+ enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */
+ enet_uint32 incomingBandwidthThrottleEpoch;
+ enet_uint32 outgoingBandwidthThrottleEpoch;
+ enet_uint32 incomingDataTotal;
+ enet_uint32 outgoingDataTotal;
+ enet_uint32 lastSendTime;
+ enet_uint32 lastReceiveTime;
+ enet_uint32 nextTimeout;
+ enet_uint32 earliestTimeout;
+ enet_uint32 packetLossEpoch;
+ enet_uint32 packetsSent;
+ enet_uint32 packetsLost;
+ enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
+ enet_uint32 packetLossVariance;
+ enet_uint32 packetThrottle;
+ enet_uint32 packetThrottleLimit;
+ enet_uint32 packetThrottleCounter;
+ enet_uint32 packetThrottleEpoch;
+ enet_uint32 packetThrottleAcceleration;
+ enet_uint32 packetThrottleDeceleration;
+ enet_uint32 packetThrottleInterval;
+ enet_uint32 lastRoundTripTime;
+ enet_uint32 lowestRoundTripTime;
+ enet_uint32 lastRoundTripTimeVariance;
+ enet_uint32 highestRoundTripTimeVariance;
+ enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
+ enet_uint32 roundTripTimeVariance;
+ enet_uint32 mtu;
+ enet_uint32 windowSize;
+ enet_uint32 reliableDataInTransit;
+ enet_uint16 outgoingReliableSequenceNumber;
+ ENetList acknowledgements;
+ ENetList sentReliableCommands;
+ ENetList sentUnreliableCommands;
+ ENetList outgoingReliableCommands;
+ ENetList outgoingUnreliableCommands;
+ ENetList dispatchedCommands;
+ int needsDispatch;
+ enet_uint16 incomingUnsequencedGroup;
+ enet_uint16 outgoingUnsequencedGroup;
+ enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
+ enet_uint32 eventData;
+} ENetPeer;
+
+/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
+ */
+typedef struct _ENetCompressor
+{
+ /** Context data for the compressor. Must be non-NULL. */
+ void * context;
+ /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
+ size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit);
+ /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
+ size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit);
+ /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
+ void (ENET_CALLBACK * destroy) (void * context);
+} ENetCompressor;
+
+/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
+typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount);
+
+/** An ENet host for communicating with peers.
+ *
+ * No fields should be modified unless otherwise stated.
+
+ @sa enet_host_create()
+ @sa enet_host_destroy()
+ @sa enet_host_connect()
+ @sa enet_host_service()
+ @sa enet_host_flush()
+ @sa enet_host_broadcast()
+ @sa enet_host_compress()
+ @sa enet_host_compress_with_range_coder()
+ @sa enet_host_channel_limit()
+ @sa enet_host_bandwidth_limit()
+ @sa enet_host_bandwidth_throttle()
+ */
+typedef struct _ENetHost
+{
+ ENetSocket socket;
+ ENetAddress address; /**< Internet address of the host */
+ enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
+ enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
+ enet_uint32 bandwidthThrottleEpoch;
+ enet_uint32 mtu;
+ enet_uint32 randomSeed;
+ int recalculateBandwidthLimits;
+ ENetPeer * peers; /**< array of peers allocated for this host */
+ size_t peerCount; /**< number of peers allocated for this host */
+ size_t channelLimit; /**< maximum number of channels allowed for connected peers */
+ enet_uint32 serviceTime;
+ ENetList dispatchQueue;
+ int continueSending;
+ size_t packetSize;
+ enet_uint16 headerFlags;
+ ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
+ size_t commandCount;
+ ENetBuffer buffers [ENET_BUFFER_MAXIMUM];
+ size_t bufferCount;
+ ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
+ ENetCompressor compressor;
+ enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
+ ENetAddress receivedAddress;
+ enet_uint8 * receivedData;
+ size_t receivedDataLength;
+ enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
+ enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
+ enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */
+ enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
+} ENetHost;
+
+/**
+ * An ENet event type, as specified in @ref ENetEvent.
+ */
+typedef enum _ENetEventType
+{
+ /** no event occurred within the specified time limit */
+ ENET_EVENT_TYPE_NONE = 0,
+
+ /** a connection request initiated by enet_host_connect has completed.
+ * The peer field contains the peer which successfully connected.
+ */
+ ENET_EVENT_TYPE_CONNECT = 1,
+
+ /** a peer has disconnected. This event is generated on a successful
+ * completion of a disconnect initiated by enet_pper_disconnect, if
+ * a peer has timed out, or if a connection request intialized by
+ * enet_host_connect has timed out. The peer field contains the peer
+ * which disconnected. The data field contains user supplied data
+ * describing the disconnection, or 0, if none is available.
+ */
+ ENET_EVENT_TYPE_DISCONNECT = 2,
+
+ /** a packet has been received from a peer. The peer field specifies the
+ * peer which sent the packet. The channelID field specifies the channel
+ * number upon which the packet was received. The packet field contains
+ * the packet that was received; this packet must be destroyed with
+ * enet_packet_destroy after use.
+ */
+ ENET_EVENT_TYPE_RECEIVE = 3
+} ENetEventType;
+
+/**
+ * An ENet event as returned by enet_host_service().
+
+ @sa enet_host_service
+ */
+typedef struct _ENetEvent
+{
+ ENetEventType type; /**< type of the event */
+ ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */
+ enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */
+ enet_uint32 data; /**< data associated with the event, if appropriate */
+ ENetPacket * packet; /**< packet associated with the event, if appropriate */
+} ENetEvent;
+
+/** @defgroup global ENet global functions
+ @{
+*/
+
+/**
+ Initializes ENet globally. Must be called prior to using any functions in
+ ENet.
+ @returns 0 on success, < 0 on failure
+*/
+ENET_API int enet_initialize (void);
+
+/**
+ Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored.
+
+ @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
+ @param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults
+ @returns 0 on success, < 0 on failure
+*/
+ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
+
+/**
+ Shuts down ENet globally. Should be called when a program that has
+ initialized ENet exits.
+*/
+ENET_API void enet_deinitialize (void);
+
+/** @} */
+
+/** @defgroup private ENet private implementation functions */
+
+/**
+ Returns the wall-time in milliseconds. Its initial value is unspecified
+ unless otherwise set.
+ */
+ENET_API enet_uint32 enet_time_get (void);
+/**
+ Sets the current wall-time in milliseconds.
+ */
+ENET_API void enet_time_set (enet_uint32);
+
+/** @defgroup socket ENet socket functions
+ @{
+*/
+ENET_API ENetSocket enet_socket_create (ENetSocketType);
+ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
+ENET_API int enet_socket_listen (ENetSocket, int);
+ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
+ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
+ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
+ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
+ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
+ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
+ENET_API void enet_socket_destroy (ENetSocket);
+ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
+
+/** @} */
+
+/** @defgroup Address ENet address functions
+ @{
+*/
+/** Attempts to resolve the host named by the parameter hostName and sets
+ the host field in the address parameter if successful.
+ @param address destination to store resolved address
+ @param hostName host name to lookup
+ @retval 0 on success
+ @retval < 0 on failure
+ @returns the address of the given hostName in address on success
+*/
+ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
+
+/** Gives the printable form of the ip address specified in the address parameter.
+ @param address address printed
+ @param hostName destination for name, must not be NULL
+ @param nameLength maximum length of hostName.
+ @returns the null-terminated name of the host in hostName on success
+ @retval 0 on success
+ @retval < 0 on failure
+*/
+ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
+
+/** Attempts to do a reverse lookup of the host field in the address parameter.
+ @param address address used for reverse lookup
+ @param hostName destination for name, must not be NULL
+ @param nameLength maximum length of hostName.
+ @returns the null-terminated name of the host in hostName on success
+ @retval 0 on success
+ @retval < 0 on failure
+*/
+ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
+
+/** @} */
+
+ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
+ENET_API void enet_packet_destroy (ENetPacket *);
+ENET_API int enet_packet_resize (ENetPacket *, size_t);
+extern enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
+
+ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
+ENET_API void enet_host_destroy (ENetHost *);
+ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
+ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
+ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
+ENET_API void enet_host_flush (ENetHost *);
+ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
+ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
+ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
+ENET_API void enet_host_channel_limit (ENetHost *, size_t);
+ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
+extern void enet_host_bandwidth_throttle (ENetHost *);
+
+ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
+ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
+ENET_API void enet_peer_ping (ENetPeer *);
+ENET_API void enet_peer_reset (ENetPeer *);
+ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32);
+ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32);
+ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32);
+ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
+extern int enet_peer_throttle (ENetPeer *, enet_uint32);
+extern void enet_peer_reset_queues (ENetPeer *);
+extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
+extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
+extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32);
+extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
+extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
+extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
+
+ENET_API void * enet_range_coder_create (void);
+ENET_API void enet_range_coder_destroy (void *);
+ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t);
+ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t);
+
+extern size_t enet_protocol_command_size (enet_uint8);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ENET_ENET_H__ */
+
diff --git a/src/enet/host.c b/src/enet/host.c
new file mode 100644
index 000000000..8bb2433fe
--- /dev/null
+++ b/src/enet/host.c
@@ -0,0 +1,479 @@
+/**
+ @file host.c
+ @brief ENet host management functions
+*/
+#define ENET_BUILDING_LIB 1
+#include <string.h>
+#include <time.h>
+#include "enet/enet.h"
+
+/** @defgroup host ENet host functions
+ @{
+*/
+
+/** Creates a host for communicating to peers.
+
+ @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
+ @param peerCount the maximum number of peers that should be allocated for the host.
+ @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
+ @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+ @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+
+ @returns the host on success and NULL on failure
+
+ @remarks ENet will strategically drop packets on specific sides of a connection between hosts
+ to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
+ the window size of a connection which limits the amount of reliable packets that may be in transit
+ at any given time.
+*/
+ENetHost *
+enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+ ENetHost * host;
+ ENetPeer * currentPeer;
+
+ if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
+ return NULL;
+
+ host = (ENetHost *) enet_malloc (sizeof (ENetHost));
+ if (host == NULL)
+ return NULL;
+
+ host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
+ if (host -> peers == NULL)
+ {
+ enet_free (host);
+
+ return NULL;
+ }
+ memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
+
+ host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
+ if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
+ {
+ if (host -> socket != ENET_SOCKET_NULL)
+ enet_socket_destroy (host -> socket);
+
+ enet_free (host -> peers);
+ enet_free (host);
+
+ return NULL;
+ }
+
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
+
+ if (address != NULL)
+ host -> address = * address;
+
+ if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+ channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+ else
+ if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+ channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+
+ host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
+ host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
+ host -> channelLimit = channelLimit;
+ host -> incomingBandwidth = incomingBandwidth;
+ host -> outgoingBandwidth = outgoingBandwidth;
+ host -> bandwidthThrottleEpoch = 0;
+ host -> recalculateBandwidthLimits = 0;
+ host -> mtu = ENET_HOST_DEFAULT_MTU;
+ host -> peerCount = peerCount;
+ host -> commandCount = 0;
+ host -> bufferCount = 0;
+ host -> checksum = NULL;
+ host -> receivedAddress.host = ENET_HOST_ANY;
+ host -> receivedAddress.port = 0;
+ host -> receivedData = NULL;
+ host -> receivedDataLength = 0;
+
+ host -> totalSentData = 0;
+ host -> totalSentPackets = 0;
+ host -> totalReceivedData = 0;
+ host -> totalReceivedPackets = 0;
+
+ host -> compressor.context = NULL;
+ host -> compressor.compress = NULL;
+ host -> compressor.decompress = NULL;
+ host -> compressor.destroy = NULL;
+
+ enet_list_clear (& host -> dispatchQueue);
+
+ for (currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
+ currentPeer -> host = host;
+ currentPeer -> incomingPeerID = currentPeer - host -> peers;
+ currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
+ currentPeer -> data = NULL;
+
+ enet_list_clear (& currentPeer -> acknowledgements);
+ enet_list_clear (& currentPeer -> sentReliableCommands);
+ enet_list_clear (& currentPeer -> sentUnreliableCommands);
+ enet_list_clear (& currentPeer -> outgoingReliableCommands);
+ enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
+ enet_list_clear (& currentPeer -> dispatchedCommands);
+
+ enet_peer_reset (currentPeer);
+ }
+
+ return host;
+}
+
+/** Destroys the host and all resources associated with it.
+ @param host pointer to the host to destroy
+*/
+void
+enet_host_destroy (ENetHost * host)
+{
+ ENetPeer * currentPeer;
+
+ enet_socket_destroy (host -> socket);
+
+ for (currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
+ enet_peer_reset (currentPeer);
+ }
+
+ if (host -> compressor.context != NULL && host -> compressor.destroy)
+ (* host -> compressor.destroy) (host -> compressor.context);
+
+ enet_free (host -> peers);
+ enet_free (host);
+}
+
+/** Initiates a connection to a foreign host.
+ @param host host seeking the connection
+ @param address destination for the connection
+ @param channelCount number of channels to allocate
+ @param data user data supplied to the receiving host
+ @returns a peer representing the foreign host on success, NULL on failure
+ @remarks The peer returned will have not completed the connection until enet_host_service()
+ notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
+*/
+ENetPeer *
+enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
+{
+ ENetPeer * currentPeer;
+ ENetChannel * channel;
+ ENetProtocol command;
+
+ if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+ channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+ else
+ if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+ channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+
+ for (currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
+ if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
+ break;
+ }
+
+ if (currentPeer >= & host -> peers [host -> peerCount])
+ return NULL;
+
+ currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
+ if (currentPeer -> channels == NULL)
+ return NULL;
+ currentPeer -> channelCount = channelCount;
+ currentPeer -> state = ENET_PEER_STATE_CONNECTING;
+ currentPeer -> address = * address;
+ currentPeer -> connectID = ++ host -> randomSeed;
+
+ if (host -> outgoingBandwidth == 0)
+ currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+ else
+ currentPeer -> windowSize = (host -> outgoingBandwidth /
+ ENET_PEER_WINDOW_SIZE_SCALE) *
+ ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+ if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+ currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+ else
+ if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+ currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+ for (channel = currentPeer -> channels;
+ channel < & currentPeer -> channels [channelCount];
+ ++ channel)
+ {
+ channel -> outgoingReliableSequenceNumber = 0;
+ channel -> outgoingUnreliableSequenceNumber = 0;
+ channel -> incomingReliableSequenceNumber = 0;
+
+ enet_list_clear (& channel -> incomingReliableCommands);
+ enet_list_clear (& channel -> incomingUnreliableCommands);
+
+ channel -> usedReliableWindows = 0;
+ memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
+ }
+
+ command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ command.header.channelID = 0xFF;
+ command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
+ command.connect.incomingSessionID = currentPeer -> incomingSessionID;
+ command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
+ command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
+ command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
+ command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
+ command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
+ command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+ command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
+ command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
+ command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
+ command.connect.connectID = currentPeer -> connectID;
+ command.connect.data = ENET_HOST_TO_NET_32 (data);
+
+ enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
+
+ return currentPeer;
+}
+
+/** Queues a packet to be sent to all peers associated with the host.
+ @param host host on which to broadcast the packet
+ @param channelID channel on which to broadcast
+ @param packet packet to broadcast
+*/
+void
+enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
+{
+ ENetPeer * currentPeer;
+
+ for (currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
+ if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
+ continue;
+
+ enet_peer_send (currentPeer, channelID, packet);
+ }
+
+ if (packet -> referenceCount == 0)
+ enet_packet_destroy (packet);
+}
+
+/** Sets the packet compressor the host should use to compress and decompress packets.
+ @param host host to enable or disable compression for
+ @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
+*/
+void
+enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
+{
+ if (host -> compressor.context != NULL && host -> compressor.destroy)
+ (* host -> compressor.destroy) (host -> compressor.context);
+
+ if (compressor)
+ host -> compressor = * compressor;
+ else
+ host -> compressor.context = NULL;
+}
+
+/** Limits the maximum allowed channels of future incoming connections.
+ @param host host to limit
+ @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
+*/
+void
+enet_host_channel_limit (ENetHost * host, size_t channelLimit)
+{
+ if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+ channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+ else
+ if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+ channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+
+ host -> channelLimit = channelLimit;
+}
+
+
+/** Adjusts the bandwidth limits of a host.
+ @param host host to adjust
+ @param incomingBandwidth new incoming bandwidth
+ @param outgoingBandwidth new outgoing bandwidth
+ @remarks the incoming and outgoing bandwidth parameters are identical in function to those
+ specified in enet_host_create().
+*/
+void
+enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+ host -> incomingBandwidth = incomingBandwidth;
+ host -> outgoingBandwidth = outgoingBandwidth;
+ host -> recalculateBandwidthLimits = 1;
+}
+
+void
+enet_host_bandwidth_throttle (ENetHost * host)
+{
+ enet_uint32 timeCurrent = enet_time_get (),
+ elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
+ peersTotal = 0,
+ dataTotal = 0,
+ peersRemaining,
+ bandwidth,
+ throttle = 0,
+ bandwidthLimit = 0;
+ int needsAdjustment;
+ ENetPeer * peer;
+ ENetProtocol command;
+
+ if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
+ return;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+ continue;
+
+ ++ peersTotal;
+ dataTotal += peer -> outgoingDataTotal;
+ }
+
+ if (peersTotal == 0)
+ return;
+
+ peersRemaining = peersTotal;
+ needsAdjustment = 1;
+
+ if (host -> outgoingBandwidth == 0)
+ bandwidth = ~0;
+ else
+ bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
+
+ while (peersRemaining > 0 && needsAdjustment != 0)
+ {
+ needsAdjustment = 0;
+
+ if (dataTotal < bandwidth)
+ throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
+ else
+ throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ enet_uint32 peerBandwidth;
+
+ if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+ peer -> incomingBandwidth == 0 ||
+ peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+ continue;
+
+ peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
+ if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
+ continue;
+
+ peer -> packetThrottleLimit = (peerBandwidth *
+ ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
+
+ if (peer -> packetThrottleLimit == 0)
+ peer -> packetThrottleLimit = 1;
+
+ if (peer -> packetThrottle > peer -> packetThrottleLimit)
+ peer -> packetThrottle = peer -> packetThrottleLimit;
+
+ peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
+
+
+ needsAdjustment = 1;
+ -- peersRemaining;
+ bandwidth -= peerBandwidth;
+ dataTotal -= peerBandwidth;
+ }
+ }
+
+ if (peersRemaining > 0)
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+ peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+ continue;
+
+ peer -> packetThrottleLimit = throttle;
+
+ if (peer -> packetThrottle > peer -> packetThrottleLimit)
+ peer -> packetThrottle = peer -> packetThrottleLimit;
+ }
+
+ if (host -> recalculateBandwidthLimits)
+ {
+ host -> recalculateBandwidthLimits = 0;
+
+ peersRemaining = peersTotal;
+ bandwidth = host -> incomingBandwidth;
+ needsAdjustment = 1;
+
+ if (bandwidth == 0)
+ bandwidthLimit = 0;
+ else
+ while (peersRemaining > 0 && needsAdjustment != 0)
+ {
+ needsAdjustment = 0;
+ bandwidthLimit = bandwidth / peersRemaining;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+ peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+ continue;
+
+ if (peer -> outgoingBandwidth > 0 &&
+ peer -> outgoingBandwidth >= bandwidthLimit)
+ continue;
+
+ peer -> incomingBandwidthThrottleEpoch = timeCurrent;
+
+ needsAdjustment = 1;
+ -- peersRemaining;
+ bandwidth -= peer -> outgoingBandwidth;
+ }
+ }
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+ continue;
+
+ command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ command.header.channelID = 0xFF;
+ command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+
+ if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+ command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
+ else
+ command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
+
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+ }
+ }
+
+ host -> bandwidthThrottleEpoch = timeCurrent;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ peer -> incomingDataTotal = 0;
+ peer -> outgoingDataTotal = 0;
+ }
+}
+
+/** @} */
diff --git a/src/enet/list.c b/src/enet/list.c
new file mode 100644
index 000000000..8487200ff
--- /dev/null
+++ b/src/enet/list.c
@@ -0,0 +1,75 @@
+/**
+ @file list.c
+ @brief ENet linked list functions
+*/
+#define ENET_BUILDING_LIB 1
+#include "enet/list.h"
+
+/**
+ @defgroup list ENet linked list utility functions
+ @ingroup private
+ @{
+*/
+void
+enet_list_clear (ENetList * list)
+{
+ list -> sentinel.next = & list -> sentinel;
+ list -> sentinel.previous = & list -> sentinel;
+}
+
+ENetListIterator
+enet_list_insert (ENetListIterator position, void * data)
+{
+ ENetListIterator result = (ENetListIterator) data;
+
+ result -> previous = position -> previous;
+ result -> next = position;
+
+ result -> previous -> next = result;
+ position -> previous = result;
+
+ return result;
+}
+
+void *
+enet_list_remove (ENetListIterator position)
+{
+ position -> previous -> next = position -> next;
+ position -> next -> previous = position -> previous;
+
+ return position;
+}
+
+ENetListIterator
+enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
+{
+ ENetListIterator first = (ENetListIterator) dataFirst,
+ last = (ENetListIterator) dataLast;
+
+ first -> previous -> next = last -> next;
+ last -> next -> previous = first -> previous;
+
+ first -> previous = position -> previous;
+ last -> next = position;
+
+ first -> previous -> next = first;
+ position -> previous = last;
+
+ return first;
+}
+
+size_t
+enet_list_size (ENetList * list)
+{
+ size_t size = 0;
+ ENetListIterator position;
+
+ for (position = enet_list_begin (list);
+ position != enet_list_end (list);
+ position = enet_list_next (position))
+ ++ size;
+
+ return size;
+}
+
+/** @} */
diff --git a/src/enet/list.h b/src/enet/list.h
new file mode 100644
index 000000000..d7b260084
--- /dev/null
+++ b/src/enet/list.h
@@ -0,0 +1,43 @@
+/**
+ @file list.h
+ @brief ENet list management
+*/
+#ifndef __ENET_LIST_H__
+#define __ENET_LIST_H__
+
+#include <stdlib.h>
+
+typedef struct _ENetListNode
+{
+ struct _ENetListNode * next;
+ struct _ENetListNode * previous;
+} ENetListNode;
+
+typedef ENetListNode * ENetListIterator;
+
+typedef struct _ENetList
+{
+ ENetListNode sentinel;
+} ENetList;
+
+extern void enet_list_clear (ENetList *);
+
+extern ENetListIterator enet_list_insert (ENetListIterator, void *);
+extern void * enet_list_remove (ENetListIterator);
+extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
+
+extern size_t enet_list_size (ENetList *);
+
+#define enet_list_begin(list) ((list) -> sentinel.next)
+#define enet_list_end(list) (& (list) -> sentinel)
+
+#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
+
+#define enet_list_next(iterator) ((iterator) -> next)
+#define enet_list_previous(iterator) ((iterator) -> previous)
+
+#define enet_list_front(list) ((void *) (list) -> sentinel.next)
+#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
+
+#endif /* __ENET_LIST_H__ */
+
diff --git a/src/enet/packet.c b/src/enet/packet.c
new file mode 100644
index 000000000..d6730dd33
--- /dev/null
+++ b/src/enet/packet.c
@@ -0,0 +1,159 @@
+/**
+ @file packet.c
+ @brief ENet packet management functions
+*/
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+/** @defgroup Packet ENet packet functions
+ @{
+*/
+
+/** Creates a packet that may be sent to a peer.
+ @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
+ @param dataLength size of the data allocated for this packet
+ @param flags flags for this packet as described for the ENetPacket structure.
+ @returns the packet on success, NULL on failure
+*/
+ENetPacket *
+enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
+{
+ ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
+ if (packet == NULL)
+ return NULL;
+
+ if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
+ packet -> data = (enet_uint8 *) data;
+ else
+ {
+ packet -> data = (enet_uint8 *) enet_malloc (dataLength);
+ if (packet -> data == NULL)
+ {
+ enet_free (packet);
+ return NULL;
+ }
+
+ if (data != NULL)
+ memcpy (packet -> data, data, dataLength);
+ }
+
+ packet -> referenceCount = 0;
+ packet -> flags = flags;
+ packet -> dataLength = dataLength;
+ packet -> freeCallback = NULL;
+
+ return packet;
+}
+
+/** Destroys the packet and deallocates its data.
+ @param packet packet to be destroyed
+*/
+void
+enet_packet_destroy (ENetPacket * packet)
+{
+ if (packet -> freeCallback != NULL)
+ (* packet -> freeCallback) (packet);
+ if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+ enet_free (packet -> data);
+ enet_free (packet);
+}
+
+/** Attempts to resize the data in the packet to length specified in the
+ dataLength parameter
+ @param packet packet to resize
+ @param dataLength new size for the packet data
+ @returns 0 on success, < 0 on failure
+*/
+int
+enet_packet_resize (ENetPacket * packet, size_t dataLength)
+{
+ enet_uint8 * newData;
+
+ if (dataLength <= packet -> dataLength
+ || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+ {
+ packet -> dataLength = dataLength;
+
+ return 0;
+ }
+
+ newData = (enet_uint8 *) enet_malloc (dataLength);
+ if (newData == NULL)
+ return -1;
+
+ memcpy (newData, packet -> data, packet -> dataLength);
+ enet_free (packet -> data);
+
+ packet -> data = newData;
+ packet -> dataLength = dataLength;
+
+ return 0;
+}
+
+static int initializedCRC32 = 0;
+static enet_uint32 crcTable [256];
+
+static enet_uint32
+reflect_crc (int val, int bits)
+{
+ int result = 0, bit;
+
+ for (bit = 0; bit < bits; bit ++)
+ {
+ if (val & 1)
+ result |= 1 << (bits - 1 - bit);
+ val >>= 1;
+ }
+
+ return result;
+}
+
+static void
+initialize_crc32 ()
+{
+ int byte;
+
+ for (byte = 0; byte < 256; ++ byte)
+ {
+ enet_uint32 crc = reflect_crc (byte, 8) << 24;
+ int offset;
+
+ for (offset = 0; offset < 8; ++ offset)
+ {
+ if (crc & 0x80000000)
+ crc = (crc << 1) ^ 0x04c11db7;
+ else
+ crc <<= 1;
+ }
+
+ crcTable [byte] = reflect_crc (crc, 32);
+ }
+
+ initializedCRC32 = 1;
+}
+
+enet_uint32
+enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
+{
+ enet_uint32 crc = 0xFFFFFFFF;
+
+ if (! initializedCRC32) initialize_crc32 ();
+
+ while (bufferCount -- > 0)
+ {
+ const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
+ * dataEnd = & data [buffers -> dataLength];
+
+ while (data < dataEnd)
+ {
+ crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
+ }
+
+ ++ buffers;
+ }
+
+ return ENET_HOST_TO_NET_32 (~ crc);
+}
+
+/** @} */
diff --git a/src/enet/peer.c b/src/enet/peer.c
new file mode 100644
index 000000000..d778ce1d6
--- /dev/null
+++ b/src/enet/peer.c
@@ -0,0 +1,816 @@
+/**
+ @file peer.c
+ @brief ENet peer management functions
+*/
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+/** @defgroup peer ENet peer functions
+ @{
+*/
+
+/** Configures throttle parameter for a peer.
+
+ Unreliable packets are dropped by ENet in response to the varying conditions
+ of the Internet connection to the peer. The throttle represents a probability
+ that an unreliable packet should not be dropped and thus sent by ENet to the peer.
+ The lowest mean round trip time from the sending of a reliable packet to the
+ receipt of its acknowledgement is measured over an amount of time specified by
+ the interval parameter in milliseconds. If a measured round trip time happens to
+ be significantly less than the mean round trip time measured over the interval,
+ then the throttle probability is increased to allow more traffic by an amount
+ specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE
+ constant. If a measured round trip time happens to be significantly greater than
+ the mean round trip time measured over the interval, then the throttle probability
+ is decreased to limit traffic by an amount specified in the deceleration parameter, which
+ is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has
+ a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by
+ ENet, and so 100% of all unreliable packets will be sent. When the throttle has a
+ value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable
+ packets will be sent. Intermediate values for the throttle represent intermediate
+ probabilities between 0% and 100% of unreliable packets being sent. The bandwidth
+ limits of the local and foreign hosts are taken into account to determine a
+ sensible limit for the throttle probability above which it should not raise even in
+ the best of conditions.
+
+ @param peer peer to configure
+ @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL.
+ @param acceleration rate at which to increase the throttle probability as mean RTT declines
+ @param deceleration rate at which to decrease the throttle probability as mean RTT increases
+*/
+void
+enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
+{
+ ENetProtocol command;
+
+ peer -> packetThrottleInterval = interval;
+ peer -> packetThrottleAcceleration = acceleration;
+ peer -> packetThrottleDeceleration = deceleration;
+
+ command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ command.header.channelID = 0xFF;
+
+ command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
+ command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
+ command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration);
+
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
+
+int
+enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
+{
+ if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance)
+ {
+ peer -> packetThrottle = peer -> packetThrottleLimit;
+ }
+ else
+ if (rtt < peer -> lastRoundTripTime)
+ {
+ peer -> packetThrottle += peer -> packetThrottleAcceleration;
+
+ if (peer -> packetThrottle > peer -> packetThrottleLimit)
+ peer -> packetThrottle = peer -> packetThrottleLimit;
+
+ return 1;
+ }
+ else
+ if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
+ {
+ if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
+ peer -> packetThrottle -= peer -> packetThrottleDeceleration;
+ else
+ peer -> packetThrottle = 0;
+
+ return -1;
+ }
+
+ return 0;
+}
+
+/** Queues a packet to be sent.
+ @param peer destination for the packet
+ @param channelID channel on which to send
+ @param packet packet to send
+ @retval 0 on success
+ @retval < 0 on failure
+*/
+int
+enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
+{
+ ENetChannel * channel = & peer -> channels [channelID];
+ ENetProtocol command;
+ size_t fragmentLength;
+
+ if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+ channelID >= peer -> channelCount)
+ return -1;
+
+ fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
+
+ if (packet -> dataLength > fragmentLength)
+ {
+ enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
+ enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
+ fragmentNumber,
+ fragmentOffset;
+ ENetList fragments;
+ ENetOutgoingCommand * fragment;
+
+ enet_list_clear (& fragments);
+
+ for (fragmentNumber = 0,
+ fragmentOffset = 0;
+ fragmentOffset < packet -> dataLength;
+ ++ fragmentNumber,
+ fragmentOffset += fragmentLength)
+ {
+ if (packet -> dataLength - fragmentOffset < fragmentLength)
+ fragmentLength = packet -> dataLength - fragmentOffset;
+
+ fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+ if (fragment == NULL)
+ {
+ while (! enet_list_empty (& fragments))
+ {
+ fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
+
+ enet_free (fragment);
+ }
+
+ return -1;
+ }
+
+ fragment -> fragmentOffset = fragmentOffset;
+ fragment -> fragmentLength = fragmentLength;
+ fragment -> packet = packet;
+ fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ fragment -> command.header.channelID = channelID;
+ fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
+ fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
+ fragment -> command.sendFragment.fragmentCount = fragmentCount;
+ fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
+ fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
+ fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
+
+ enet_list_insert (enet_list_end (& fragments), fragment);
+ }
+
+ packet -> referenceCount += fragmentNumber;
+
+ while (! enet_list_empty (& fragments))
+ {
+ fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
+
+ enet_peer_setup_outgoing_command (peer, fragment);
+ }
+
+ return 0;
+ }
+
+ command.header.channelID = channelID;
+
+ if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
+ {
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+ }
+ else
+ if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
+ {
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
+ command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
+ command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+ }
+ else
+ if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
+ {
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+ }
+ else
+ {
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
+ command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
+ command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+ }
+
+ if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
+ return -1;
+
+ return 0;
+}
+
+/** Attempts to dequeue any incoming queued packet.
+ @param peer peer to dequeue packets from
+ @param channelID holds the channel ID of the channel the packet was received on success
+ @returns a pointer to the packet, or NULL if there are no available incoming queued packets
+*/
+ENetPacket *
+enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
+{
+ ENetIncomingCommand * incomingCommand;
+ ENetPacket * packet;
+
+ if (enet_list_empty (& peer -> dispatchedCommands))
+ return NULL;
+
+ incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands));
+
+ if (channelID != NULL)
+ * channelID = incomingCommand -> command.header.channelID;
+
+ packet = incomingCommand -> packet;
+
+ -- packet -> referenceCount;
+
+ if (incomingCommand -> fragments != NULL)
+ enet_free (incomingCommand -> fragments);
+
+ enet_free (incomingCommand);
+
+ return packet;
+}
+
+static void
+enet_peer_reset_outgoing_commands (ENetList * queue)
+{
+ ENetOutgoingCommand * outgoingCommand;
+
+ while (! enet_list_empty (queue))
+ {
+ outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ -- outgoingCommand -> packet -> referenceCount;
+
+ if (outgoingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (outgoingCommand -> packet);
+ }
+
+ enet_free (outgoingCommand);
+ }
+}
+
+static void
+enet_peer_reset_incoming_commands (ENetList * queue)
+{
+ ENetIncomingCommand * incomingCommand;
+
+ while (! enet_list_empty (queue))
+ {
+ incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
+
+ if (incomingCommand -> packet != NULL)
+ {
+ -- incomingCommand -> packet -> referenceCount;
+
+ if (incomingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (incomingCommand -> packet);
+ }
+
+ if (incomingCommand -> fragments != NULL)
+ enet_free (incomingCommand -> fragments);
+
+ enet_free (incomingCommand);
+ }
+}
+
+void
+enet_peer_reset_queues (ENetPeer * peer)
+{
+ ENetChannel * channel;
+
+ if (peer -> needsDispatch)
+ {
+ enet_list_remove (& peer -> dispatchList);
+
+ peer -> needsDispatch = 0;
+ }
+
+ while (! enet_list_empty (& peer -> acknowledgements))
+ enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
+
+ enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
+ enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
+
+ if (peer -> channels != NULL && peer -> channelCount > 0)
+ {
+ for (channel = peer -> channels;
+ channel < & peer -> channels [peer -> channelCount];
+ ++ channel)
+ {
+ enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
+ enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
+ }
+
+ enet_free (peer -> channels);
+ }
+
+ peer -> channels = NULL;
+ peer -> channelCount = 0;
+}
+
+/** Forcefully disconnects a peer.
+ @param peer peer to forcefully disconnect
+ @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
+ on its connection to the local host.
+*/
+void
+enet_peer_reset (ENetPeer * peer)
+{
+ peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
+ peer -> connectID = 0;
+
+ peer -> state = ENET_PEER_STATE_DISCONNECTED;
+
+ peer -> incomingBandwidth = 0;
+ peer -> outgoingBandwidth = 0;
+ peer -> incomingBandwidthThrottleEpoch = 0;
+ peer -> outgoingBandwidthThrottleEpoch = 0;
+ peer -> incomingDataTotal = 0;
+ peer -> outgoingDataTotal = 0;
+ peer -> lastSendTime = 0;
+ peer -> lastReceiveTime = 0;
+ peer -> nextTimeout = 0;
+ peer -> earliestTimeout = 0;
+ peer -> packetLossEpoch = 0;
+ peer -> packetsSent = 0;
+ peer -> packetsLost = 0;
+ peer -> packetLoss = 0;
+ peer -> packetLossVariance = 0;
+ peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
+ peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
+ peer -> packetThrottleCounter = 0;
+ peer -> packetThrottleEpoch = 0;
+ peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION;
+ peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION;
+ peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL;
+ peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+ peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+ peer -> lastRoundTripTimeVariance = 0;
+ peer -> highestRoundTripTimeVariance = 0;
+ peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+ peer -> roundTripTimeVariance = 0;
+ peer -> mtu = peer -> host -> mtu;
+ peer -> reliableDataInTransit = 0;
+ peer -> outgoingReliableSequenceNumber = 0;
+ peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+ peer -> incomingUnsequencedGroup = 0;
+ peer -> outgoingUnsequencedGroup = 0;
+ peer -> eventData = 0;
+
+ memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
+
+ enet_peer_reset_queues (peer);
+}
+
+/** Sends a ping request to a peer.
+ @param peer destination for the ping request
+ @remarks ping requests factor into the mean round trip time as designated by the
+ roundTripTime field in the ENetPeer structure. Enet automatically pings all connected
+ peers at regular intervals, however, this function may be called to ensure more
+ frequent ping requests.
+*/
+void
+enet_peer_ping (ENetPeer * peer)
+{
+ ENetProtocol command;
+
+ if (peer -> state != ENET_PEER_STATE_CONNECTED)
+ return;
+
+ command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ command.header.channelID = 0xFF;
+
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
+
+/** Force an immediate disconnection from a peer.
+ @param peer peer to disconnect
+ @param data data describing the disconnection
+ @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
+ guarenteed to receive the disconnect notification, and is reset immediately upon
+ return from this function.
+*/
+void
+enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
+{
+ ENetProtocol command;
+
+ if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
+ return;
+
+ if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
+ peer -> state != ENET_PEER_STATE_DISCONNECTING)
+ {
+ enet_peer_reset_queues (peer);
+
+ command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
+ command.header.channelID = 0xFF;
+ command.disconnect.data = ENET_HOST_TO_NET_32 (data);
+
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+
+ enet_host_flush (peer -> host);
+ }
+
+ enet_peer_reset (peer);
+}
+
+/** Request a disconnection from a peer.
+ @param peer peer to request a disconnection
+ @param data data describing the disconnection
+ @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
+ once the disconnection is complete.
+*/
+void
+enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
+{
+ ENetProtocol command;
+
+ if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
+ peer -> state == ENET_PEER_STATE_DISCONNECTED ||
+ peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT ||
+ peer -> state == ENET_PEER_STATE_ZOMBIE)
+ return;
+
+ enet_peer_reset_queues (peer);
+
+ command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
+ command.header.channelID = 0xFF;
+ command.disconnect.data = ENET_HOST_TO_NET_32 (data);
+
+ if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+ command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ else
+ command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
+
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+
+ if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+ peer -> state = ENET_PEER_STATE_DISCONNECTING;
+ else
+ {
+ enet_host_flush (peer -> host);
+ enet_peer_reset (peer);
+ }
+}
+
+/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
+ @param peer peer to request a disconnection
+ @param data data describing the disconnection
+ @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
+ once the disconnection is complete.
+*/
+void
+enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
+{
+ if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
+ ! (enet_list_empty (& peer -> outgoingReliableCommands) &&
+ enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ enet_list_empty (& peer -> sentReliableCommands)))
+ {
+ peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
+ peer -> eventData = data;
+ }
+ else
+ enet_peer_disconnect (peer, data);
+}
+
+ENetAcknowledgement *
+enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
+{
+ ENetAcknowledgement * acknowledgement;
+
+ if (command -> header.channelID < peer -> channelCount)
+ {
+ ENetChannel * channel = & peer -> channels [command -> header.channelID];
+ enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE,
+ currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+ if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+ reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+ if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS)
+ return NULL;
+ }
+
+ acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
+ if (acknowledgement == NULL)
+ return NULL;
+
+ peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
+
+ acknowledgement -> sentTime = sentTime;
+ acknowledgement -> command = * command;
+
+ enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
+
+ return acknowledgement;
+}
+
+void
+enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
+{
+ ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
+
+ peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
+
+ if (outgoingCommand -> command.header.channelID == 0xFF)
+ {
+ ++ peer -> outgoingReliableSequenceNumber;
+
+ outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
+ outgoingCommand -> unreliableSequenceNumber = 0;
+ }
+ else
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+ {
+ ++ channel -> outgoingReliableSequenceNumber;
+ channel -> outgoingUnreliableSequenceNumber = 0;
+
+ outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+ outgoingCommand -> unreliableSequenceNumber = 0;
+ }
+ else
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
+ {
+ ++ peer -> outgoingUnsequencedGroup;
+
+ outgoingCommand -> reliableSequenceNumber = 0;
+ outgoingCommand -> unreliableSequenceNumber = 0;
+ }
+ else
+ {
+ ++ channel -> outgoingUnreliableSequenceNumber;
+
+ outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+ outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
+ }
+
+ outgoingCommand -> sendAttempts = 0;
+ outgoingCommand -> sentTime = 0;
+ outgoingCommand -> roundTripTimeout = 0;
+ outgoingCommand -> roundTripTimeoutLimit = 0;
+ outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
+
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+ enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
+ else
+ enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
+}
+
+ENetOutgoingCommand *
+enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length)
+{
+ ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+ if (outgoingCommand == NULL)
+ return NULL;
+
+ outgoingCommand -> command = * command;
+ outgoingCommand -> fragmentOffset = offset;
+ outgoingCommand -> fragmentLength = length;
+ outgoingCommand -> packet = packet;
+ if (packet != NULL)
+ ++ packet -> referenceCount;
+
+ enet_peer_setup_outgoing_command (peer, outgoingCommand);
+
+ return outgoingCommand;
+}
+
+void
+enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
+{
+ ENetListIterator currentCommand;
+
+ for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
+ currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
+ currentCommand = enet_list_next (currentCommand))
+ {
+ ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+ if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE &&
+ incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
+ break;
+ }
+
+ if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
+ return;
+
+ enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
+
+ if (! peer -> needsDispatch)
+ {
+ enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
+
+ peer -> needsDispatch = 1;
+ }
+}
+
+void
+enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
+{
+ ENetListIterator currentCommand;
+
+ for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands);
+ currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+ currentCommand = enet_list_next (currentCommand))
+ {
+ ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+ if (incomingCommand -> fragmentsRemaining > 0 ||
+ incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1))
+ break;
+
+ channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
+
+ if (incomingCommand -> fragmentCount > 0)
+ channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
+ }
+
+ if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands))
+ return;
+
+ enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
+
+ if (! peer -> needsDispatch)
+ {
+ enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
+
+ peer -> needsDispatch = 1;
+ }
+
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+}
+
+ENetIncomingCommand *
+enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
+{
+ static ENetIncomingCommand dummyCommand;
+
+ ENetChannel * channel = & peer -> channels [command -> header.channelID];
+ enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
+ enet_uint16 reliableWindow, currentWindow;
+ ENetIncomingCommand * incomingCommand;
+ ENetListIterator currentCommand;
+
+ if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+ goto freePacket;
+
+ if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
+ {
+ reliableSequenceNumber = command -> header.reliableSequenceNumber;
+ reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+ currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+ if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+ reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+ if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
+ goto freePacket;
+ }
+
+ switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+ {
+ case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+ case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+ if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
+ goto freePacket;
+
+ for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
+ currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+ currentCommand = enet_list_previous (currentCommand))
+ {
+ incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+ if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+ {
+ if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+ continue;
+ }
+ else
+ if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+ break;
+
+ if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
+ {
+ if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
+ break;
+
+ goto freePacket;
+ }
+ }
+ break;
+
+ case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
+ unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
+
+ for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
+ currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
+ currentCommand = enet_list_previous (currentCommand))
+ {
+ incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+ if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
+ continue;
+
+ if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+ {
+ if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+ continue;
+ }
+ else
+ if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+ break;
+
+ if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
+ break;
+
+ if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
+ continue;
+
+ if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
+ {
+ if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
+ break;
+
+ goto freePacket;
+ }
+ }
+ break;
+
+ case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
+ currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
+ break;
+
+ default:
+ goto freePacket;
+ }
+
+ incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
+ if (incomingCommand == NULL)
+ goto notifyError;
+
+ incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
+ incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
+ incomingCommand -> command = * command;
+ incomingCommand -> fragmentCount = fragmentCount;
+ incomingCommand -> fragmentsRemaining = fragmentCount;
+ incomingCommand -> packet = packet;
+ incomingCommand -> fragments = NULL;
+
+ if (fragmentCount > 0)
+ {
+ incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
+ if (incomingCommand -> fragments == NULL)
+ {
+ enet_free (incomingCommand);
+
+ goto notifyError;
+ }
+ memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
+ }
+
+ if (packet != NULL)
+ ++ packet -> referenceCount;
+
+ enet_list_insert (enet_list_next (currentCommand), incomingCommand);
+
+ switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+ {
+ case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+ case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+ enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+ break;
+
+ default:
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+ break;
+ }
+
+ return incomingCommand;
+
+freePacket:
+ if (fragmentCount > 0)
+ goto notifyError;
+
+ if (packet != NULL && packet -> referenceCount == 0)
+ enet_packet_destroy (packet);
+
+ return & dummyCommand;
+
+notifyError:
+ if (packet != NULL && packet -> referenceCount == 0)
+ enet_packet_destroy (packet);
+
+ return NULL;
+}
+
+/** @} */
diff --git a/src/enet/protocol.c b/src/enet/protocol.c
new file mode 100644
index 000000000..8e26dfb24
--- /dev/null
+++ b/src/enet/protocol.c
@@ -0,0 +1,1671 @@
+/**
+ @file protocol.c
+ @brief ENet protocol functions
+*/
+#include <stdio.h>
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/utility.h"
+#include "enet/time.h"
+#include "enet/enet.h"
+
+static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
+{
+ 0,
+ sizeof (ENetProtocolAcknowledge),
+ sizeof (ENetProtocolConnect),
+ sizeof (ENetProtocolVerifyConnect),
+ sizeof (ENetProtocolDisconnect),
+ sizeof (ENetProtocolPing),
+ sizeof (ENetProtocolSendReliable),
+ sizeof (ENetProtocolSendUnreliable),
+ sizeof (ENetProtocolSendFragment),
+ sizeof (ENetProtocolSendUnsequenced),
+ sizeof (ENetProtocolBandwidthLimit),
+ sizeof (ENetProtocolThrottleConfigure),
+};
+
+size_t
+enet_protocol_command_size (enet_uint8 commandNumber)
+{
+ return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK];
+}
+
+static int
+enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
+{
+ while (! enet_list_empty (& host -> dispatchQueue))
+ {
+ ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
+
+ peer -> needsDispatch = 0;
+
+ switch (peer -> state)
+ {
+ case ENET_PEER_STATE_CONNECTION_PENDING:
+ case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
+ peer -> state = ENET_PEER_STATE_CONNECTED;
+
+ event -> type = ENET_EVENT_TYPE_CONNECT;
+ event -> peer = peer;
+ event -> data = peer -> eventData;
+
+ return 1;
+
+ case ENET_PEER_STATE_ZOMBIE:
+ host -> recalculateBandwidthLimits = 1;
+
+ event -> type = ENET_EVENT_TYPE_DISCONNECT;
+ event -> peer = peer;
+ event -> data = peer -> eventData;
+
+ enet_peer_reset (peer);
+
+ return 1;
+
+ case ENET_PEER_STATE_CONNECTED:
+ if (enet_list_empty (& peer -> dispatchedCommands))
+ continue;
+
+ event -> packet = enet_peer_receive (peer, & event -> channelID);
+ if (event -> packet == NULL)
+ continue;
+
+ event -> type = ENET_EVENT_TYPE_RECEIVE;
+ event -> peer = peer;
+
+ if (! enet_list_empty (& peer -> dispatchedCommands))
+ {
+ peer -> needsDispatch = 1;
+
+ enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
+ }
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
+{
+ peer -> state = state;
+
+ if (! peer -> needsDispatch)
+ {
+ enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
+
+ peer -> needsDispatch = 1;
+ }
+}
+
+static void
+enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
+{
+ host -> recalculateBandwidthLimits = 1;
+
+ if (event != NULL)
+ {
+ peer -> state = ENET_PEER_STATE_CONNECTED;
+
+ event -> type = ENET_EVENT_TYPE_CONNECT;
+ event -> peer = peer;
+ event -> data = peer -> eventData;
+ }
+ else
+ enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING);
+}
+
+static void
+enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
+{
+ if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING)
+ host -> recalculateBandwidthLimits = 1;
+
+ if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED)
+ enet_peer_reset (peer);
+ else
+ if (event != NULL)
+ {
+ event -> type = ENET_EVENT_TYPE_DISCONNECT;
+ event -> peer = peer;
+ event -> data = 0;
+
+ enet_peer_reset (peer);
+ }
+ else
+ {
+ peer -> eventData = 0;
+
+ enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+ }
+}
+
+static void
+enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
+{
+ ENetOutgoingCommand * outgoingCommand;
+
+ while (! enet_list_empty (& peer -> sentUnreliableCommands))
+ {
+ outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
+
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ -- outgoingCommand -> packet -> referenceCount;
+
+ if (outgoingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (outgoingCommand -> packet);
+ }
+
+ enet_free (outgoingCommand);
+ }
+}
+
+static ENetProtocolCommand
+enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID)
+{
+ ENetOutgoingCommand * outgoingCommand;
+ ENetListIterator currentCommand;
+ ENetProtocolCommand commandNumber;
+
+ for (currentCommand = enet_list_begin (& peer -> sentReliableCommands);
+ currentCommand != enet_list_end (& peer -> sentReliableCommands);
+ currentCommand = enet_list_next (currentCommand))
+ {
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+ if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
+ outgoingCommand -> command.header.channelID == channelID)
+ break;
+ }
+
+ if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
+ {
+ for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
+ currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
+ currentCommand = enet_list_next (currentCommand))
+ {
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+ if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
+
+ if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
+ outgoingCommand -> command.header.channelID == channelID)
+ break;
+ }
+
+ if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
+ return ENET_PROTOCOL_COMMAND_NONE;
+ }
+
+ if (channelID < peer -> channelCount)
+ {
+ ENetChannel * channel = & peer -> channels [channelID];
+ enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+ if (channel -> reliableWindows [reliableWindow] > 0)
+ {
+ -- channel -> reliableWindows [reliableWindow];
+ if (! channel -> reliableWindows [reliableWindow])
+ channel -> usedReliableWindows &= ~ (1 << reliableWindow);
+ }
+ }
+
+ commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK);
+
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
+
+ -- outgoingCommand -> packet -> referenceCount;
+
+ if (outgoingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (outgoingCommand -> packet);
+ }
+
+ enet_free (outgoingCommand);
+
+ if (enet_list_empty (& peer -> sentReliableCommands))
+ return commandNumber;
+
+ outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands);
+
+ peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
+
+ return commandNumber;
+}
+
+static ENetPeer *
+enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command)
+{
+ enet_uint8 incomingSessionID, outgoingSessionID;
+ enet_uint32 mtu, windowSize;
+ ENetChannel * channel;
+ size_t channelCount;
+ ENetPeer * currentPeer;
+ ENetProtocol verifyCommand;
+
+ channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);
+
+ if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT ||
+ channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+ return NULL;
+
+ for (currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
+ if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
+ currentPeer -> address.host == host -> receivedAddress.host &&
+ currentPeer -> address.port == host -> receivedAddress.port &&
+ currentPeer -> connectID == command -> connect.connectID)
+ return NULL;
+ }
+
+ for (currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
+ if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
+ break;
+ }
+
+ if (currentPeer >= & host -> peers [host -> peerCount])
+ return NULL;
+
+ if (channelCount > host -> channelLimit)
+ channelCount = host -> channelLimit;
+ currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
+ if (currentPeer -> channels == NULL)
+ return NULL;
+ currentPeer -> channelCount = channelCount;
+ currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
+ currentPeer -> connectID = command -> connect.connectID;
+ currentPeer -> address = host -> receivedAddress;
+ currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
+ currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
+ currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
+ currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
+ currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
+ currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
+ currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data);
+
+ incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID;
+ incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+ if (incomingSessionID == currentPeer -> outgoingSessionID)
+ incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+ currentPeer -> outgoingSessionID = incomingSessionID;
+
+ outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID;
+ outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+ if (outgoingSessionID == currentPeer -> incomingSessionID)
+ outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+ currentPeer -> incomingSessionID = outgoingSessionID;
+
+ for (channel = currentPeer -> channels;
+ channel < & currentPeer -> channels [channelCount];
+ ++ channel)
+ {
+ channel -> outgoingReliableSequenceNumber = 0;
+ channel -> outgoingUnreliableSequenceNumber = 0;
+ channel -> incomingReliableSequenceNumber = 0;
+
+ enet_list_clear (& channel -> incomingReliableCommands);
+ enet_list_clear (& channel -> incomingUnreliableCommands);
+
+ channel -> usedReliableWindows = 0;
+ memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
+ }
+
+ mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu);
+
+ if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
+ mtu = ENET_PROTOCOL_MINIMUM_MTU;
+ else
+ if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
+ mtu = ENET_PROTOCOL_MAXIMUM_MTU;
+
+ currentPeer -> mtu = mtu;
+
+ if (host -> outgoingBandwidth == 0 &&
+ currentPeer -> incomingBandwidth == 0)
+ currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+ else
+ if (host -> outgoingBandwidth == 0 ||
+ currentPeer -> incomingBandwidth == 0)
+ currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
+ ENET_PEER_WINDOW_SIZE_SCALE) *
+ ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+ else
+ currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
+ ENET_PEER_WINDOW_SIZE_SCALE) *
+ ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+ if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+ currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+ else
+ if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+ currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+ if (host -> incomingBandwidth == 0)
+ windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+ else
+ windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) *
+ ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+ if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize))
+ windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize);
+
+ if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+ windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+ else
+ if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+ windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+ verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+ verifyCommand.header.channelID = 0xFF;
+ verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
+ verifyCommand.verifyConnect.incomingSessionID = incomingSessionID;
+ verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID;
+ verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
+ verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
+ verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
+ verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
+ verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+ verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
+ verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
+ verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
+ verifyCommand.verifyConnect.connectID = currentPeer -> connectID;
+
+ enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0);
+
+ return currentPeer;
+}
+
+static int
+enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+ ENetPacket * packet;
+ size_t dataLength;
+
+ if (command -> header.channelID >= peer -> channelCount ||
+ (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+ return -1;
+
+ dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
+ * currentData += dataLength;
+ if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ return -1;
+
+ packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable),
+ dataLength,
+ ENET_PACKET_FLAG_RELIABLE);
+ if (packet == NULL ||
+ enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
+ return -1;
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+ ENetPacket * packet;
+ enet_uint32 unsequencedGroup, index;
+ size_t dataLength;
+
+ if (command -> header.channelID >= peer -> channelCount ||
+ (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+ return -1;
+
+ dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
+ * currentData += dataLength;
+ if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ return -1;
+
+ unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup);
+ index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE;
+
+ if (unsequencedGroup < peer -> incomingUnsequencedGroup)
+ unsequencedGroup += 0x10000;
+
+ if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE)
+ return 0;
+
+ unsequencedGroup &= 0xFFFF;
+
+ if (unsequencedGroup - index != peer -> incomingUnsequencedGroup)
+ {
+ peer -> incomingUnsequencedGroup = unsequencedGroup - index;
+
+ memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
+ }
+ else
+ if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32)))
+ return 0;
+
+ packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced),
+ dataLength,
+ ENET_PACKET_FLAG_UNSEQUENCED);
+ if (packet == NULL ||
+ enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
+ return -1;
+
+ peer -> unsequencedWindow [index / 32] |= 1 << (index % 32);
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+ ENetPacket * packet;
+ size_t dataLength;
+
+ if (command -> header.channelID >= peer -> channelCount ||
+ (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+ return -1;
+
+ dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
+ * currentData += dataLength;
+ if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ return -1;
+
+ packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable),
+ dataLength,
+ 0);
+ if (packet == NULL ||
+ enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
+ return -1;
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+ enet_uint32 fragmentNumber,
+ fragmentCount,
+ fragmentOffset,
+ fragmentLength,
+ startSequenceNumber,
+ totalLength;
+ ENetChannel * channel;
+ enet_uint16 startWindow, currentWindow;
+ ENetListIterator currentCommand;
+ ENetIncomingCommand * startCommand = NULL;
+
+ if (command -> header.channelID >= peer -> channelCount ||
+ (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+ return -1;
+
+ fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
+ * currentData += fragmentLength;
+ if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ return -1;
+
+ channel = & peer -> channels [command -> header.channelID];
+ startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
+ startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+ currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+ if (startSequenceNumber < channel -> incomingReliableSequenceNumber)
+ startWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+ if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
+ return 0;
+
+ fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
+ fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
+ fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
+ totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
+
+ if (fragmentOffset >= totalLength ||
+ fragmentOffset + fragmentLength > totalLength ||
+ fragmentNumber >= fragmentCount)
+ return -1;
+
+ for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
+ currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+ currentCommand = enet_list_previous (currentCommand))
+ {
+ ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+ if (startSequenceNumber >= channel -> incomingReliableSequenceNumber)
+ {
+ if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+ continue;
+ }
+ else
+ if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+ break;
+
+ if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber)
+ {
+ if (incomingCommand -> reliableSequenceNumber < startSequenceNumber)
+ break;
+
+ if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT ||
+ totalLength != incomingCommand -> packet -> dataLength ||
+ fragmentCount != incomingCommand -> fragmentCount)
+ return -1;
+
+ startCommand = incomingCommand;
+ break;
+ }
+ }
+
+ if (startCommand == NULL)
+ {
+ ENetProtocol hostCommand = * command;
+ ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE);
+ if (packet == NULL)
+ return -1;
+
+ hostCommand.header.reliableSequenceNumber = startSequenceNumber;
+ hostCommand.sendFragment.startSequenceNumber = startSequenceNumber;
+ hostCommand.sendFragment.dataLength = fragmentLength;
+ hostCommand.sendFragment.fragmentNumber = fragmentNumber;
+ hostCommand.sendFragment.fragmentCount = fragmentCount;
+ hostCommand.sendFragment.fragmentOffset = fragmentOffset;
+ hostCommand.sendFragment.totalLength = totalLength;
+
+ startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount);
+ if (startCommand == NULL)
+ return -1;
+ }
+
+ if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
+ {
+ -- startCommand -> fragmentsRemaining;
+
+ startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32));
+
+ if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
+ fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;
+
+ memcpy (startCommand -> packet -> data + fragmentOffset,
+ (enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
+ fragmentLength);
+
+ if (startCommand -> fragmentsRemaining <= 0)
+ enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+ }
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+ return 0;
+}
+
+static int
+enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+ peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
+ peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
+
+ if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
+ peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+ else
+ peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
+ ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+ if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+ peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+ else
+ if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+ peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+ peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
+ peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
+ peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration);
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+ if (peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT)
+ return 0;
+
+ enet_peer_reset_queues (peer);
+
+ if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED)
+ enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+ else
+ if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+ {
+ if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1;
+
+ enet_peer_reset (peer);
+ }
+ else
+ if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+ peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT;
+ else
+ enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+
+ if (peer -> state != ENET_PEER_STATE_DISCONNECTED)
+ peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data);
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
+{
+ enet_uint32 roundTripTime,
+ receivedSentTime,
+ receivedReliableSequenceNumber;
+ ENetProtocolCommand commandNumber;
+
+ receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime);
+ receivedSentTime |= host -> serviceTime & 0xFFFF0000;
+ if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000))
+ receivedSentTime -= 0x10000;
+
+ if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
+ return 0;
+
+ peer -> lastReceiveTime = host -> serviceTime;
+ peer -> earliestTimeout = 0;
+
+ roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
+
+ enet_peer_throttle (peer, roundTripTime);
+
+ peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
+
+ if (roundTripTime >= peer -> roundTripTime)
+ {
+ peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
+ peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
+ }
+ else
+ {
+ peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
+ peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
+ }
+
+ if (peer -> roundTripTime < peer -> lowestRoundTripTime)
+ peer -> lowestRoundTripTime = peer -> roundTripTime;
+
+ if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
+ peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
+
+ if (peer -> packetThrottleEpoch == 0 ||
+ ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
+ {
+ peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
+ peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
+ peer -> lowestRoundTripTime = peer -> roundTripTime;
+ peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
+ peer -> packetThrottleEpoch = host -> serviceTime;
+ }
+
+ receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
+
+ commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
+
+ switch (peer -> state)
+ {
+ case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
+ if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT)
+ return -1;
+
+ enet_protocol_notify_connect (host, peer, event);
+ break;
+
+ case ENET_PEER_STATE_DISCONNECTING:
+ if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT)
+ return -1;
+
+ enet_protocol_notify_disconnect (host, peer, event);
+ break;
+
+ case ENET_PEER_STATE_DISCONNECT_LATER:
+ if (enet_list_empty (& peer -> outgoingReliableCommands) &&
+ enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ enet_list_empty (& peer -> sentReliableCommands))
+ enet_peer_disconnect (peer, peer -> eventData);
+ break;
+ }
+
+ return 0;
+}
+
+static int
+enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
+{
+ enet_uint32 mtu, windowSize;
+ size_t channelCount;
+
+ if (peer -> state != ENET_PEER_STATE_CONNECTING)
+ return 0;
+
+ channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount);
+
+ if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT ||
+ ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval ||
+ ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration ||
+ ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration ||
+ command -> verifyConnect.connectID != peer -> connectID)
+ {
+ peer -> eventData = 0;
+
+ enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+
+ return -1;
+ }
+
+ enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF);
+
+ if (channelCount < peer -> channelCount)
+ peer -> channelCount = channelCount;
+
+ peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID);
+ peer -> incomingSessionID = command -> verifyConnect.incomingSessionID;
+ peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID;
+
+ mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu);
+
+ if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
+ mtu = ENET_PROTOCOL_MINIMUM_MTU;
+ else
+ if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
+ mtu = ENET_PROTOCOL_MAXIMUM_MTU;
+
+ if (mtu < peer -> mtu)
+ peer -> mtu = mtu;
+
+ windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize);
+
+ if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+ windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+ if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+ windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+ if (windowSize < peer -> windowSize)
+ peer -> windowSize = windowSize;
+
+ peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth);
+ peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth);
+
+ enet_protocol_notify_connect (host, peer, event);
+ return 0;
+}
+
+static int
+enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+{
+ ENetProtocolHeader * header;
+ ENetProtocol * command;
+ ENetPeer * peer;
+ enet_uint8 * currentData;
+ size_t headerSize;
+ enet_uint16 peerID, flags;
+ enet_uint8 sessionID;
+
+ if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime)
+ return 0;
+
+ header = (ENetProtocolHeader *) host -> receivedData;
+
+ peerID = ENET_NET_TO_HOST_16 (header -> peerID);
+ sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT;
+ flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK;
+ peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK);
+
+ headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime);
+ if (host -> checksum != NULL)
+ headerSize += sizeof (enet_uint32);
+
+ if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID)
+ peer = NULL;
+ else
+ if (peerID >= host -> peerCount)
+ return 0;
+ else
+ {
+ peer = & host -> peers [peerID];
+
+ if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
+ peer -> state == ENET_PEER_STATE_ZOMBIE ||
+ (host -> receivedAddress.host != peer -> address.host &&
+ peer -> address.host != ENET_HOST_BROADCAST) ||
+ (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
+ sessionID != peer -> incomingSessionID))
+ return 0;
+ }
+
+ if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED)
+ {
+ size_t originalSize;
+ if (host -> compressor.context == NULL || host -> compressor.decompress == NULL)
+ return 0;
+
+ originalSize = host -> compressor.decompress (host -> compressor.context,
+ host -> receivedData + headerSize,
+ host -> receivedDataLength - headerSize,
+ host -> packetData [1] + headerSize,
+ sizeof (host -> packetData [1]) - headerSize);
+ if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize)
+ return 0;
+
+ memcpy (host -> packetData [1], header, headerSize);
+ host -> receivedData = host -> packetData [1];
+ host -> receivedDataLength = headerSize + originalSize;
+ }
+
+ if (host -> checksum != NULL)
+ {
+ enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)],
+ desiredChecksum = * checksum;
+ ENetBuffer buffer;
+
+ * checksum = peer != NULL ? peer -> connectID : 0;
+
+ buffer.data = host -> receivedData;
+ buffer.dataLength = host -> receivedDataLength;
+
+ if (host -> checksum (& buffer, 1) != desiredChecksum)
+ return 0;
+ }
+
+ if (peer != NULL)
+ {
+ peer -> address.host = host -> receivedAddress.host;
+ peer -> address.port = host -> receivedAddress.port;
+ peer -> incomingDataTotal += host -> receivedDataLength;
+ }
+
+ currentData = host -> receivedData + headerSize;
+
+ while (currentData < & host -> receivedData [host -> receivedDataLength])
+ {
+ enet_uint8 commandNumber;
+ size_t commandSize;
+
+ command = (ENetProtocol *) currentData;
+
+ if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
+ break;
+
+ commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK;
+ if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT)
+ break;
+
+ commandSize = commandSizes [commandNumber];
+ if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength])
+ break;
+
+ currentData += commandSize;
+
+ if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT)
+ break;
+
+ command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
+
+ switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+ {
+ case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
+ if (enet_protocol_handle_acknowledge (host, event, peer, command))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_CONNECT:
+ peer = enet_protocol_handle_connect (host, header, command);
+ if (peer == NULL)
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT:
+ if (enet_protocol_handle_verify_connect (host, event, peer, command))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_DISCONNECT:
+ if (enet_protocol_handle_disconnect (host, peer, command))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_PING:
+ if (enet_protocol_handle_ping (host, peer, command))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+ if (enet_protocol_handle_send_reliable (host, peer, command, & currentData))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
+ if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
+ if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+ if (enet_protocol_handle_send_fragment (host, peer, command, & currentData))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT:
+ if (enet_protocol_handle_bandwidth_limit (host, peer, command))
+ goto commandError;
+ break;
+
+ case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE:
+ if (enet_protocol_handle_throttle_configure (host, peer, command))
+ goto commandError;
+ break;
+
+ default:
+ goto commandError;
+ }
+
+ if (peer != NULL &&
+ (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0)
+ {
+ enet_uint16 sentTime;
+
+ if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME))
+ break;
+
+ sentTime = ENET_NET_TO_HOST_16 (header -> sentTime);
+
+ switch (peer -> state)
+ {
+ case ENET_PEER_STATE_DISCONNECTING:
+ case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
+ break;
+
+ case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
+ if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
+ enet_peer_queue_acknowledgement (peer, command, sentTime);
+ break;
+
+ default:
+ enet_peer_queue_acknowledgement (peer, command, sentTime);
+ break;
+ }
+ }
+ }
+
+commandError:
+ if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
+ return 1;
+
+ return 0;
+}
+
+static int
+enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
+{
+ for (;;)
+ {
+ int receivedLength;
+ ENetBuffer buffer;
+
+ buffer.data = host -> packetData [0];
+ buffer.dataLength = sizeof (host -> packetData [0]);
+
+ receivedLength = enet_socket_receive (host -> socket,
+ & host -> receivedAddress,
+ & buffer,
+ 1);
+
+ if (receivedLength < 0)
+ return -1;
+
+ if (receivedLength == 0)
+ return 0;
+
+ host -> receivedData = host -> packetData [0];
+ host -> receivedDataLength = receivedLength;
+
+ host -> totalReceivedData += receivedLength;
+ host -> totalReceivedPackets ++;
+
+ switch (enet_protocol_handle_incoming_commands (host, event))
+ {
+ case 1:
+ return 1;
+
+ case -1:
+ return -1;
+
+ default:
+ break;
+ }
+ }
+
+ return -1;
+}
+
+static void
+enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
+{
+ ENetProtocol * command = & host -> commands [host -> commandCount];
+ ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
+ ENetAcknowledgement * acknowledgement;
+ ENetListIterator currentAcknowledgement;
+
+ currentAcknowledgement = enet_list_begin (& peer -> acknowledgements);
+
+ while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements))
+ {
+ if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
+ buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
+ peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
+ {
+ host -> continueSending = 1;
+
+ break;
+ }
+
+ acknowledgement = (ENetAcknowledgement *) currentAcknowledgement;
+
+ currentAcknowledgement = enet_list_next (currentAcknowledgement);
+
+ buffer -> data = command;
+ buffer -> dataLength = sizeof (ENetProtocolAcknowledge);
+
+ host -> packetSize += buffer -> dataLength;
+
+ command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
+ command -> header.channelID = acknowledgement -> command.header.channelID;
+ command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
+ command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime);
+
+ if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
+ enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+
+ enet_list_remove (& acknowledgement -> acknowledgementList);
+ enet_free (acknowledgement);
+
+ ++ command;
+ ++ buffer;
+ }
+
+ host -> commandCount = command - host -> commands;
+ host -> bufferCount = buffer - host -> buffers;
+}
+
+static void
+enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
+{
+ ENetProtocol * command = & host -> commands [host -> commandCount];
+ ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
+ ENetOutgoingCommand * outgoingCommand;
+ ENetListIterator currentCommand;
+
+ currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
+
+ while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
+ {
+ size_t commandSize;
+
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+ commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
+
+ if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
+ buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
+ peer -> mtu - host -> packetSize < commandSize ||
+ (outgoingCommand -> packet != NULL &&
+ peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> packet -> dataLength))
+ {
+ host -> continueSending = 1;
+
+ break;
+ }
+
+ currentCommand = enet_list_next (currentCommand);
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
+ peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
+
+ if (peer -> packetThrottleCounter > peer -> packetThrottle)
+ {
+ -- outgoingCommand -> packet -> referenceCount;
+
+ if (outgoingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (outgoingCommand -> packet);
+
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+ enet_free (outgoingCommand);
+
+ continue;
+ }
+ }
+
+ buffer -> data = command;
+ buffer -> dataLength = commandSize;
+
+ host -> packetSize += buffer -> dataLength;
+
+ * command = outgoingCommand -> command;
+
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ ++ buffer;
+
+ buffer -> data = outgoingCommand -> packet -> data;
+ buffer -> dataLength = outgoingCommand -> packet -> dataLength;
+
+ host -> packetSize += buffer -> dataLength;
+
+ enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
+ }
+ else
+ enet_free (outgoingCommand);
+
+ ++ command;
+ ++ buffer;
+ }
+
+ host -> commandCount = command - host -> commands;
+ host -> bufferCount = buffer - host -> buffers;
+
+ if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
+ enet_list_empty (& peer -> outgoingReliableCommands) &&
+ enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ enet_list_empty (& peer -> sentReliableCommands))
+ enet_peer_disconnect (peer, peer -> eventData);
+}
+
+static int
+enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
+{
+ ENetOutgoingCommand * outgoingCommand;
+ ENetListIterator currentCommand, insertPosition;
+
+ currentCommand = enet_list_begin (& peer -> sentReliableCommands);
+ insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
+
+ while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
+ {
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+ currentCommand = enet_list_next (currentCommand);
+
+ if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout)
+ continue;
+
+ if (peer -> earliestTimeout == 0 ||
+ ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout))
+ peer -> earliestTimeout = outgoingCommand -> sentTime;
+
+ if (peer -> earliestTimeout != 0 &&
+ (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MAXIMUM ||
+ (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit &&
+ ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MINIMUM)))
+ {
+ enet_protocol_notify_disconnect (host, peer, event);
+
+ return 1;
+ }
+
+ if (outgoingCommand -> packet != NULL)
+ peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
+
+ ++ peer -> packetsLost;
+
+ outgoingCommand -> roundTripTimeout *= 2;
+
+ enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
+
+ if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
+ ! enet_list_empty (& peer -> sentReliableCommands))
+ {
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+ peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
+ }
+ }
+
+ return 0;
+}
+
+static void
+enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
+{
+ ENetProtocol * command = & host -> commands [host -> commandCount];
+ ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
+ ENetOutgoingCommand * outgoingCommand;
+ ENetListIterator currentCommand;
+ ENetChannel *channel;
+ enet_uint16 reliableWindow;
+ size_t commandSize;
+
+ currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
+
+ while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
+ {
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+ channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
+ reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+ if (channel != NULL &&
+ outgoingCommand -> sendAttempts < 1 &&
+ ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
+ (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
+ channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
+ (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
+ break;
+
+ commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
+ if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
+ buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
+ peer -> mtu - host -> packetSize < commandSize)
+ {
+ host -> continueSending = 1;
+
+ break;
+ }
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
+ break;
+
+ if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))
+ {
+ host -> continueSending = 1;
+
+ break;
+ }
+ }
+
+ currentCommand = enet_list_next (currentCommand);
+
+ if (channel != NULL && outgoingCommand -> sendAttempts < 1)
+ {
+ channel -> usedReliableWindows |= 1 << reliableWindow;
+ ++ channel -> reliableWindows [reliableWindow];
+ }
+
+ ++ outgoingCommand -> sendAttempts;
+
+ if (outgoingCommand -> roundTripTimeout == 0)
+ {
+ outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
+ outgoingCommand -> roundTripTimeoutLimit = ENET_PEER_TIMEOUT_LIMIT * outgoingCommand -> roundTripTimeout;
+ }
+
+ if (enet_list_empty (& peer -> sentReliableCommands))
+ peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
+
+ enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
+ enet_list_remove (& outgoingCommand -> outgoingCommandList));
+
+ outgoingCommand -> sentTime = host -> serviceTime;
+
+ buffer -> data = command;
+ buffer -> dataLength = commandSize;
+
+ host -> packetSize += buffer -> dataLength;
+ host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
+
+ * command = outgoingCommand -> command;
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ ++ buffer;
+
+ buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
+ buffer -> dataLength = outgoingCommand -> fragmentLength;
+
+ host -> packetSize += outgoingCommand -> fragmentLength;
+
+ peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
+ }
+
+ ++ peer -> packetsSent;
+
+ ++ command;
+ ++ buffer;
+ }
+
+ host -> commandCount = command - host -> commands;
+ host -> bufferCount = buffer - host -> buffers;
+}
+
+static int
+enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
+{
+ enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
+ ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
+ ENetPeer * currentPeer;
+ int sentLength;
+ size_t shouldCompress = 0;
+
+ host -> continueSending = 1;
+
+ while (host -> continueSending)
+ for (host -> continueSending = 0,
+ currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
+ if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
+ currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
+ continue;
+
+ host -> headerFlags = 0;
+ host -> commandCount = 0;
+ host -> bufferCount = 1;
+ host -> packetSize = sizeof (ENetProtocolHeader);
+
+ if (! enet_list_empty (& currentPeer -> acknowledgements))
+ enet_protocol_send_acknowledgements (host, currentPeer);
+
+ if (checkForTimeouts != 0 &&
+ ! enet_list_empty (& currentPeer -> sentReliableCommands) &&
+ ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) &&
+ enet_protocol_check_timeouts (host, currentPeer, event) == 1)
+ return 1;
+
+ if (! enet_list_empty (& currentPeer -> outgoingReliableCommands))
+ enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
+ else
+ if (enet_list_empty (& currentPeer -> sentReliableCommands) &&
+ ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL &&
+ currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
+ {
+ enet_peer_ping (currentPeer);
+ enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
+ }
+
+ if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
+ enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
+
+ if (host -> commandCount == 0)
+ continue;
+
+ if (currentPeer -> packetLossEpoch == 0)
+ currentPeer -> packetLossEpoch = host -> serviceTime;
+ else
+ if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL &&
+ currentPeer -> packetsSent > 0)
+ {
+ enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
+
+#ifdef ENET_DEBUG
+#ifdef WIN32
+ printf (
+#else
+ fprintf (stderr,
+#endif
+ "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
+#endif
+
+ currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
+
+ if (packetLoss >= currentPeer -> packetLoss)
+ {
+ currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
+ currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
+ }
+ else
+ {
+ currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
+ currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
+ }
+
+ currentPeer -> packetLossEpoch = host -> serviceTime;
+ currentPeer -> packetsSent = 0;
+ currentPeer -> packetsLost = 0;
+ }
+
+ host -> buffers -> data = headerData;
+ if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)
+ {
+ header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF);
+
+ host -> buffers -> dataLength = sizeof (ENetProtocolHeader);
+ }
+ else
+ host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime;
+
+ shouldCompress = 0;
+ if (host -> compressor.context != NULL && host -> compressor.compress != NULL)
+ {
+ size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader),
+ compressedSize = host -> compressor.compress (host -> compressor.context,
+ & host -> buffers [1], host -> bufferCount - 1,
+ originalSize,
+ host -> packetData [1],
+ originalSize);
+ if (compressedSize > 0 && compressedSize < originalSize)
+ {
+ host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED;
+ shouldCompress = compressedSize;
+#ifdef ENET_DEBUG_COMPRESS
+#ifdef WIN32
+ printf (
+#else
+ fprintf (stderr,
+#endif
+ "peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
+#endif
+ }
+ }
+
+ if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID)
+ host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT;
+ header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags);
+ if (host -> checksum != NULL)
+ {
+ enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength];
+ * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0;
+ host -> buffers -> dataLength += sizeof (enet_uint32);
+ * checksum = host -> checksum (host -> buffers, host -> bufferCount);
+ }
+
+ if (shouldCompress > 0)
+ {
+ host -> buffers [1].data = host -> packetData [1];
+ host -> buffers [1].dataLength = shouldCompress;
+ host -> bufferCount = 2;
+ }
+
+ currentPeer -> lastSendTime = host -> serviceTime;
+
+ sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
+
+ enet_protocol_remove_sent_unreliable_commands (currentPeer);
+
+ if (sentLength < 0)
+ return -1;
+
+ host -> totalSentData += sentLength;
+ host -> totalSentPackets ++;
+ }
+
+ return 0;
+}
+
+/** Sends any queued packets on the host specified to its designated peers.
+
+ @param host host to flush
+ @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service().
+ @ingroup host
+*/
+void
+enet_host_flush (ENetHost * host)
+{
+ host -> serviceTime = enet_time_get ();
+
+ enet_protocol_send_outgoing_commands (host, NULL, 0);
+}
+
+/** Checks for any queued events on the host and dispatches one if available.
+
+ @param host host to check for events
+ @param event an event structure where event details will be placed if available
+ @retval > 0 if an event was dispatched
+ @retval 0 if no events are available
+ @retval < 0 on failure
+ @ingroup host
+*/
+int
+enet_host_check_events (ENetHost * host, ENetEvent * event)
+{
+ if (event == NULL) return -1;
+
+ event -> type = ENET_EVENT_TYPE_NONE;
+ event -> peer = NULL;
+ event -> packet = NULL;
+
+ return enet_protocol_dispatch_incoming_commands (host, event);
+}
+
+/** Waits for events on the host specified and shuttles packets between
+ the host and its peers.
+
+ @param host host to service
+ @param event an event structure where event details will be placed if one occurs
+ if event == NULL then no events will be delivered
+ @param timeout number of milliseconds that ENet should wait for events
+ @retval > 0 if an event occurred within the specified time limit
+ @retval 0 if no event occurred
+ @retval < 0 on failure
+ @remarks enet_host_service should be called fairly regularly for adequate performance
+ @ingroup host
+*/
+int
+enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
+{
+ enet_uint32 waitCondition;
+
+ if (event != NULL)
+ {
+ event -> type = ENET_EVENT_TYPE_NONE;
+ event -> peer = NULL;
+ event -> packet = NULL;
+
+ switch (enet_protocol_dispatch_incoming_commands (host, event))
+ {
+ case 1:
+ return 1;
+
+ case -1:
+ perror ("Error dispatching incoming packets");
+
+ return -1;
+
+ default:
+ break;
+ }
+ }
+
+ host -> serviceTime = enet_time_get ();
+
+ timeout += host -> serviceTime;
+
+ do
+ {
+ if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
+ enet_host_bandwidth_throttle (host);
+
+ switch (enet_protocol_send_outgoing_commands (host, event, 1))
+ {
+ case 1:
+ return 1;
+
+ case -1:
+ perror ("Error sending outgoing packets");
+
+ return -1;
+
+ default:
+ break;
+ }
+
+ switch (enet_protocol_receive_incoming_commands (host, event))
+ {
+ case 1:
+ return 1;
+
+ case -1:
+ perror ("Error receiving incoming packets");
+
+ return -1;
+
+ default:
+ break;
+ }
+
+ switch (enet_protocol_send_outgoing_commands (host, event, 1))
+ {
+ case 1:
+ return 1;
+
+ case -1:
+ perror ("Error sending outgoing packets");
+
+ return -1;
+
+ default:
+ break;
+ }
+
+ if (event != NULL)
+ {
+ switch (enet_protocol_dispatch_incoming_commands (host, event))
+ {
+ case 1:
+ return 1;
+
+ case -1:
+ perror ("Error dispatching incoming packets");
+
+ return -1;
+
+ default:
+ break;
+ }
+ }
+
+ host -> serviceTime = enet_time_get ();
+
+ if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
+ return 0;
+
+ waitCondition = ENET_SOCKET_WAIT_RECEIVE;
+
+ if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
+ return -1;
+
+ host -> serviceTime = enet_time_get ();
+ } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE);
+
+ return 0;
+}
+
diff --git a/src/enet/protocol.h b/src/enet/protocol.h
new file mode 100644
index 000000000..19f7e45de
--- /dev/null
+++ b/src/enet/protocol.h
@@ -0,0 +1,196 @@
+/**
+ @file protocol.h
+ @brief ENet protocol
+*/
+#ifndef __ENET_PROTOCOL_H__
+#define __ENET_PROTOCOL_H__
+
+#include "enet/types.h"
+
+enum
+{
+ ENET_PROTOCOL_MINIMUM_MTU = 576,
+ ENET_PROTOCOL_MAXIMUM_MTU = 4096,
+ ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
+ ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
+ ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
+ ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
+ ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
+ ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF
+};
+
+typedef enum _ENetProtocolCommand
+{
+ ENET_PROTOCOL_COMMAND_NONE = 0,
+ ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
+ ENET_PROTOCOL_COMMAND_CONNECT = 2,
+ ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
+ ENET_PROTOCOL_COMMAND_DISCONNECT = 4,
+ ENET_PROTOCOL_COMMAND_PING = 5,
+ ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
+ ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
+ ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
+ ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
+ ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
+ ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
+ ENET_PROTOCOL_COMMAND_COUNT = 12,
+
+ ENET_PROTOCOL_COMMAND_MASK = 0x0F
+} ENetProtocolCommand;
+
+typedef enum _ENetProtocolFlag
+{
+ ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
+ ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
+
+ ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
+ ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
+ ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
+
+ ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12),
+ ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
+} ENetProtocolFlag;
+
+#ifdef _MSC_VER_
+#pragma pack(push, 1)
+#define ENET_PACKED
+#elif defined(__GNUC__)
+#define ENET_PACKED __attribute__ ((packed))
+#else
+#define ENET_PACKED
+#endif
+
+typedef struct _ENetProtocolHeader
+{
+ enet_uint16 peerID;
+ enet_uint16 sentTime;
+} ENET_PACKED ENetProtocolHeader;
+
+typedef struct _ENetProtocolCommandHeader
+{
+ enet_uint8 command;
+ enet_uint8 channelID;
+ enet_uint16 reliableSequenceNumber;
+} ENET_PACKED ENetProtocolCommandHeader;
+
+typedef struct _ENetProtocolAcknowledge
+{
+ ENetProtocolCommandHeader header;
+ enet_uint16 receivedReliableSequenceNumber;
+ enet_uint16 receivedSentTime;
+} ENET_PACKED ENetProtocolAcknowledge;
+
+typedef struct _ENetProtocolConnect
+{
+ ENetProtocolCommandHeader header;
+ enet_uint16 outgoingPeerID;
+ enet_uint8 incomingSessionID;
+ enet_uint8 outgoingSessionID;
+ enet_uint32 mtu;
+ enet_uint32 windowSize;
+ enet_uint32 channelCount;
+ enet_uint32 incomingBandwidth;
+ enet_uint32 outgoingBandwidth;
+ enet_uint32 packetThrottleInterval;
+ enet_uint32 packetThrottleAcceleration;
+ enet_uint32 packetThrottleDeceleration;
+ enet_uint32 connectID;
+ enet_uint32 data;
+} ENET_PACKED ENetProtocolConnect;
+
+typedef struct _ENetProtocolVerifyConnect
+{
+ ENetProtocolCommandHeader header;
+ enet_uint16 outgoingPeerID;
+ enet_uint8 incomingSessionID;
+ enet_uint8 outgoingSessionID;
+ enet_uint32 mtu;
+ enet_uint32 windowSize;
+ enet_uint32 channelCount;
+ enet_uint32 incomingBandwidth;
+ enet_uint32 outgoingBandwidth;
+ enet_uint32 packetThrottleInterval;
+ enet_uint32 packetThrottleAcceleration;
+ enet_uint32 packetThrottleDeceleration;
+ enet_uint32 connectID;
+} ENET_PACKED ENetProtocolVerifyConnect;
+
+typedef struct _ENetProtocolBandwidthLimit
+{
+ ENetProtocolCommandHeader header;
+ enet_uint32 incomingBandwidth;
+ enet_uint32 outgoingBandwidth;
+} ENET_PACKED ENetProtocolBandwidthLimit;
+
+typedef struct _ENetProtocolThrottleConfigure
+{
+ ENetProtocolCommandHeader header;
+ enet_uint32 packetThrottleInterval;
+ enet_uint32 packetThrottleAcceleration;
+ enet_uint32 packetThrottleDeceleration;
+} ENET_PACKED ENetProtocolThrottleConfigure;
+
+typedef struct _ENetProtocolDisconnect
+{
+ ENetProtocolCommandHeader header;
+ enet_uint32 data;
+} ENET_PACKED ENetProtocolDisconnect;
+
+typedef struct _ENetProtocolPing
+{
+ ENetProtocolCommandHeader header;
+} ENET_PACKED ENetProtocolPing;
+
+typedef struct _ENetProtocolSendReliable
+{
+ ENetProtocolCommandHeader header;
+ enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendReliable;
+
+typedef struct _ENetProtocolSendUnreliable
+{
+ ENetProtocolCommandHeader header;
+ enet_uint16 unreliableSequenceNumber;
+ enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendUnreliable;
+
+typedef struct _ENetProtocolSendUnsequenced
+{
+ ENetProtocolCommandHeader header;
+ enet_uint16 unsequencedGroup;
+ enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendUnsequenced;
+
+typedef struct _ENetProtocolSendFragment
+{
+ ENetProtocolCommandHeader header;
+ enet_uint16 startSequenceNumber;
+ enet_uint16 dataLength;
+ enet_uint32 fragmentCount;
+ enet_uint32 fragmentNumber;
+ enet_uint32 totalLength;
+ enet_uint32 fragmentOffset;
+} ENET_PACKED ENetProtocolSendFragment;
+
+typedef union _ENetProtocol
+{
+ ENetProtocolCommandHeader header;
+ ENetProtocolAcknowledge acknowledge;
+ ENetProtocolConnect connect;
+ ENetProtocolVerifyConnect verifyConnect;
+ ENetProtocolDisconnect disconnect;
+ ENetProtocolPing ping;
+ ENetProtocolSendReliable sendReliable;
+ ENetProtocolSendUnreliable sendUnreliable;
+ ENetProtocolSendUnsequenced sendUnsequenced;
+ ENetProtocolSendFragment sendFragment;
+ ENetProtocolBandwidthLimit bandwidthLimit;
+ ENetProtocolThrottleConfigure throttleConfigure;
+} ENET_PACKED ENetProtocol;
+
+#ifdef _MSC_VER_
+#pragma pack(pop)
+#endif
+
+#endif /* __ENET_PROTOCOL_H__ */
+
diff --git a/src/enet/time.h b/src/enet/time.h
new file mode 100644
index 000000000..c82a54603
--- /dev/null
+++ b/src/enet/time.h
@@ -0,0 +1,18 @@
+/**
+ @file time.h
+ @brief ENet time constants and macros
+*/
+#ifndef __ENET_TIME_H__
+#define __ENET_TIME_H__
+
+#define ENET_TIME_OVERFLOW 86400000
+
+#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
+#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
+#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
+#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
+
+#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
+
+#endif /* __ENET_TIME_H__ */
+
diff --git a/src/enet/types.h b/src/enet/types.h
new file mode 100644
index 000000000..ab010a4b1
--- /dev/null
+++ b/src/enet/types.h
@@ -0,0 +1,13 @@
+/**
+ @file types.h
+ @brief type definitions for ENet
+*/
+#ifndef __ENET_TYPES_H__
+#define __ENET_TYPES_H__
+
+typedef unsigned char enet_uint8; /**< unsigned 8-bit type */
+typedef unsigned short enet_uint16; /**< unsigned 16-bit type */
+typedef unsigned int enet_uint32; /**< unsigned 32-bit type */
+
+#endif /* __ENET_TYPES_H__ */
+
diff --git a/src/enet/unix.c b/src/enet/unix.c
new file mode 100644
index 000000000..9cb26692f
--- /dev/null
+++ b/src/enet/unix.c
@@ -0,0 +1,443 @@
+/**
+ @file unix.c
+ @brief ENet Unix system specific functions
+*/
+#ifndef WIN32
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+#ifdef HAS_FCNTL
+#include <fcntl.h>
+#endif
+
+#ifdef __APPLE__
+#undef HAS_POLL
+#endif
+
+#ifdef HAS_POLL
+#include <sys/poll.h>
+#endif
+
+
+#ifndef HAS_SOCKLEN_T
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+//typedef int socklen_t;
+#endif
+#endif
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+ return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+}
+
+enet_uint32
+enet_time_get (void)
+{
+ struct timeval timeVal;
+
+ gettimeofday (& timeVal, NULL);
+
+ return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+ struct timeval timeVal;
+
+ gettimeofday (& timeVal, NULL);
+
+ timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
+}
+
+int
+enet_address_set_host (ENetAddress * address, const char * name)
+{
+ struct hostent * hostEntry = NULL;
+#ifdef HAS_GETHOSTBYNAME_R
+ struct hostent hostData;
+ char buffer [2048];
+ int errnum;
+
+#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+#else
+ hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
+#endif
+#else
+ hostEntry = gethostbyname (name);
+#endif
+
+ if (hostEntry == NULL ||
+ hostEntry -> h_addrtype != AF_INET)
+ {
+#ifdef HAS_INET_PTON
+ if (! inet_pton (AF_INET, name, & address -> host))
+#else
+ if (! inet_aton (name, (struct in_addr *) & address -> host))
+#endif
+ return -1;
+ return 0;
+ }
+
+ address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+ return 0;
+}
+
+int
+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+{
+#ifdef HAS_INET_NTOP
+ if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
+#else
+ char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+ if (addr != NULL)
+ strncpy (name, addr, nameLength);
+ else
+#endif
+ return -1;
+ return 0;
+}
+
+int
+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
+{
+ struct in_addr in;
+ struct hostent * hostEntry = NULL;
+#ifdef HAS_GETHOSTBYADDR_R
+ struct hostent hostData;
+ char buffer [2048];
+ int errnum;
+
+ in.s_addr = address -> host;
+
+#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+#else
+ hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
+#endif
+#else
+ in.s_addr = address -> host;
+
+ hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
+#endif
+
+ if (hostEntry == NULL)
+ return enet_address_get_host_ip (address, name, nameLength);
+
+ strncpy (name, hostEntry -> h_name, nameLength);
+
+ return 0;
+}
+
+int
+enet_socket_bind (ENetSocket socket, const ENetAddress * address)
+{
+ struct sockaddr_in sin;
+
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+
+ if (address != NULL)
+ {
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+ }
+ else
+ {
+ sin.sin_port = 0;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ }
+
+ return bind (socket,
+ (struct sockaddr *) & sin,
+ sizeof (struct sockaddr_in));
+}
+
+int
+enet_socket_listen (ENetSocket socket, int backlog)
+{
+ return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type)
+{
+ return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+}
+
+int
+enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+{
+ int result = -1;
+ switch (option)
+ {
+ case ENET_SOCKOPT_NONBLOCK:
+#ifdef HAS_FCNTL
+ result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
+#else
+ result = ioctl (socket, FIONBIO, & value);
+#endif
+ break;
+
+ case ENET_SOCKOPT_BROADCAST:
+ result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
+ break;
+
+ case ENET_SOCKOPT_REUSEADDR:
+ result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
+ break;
+
+ case ENET_SOCKOPT_RCVBUF:
+ result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
+ break;
+
+ case ENET_SOCKOPT_SNDBUF:
+ result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
+ break;
+
+ default:
+ break;
+ }
+ return result == -1 ? -1 : 0;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+ struct sockaddr_in sin;
+
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+
+ return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+ int result;
+ struct sockaddr_in sin;
+ socklen_t sinLength = sizeof (struct sockaddr_in);
+
+ result = accept (socket,
+ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL);
+
+ if (result == -1)
+ return ENET_SOCKET_NULL;
+
+ if (address != NULL)
+ {
+ address -> host = (enet_uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
+
+ return result;
+}
+
+void
+enet_socket_destroy (ENetSocket socket)
+{
+ close (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+ const ENetAddress * address,
+ const ENetBuffer * buffers,
+ size_t bufferCount)
+{
+ struct msghdr msgHdr;
+ struct sockaddr_in sin;
+ int sentLength;
+
+ memset (& msgHdr, 0, sizeof (struct msghdr));
+
+ if (address != NULL)
+ {
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+
+ msgHdr.msg_name = & sin;
+ msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+ }
+
+ msgHdr.msg_iov = (struct iovec *) buffers;
+ msgHdr.msg_iovlen = bufferCount;
+
+ sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
+
+ if (sentLength == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ return 0;
+
+ return -1;
+ }
+
+ return sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+ ENetAddress * address,
+ ENetBuffer * buffers,
+ size_t bufferCount)
+{
+ struct msghdr msgHdr;
+ struct sockaddr_in sin;
+ int recvLength;
+
+ memset (& msgHdr, 0, sizeof (struct msghdr));
+
+ if (address != NULL)
+ {
+ msgHdr.msg_name = & sin;
+ msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+ }
+
+ msgHdr.msg_iov = (struct iovec *) buffers;
+ msgHdr.msg_iovlen = bufferCount;
+
+ recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
+
+ if (recvLength == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ return 0;
+
+ return -1;
+ }
+
+#ifdef HAS_MSGHDR_FLAGS
+ if (msgHdr.msg_flags & MSG_TRUNC)
+ return -1;
+#endif
+
+ if (address != NULL)
+ {
+ address -> host = (enet_uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
+
+ return recvLength;
+}
+
+int
+enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
+{
+ struct timeval timeVal;
+
+ timeVal.tv_sec = timeout / 1000;
+ timeVal.tv_usec = (timeout % 1000) * 1000;
+
+ return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+#ifdef HAS_POLL
+ struct pollfd pollSocket;
+ int pollCount;
+
+ pollSocket.fd = socket;
+ pollSocket.events = 0;
+
+ if (* condition & ENET_SOCKET_WAIT_SEND)
+ pollSocket.events |= POLLOUT;
+
+ if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+ pollSocket.events |= POLLIN;
+
+ pollCount = poll (& pollSocket, 1, timeout);
+
+ if (pollCount < 0)
+ return -1;
+
+ * condition = ENET_SOCKET_WAIT_NONE;
+
+ if (pollCount == 0)
+ return 0;
+
+ if (pollSocket.revents & POLLOUT)
+ * condition |= ENET_SOCKET_WAIT_SEND;
+
+ if (pollSocket.revents & POLLIN)
+ * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+ return 0;
+#else
+ fd_set readSet, writeSet;
+ struct timeval timeVal;
+ int selectCount;
+
+ timeVal.tv_sec = timeout / 1000;
+ timeVal.tv_usec = (timeout % 1000) * 1000;
+
+ FD_ZERO (& readSet);
+ FD_ZERO (& writeSet);
+
+ if (* condition & ENET_SOCKET_WAIT_SEND)
+ FD_SET (socket, & writeSet);
+
+ if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+ FD_SET (socket, & readSet);
+
+ selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+ if (selectCount < 0)
+ return -1;
+
+ * condition = ENET_SOCKET_WAIT_NONE;
+
+ if (selectCount == 0)
+ return 0;
+
+ if (FD_ISSET (socket, & writeSet))
+ * condition |= ENET_SOCKET_WAIT_SEND;
+
+ if (FD_ISSET (socket, & readSet))
+ * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+ return 0;
+#endif
+}
+
+#endif
+
diff --git a/src/enet/unix.h b/src/enet/unix.h
new file mode 100644
index 000000000..087015e51
--- /dev/null
+++ b/src/enet/unix.h
@@ -0,0 +1,45 @@
+/**
+ @file unix.h
+ @brief ENet Unix header
+*/
+#ifndef __ENET_UNIX_H__
+#define __ENET_UNIX_H__
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+typedef int ENetSocket;
+
+enum
+{
+ ENET_SOCKET_NULL = -1
+};
+
+#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
+#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
+
+#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
+#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
+
+typedef struct
+{
+ void * data;
+ size_t dataLength;
+} ENetBuffer;
+
+#define ENET_CALLBACK
+
+#define ENET_API extern
+
+typedef fd_set ENetSocketSet;
+
+#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
+#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
+#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
+#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
+
+#endif /* __ENET_UNIX_H__ */
+
diff --git a/src/enet/utility.h b/src/enet/utility.h
new file mode 100644
index 000000000..e48a476be
--- /dev/null
+++ b/src/enet/utility.h
@@ -0,0 +1,12 @@
+/**
+ @file utility.h
+ @brief ENet utility header
+*/
+#ifndef __ENET_UTILITY_H__
+#define __ENET_UTILITY_H__
+
+#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
+#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#endif /* __ENET_UTILITY_H__ */
+
diff --git a/src/enet/win32.c b/src/enet/win32.c
new file mode 100644
index 000000000..e1fae2330
--- /dev/null
+++ b/src/enet/win32.c
@@ -0,0 +1,348 @@
+/**
+ @file win32.c
+ @brief ENet Win32 system specific functions
+*/
+#ifdef WIN32
+
+#include <time.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+ WORD versionRequested = MAKEWORD (1, 1);
+ WSADATA wsaData;
+
+ if (WSAStartup (versionRequested, & wsaData))
+ return -1;
+
+ if (LOBYTE (wsaData.wVersion) != 1||
+ HIBYTE (wsaData.wVersion) != 1)
+ {
+ WSACleanup ();
+
+ return -1;
+ }
+
+ timeBeginPeriod (1);
+
+ return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+ timeEndPeriod (1);
+
+ WSACleanup ();
+}
+
+enet_uint32
+enet_time_get (void)
+{
+ return (enet_uint32) timeGetTime () - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+ timeBase = (enet_uint32) timeGetTime () - newTimeBase;
+}
+
+int
+enet_address_set_host (ENetAddress * address, const char * name)
+{
+ struct hostent * hostEntry;
+
+ hostEntry = gethostbyname (name);
+ if (hostEntry == NULL ||
+ hostEntry -> h_addrtype != AF_INET)
+ {
+ unsigned long host = inet_addr (name);
+ if (host == INADDR_NONE)
+ return -1;
+ address -> host = host;
+ return 0;
+ }
+
+ address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+ return 0;
+}
+
+int
+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+{
+ char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+ if (addr == NULL)
+ return -1;
+ strncpy (name, addr, nameLength);
+ return 0;
+}
+
+int
+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
+{
+ struct in_addr in;
+ struct hostent * hostEntry;
+
+ in.s_addr = address -> host;
+
+ hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
+ if (hostEntry == NULL)
+ return enet_address_get_host_ip (address, name, nameLength);
+
+ strncpy (name, hostEntry -> h_name, nameLength);
+
+ return 0;
+}
+
+int
+enet_socket_bind (ENetSocket socket, const ENetAddress * address)
+{
+ struct sockaddr_in sin;
+
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+
+ if (address != NULL)
+ {
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+ }
+ else
+ {
+ sin.sin_port = 0;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ }
+
+ return bind (socket,
+ (struct sockaddr *) & sin,
+ sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+}
+
+int
+enet_socket_listen (ENetSocket socket, int backlog)
+{
+ return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type)
+{
+ return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+}
+
+int
+enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+{
+ int result = SOCKET_ERROR;
+ switch (option)
+ {
+ case ENET_SOCKOPT_NONBLOCK:
+ {
+ u_long nonBlocking = (u_long) value;
+ result = ioctlsocket (socket, FIONBIO, & nonBlocking);
+ break;
+ }
+
+ case ENET_SOCKOPT_BROADCAST:
+ result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
+ break;
+
+ case ENET_SOCKOPT_REUSEADDR:
+ result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
+ break;
+
+ case ENET_SOCKOPT_RCVBUF:
+ result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
+ break;
+
+ case ENET_SOCKOPT_SNDBUF:
+ result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
+ break;
+
+ default:
+ break;
+ }
+ return result == SOCKET_ERROR ? -1 : 0;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+ struct sockaddr_in sin;
+
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+
+ return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+ SOCKET result;
+ struct sockaddr_in sin;
+ int sinLength = sizeof (struct sockaddr_in);
+
+ result = accept (socket,
+ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL);
+
+ if (result == INVALID_SOCKET)
+ return ENET_SOCKET_NULL;
+
+ if (address != NULL)
+ {
+ address -> host = (enet_uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
+
+ return result;
+}
+
+void
+enet_socket_destroy (ENetSocket socket)
+{
+ closesocket (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+ const ENetAddress * address,
+ const ENetBuffer * buffers,
+ size_t bufferCount)
+{
+ struct sockaddr_in sin;
+ DWORD sentLength;
+
+ if (address != NULL)
+ {
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+ }
+
+ if (WSASendTo (socket,
+ (LPWSABUF) buffers,
+ (DWORD) bufferCount,
+ & sentLength,
+ 0,
+ address != NULL ? (struct sockaddr *) & sin : 0,
+ address != NULL ? sizeof (struct sockaddr_in) : 0,
+ NULL,
+ NULL) == SOCKET_ERROR)
+ {
+ if (WSAGetLastError () == WSAEWOULDBLOCK)
+ return 0;
+
+ return -1;
+ }
+
+ return (int) sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+ ENetAddress * address,
+ ENetBuffer * buffers,
+ size_t bufferCount)
+{
+ INT sinLength = sizeof (struct sockaddr_in);
+ DWORD flags = 0,
+ recvLength;
+ struct sockaddr_in sin;
+
+ if (WSARecvFrom (socket,
+ (LPWSABUF) buffers,
+ (DWORD) bufferCount,
+ & recvLength,
+ & flags,
+ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL,
+ NULL,
+ NULL) == SOCKET_ERROR)
+ {
+ switch (WSAGetLastError ())
+ {
+ case WSAEWOULDBLOCK:
+ case WSAECONNRESET:
+ return 0;
+ }
+
+ return -1;
+ }
+
+ if (flags & MSG_PARTIAL)
+ return -1;
+
+ if (address != NULL)
+ {
+ address -> host = (enet_uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
+
+ return (int) recvLength;
+}
+
+int
+enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
+{
+ struct timeval timeVal;
+
+ timeVal.tv_sec = timeout / 1000;
+ timeVal.tv_usec = (timeout % 1000) * 1000;
+
+ return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+ fd_set readSet, writeSet;
+ struct timeval timeVal;
+ int selectCount;
+
+ timeVal.tv_sec = timeout / 1000;
+ timeVal.tv_usec = (timeout % 1000) * 1000;
+
+ FD_ZERO (& readSet);
+ FD_ZERO (& writeSet);
+
+ if (* condition & ENET_SOCKET_WAIT_SEND)
+ FD_SET (socket, & writeSet);
+
+ if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+ FD_SET (socket, & readSet);
+
+ selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+ if (selectCount < 0)
+ return -1;
+
+ * condition = ENET_SOCKET_WAIT_NONE;
+
+ if (selectCount == 0)
+ return 0;
+
+ if (FD_ISSET (socket, & writeSet))
+ * condition |= ENET_SOCKET_WAIT_SEND;
+
+ if (FD_ISSET (socket, & readSet))
+ * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+ return 0;
+}
+
+#endif
+
diff --git a/src/enet/win32.h b/src/enet/win32.h
new file mode 100644
index 000000000..0e1cf0c5a
--- /dev/null
+++ b/src/enet/win32.h
@@ -0,0 +1,58 @@
+/**
+ @file win32.h
+ @brief ENet Win32 header
+*/
+#ifndef __ENET_WIN32_H__
+#define __ENET_WIN32_H__
+
+#ifdef ENET_BUILDING_LIB
+#pragma warning (disable: 4996) // 'strncpy' was declared deprecated
+#pragma warning (disable: 4267) // size_t to int conversion
+#pragma warning (disable: 4244) // 64bit to 32bit int
+#pragma warning (disable: 4018) // signed/unsigned mismatch
+#endif
+
+#include <stdlib.h>
+#include <winsock2.h>
+
+typedef SOCKET ENetSocket;
+
+enum
+{
+ ENET_SOCKET_NULL = INVALID_SOCKET
+};
+
+#define ENET_HOST_TO_NET_16(value) (htons (value))
+#define ENET_HOST_TO_NET_32(value) (htonl (value))
+
+#define ENET_NET_TO_HOST_16(value) (ntohs (value))
+#define ENET_NET_TO_HOST_32(value) (ntohl (value))
+
+typedef struct
+{
+ size_t dataLength;
+ void * data;
+} ENetBuffer;
+
+#define ENET_CALLBACK __cdecl
+
+#if defined ENET_DLL
+#if defined ENET_BUILDING_LIB
+#define ENET_API __declspec( dllexport )
+#else
+#define ENET_API __declspec( dllimport )
+#endif /* ENET_BUILDING_LIB */
+#else /* !ENET_DLL */
+#define ENET_API extern
+#endif /* ENET_DLL */
+
+typedef fd_set ENetSocketSet;
+
+#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
+#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
+#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
+#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
+
+#endif /* __ENET_WIN32_H__ */
+
+
diff --git a/src/equipment.h b/src/equipment.h
new file mode 100644
index 000000000..24f7174fd
--- /dev/null
+++ b/src/equipment.h
@@ -0,0 +1,94 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EQUIPMENT_H
+#define EQUIPMENT_H
+
+#define EQUIPMENT_SIZE 13
+
+class Item;
+
+class Equipment
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Equipment(): mBackend(0)
+ { }
+
+ /**
+ * Destructor.
+ */
+ ~Equipment()
+ { mBackend = 0; }
+
+ enum Slot
+ {
+ EQUIP_TORSO_SLOT = 0,
+ EQUIP_GLOVES_SLOT = 1,
+ EQUIP_HEAD_SLOT = 2,
+ EQUIP_LEGS_SLOT = 3,
+ EQUIP_FEET_SLOT = 4,
+ EQUIP_RING1_SLOT = 5,
+ EQUIP_RING2_SLOT = 6,
+ EQUIP_NECK_SLOT = 7,
+ EQUIP_FIGHT1_SLOT = 8,
+ EQUIP_FIGHT2_SLOT = 9,
+ EQUIP_PROJECTILE_SLOT = 10,
+ EQUIP_EVOL_RING1_SLOT = 11,
+ EQUIP_EVOL_RING2_SLOT = 12,
+ EQUIP_VECTOREND
+ };
+
+ class Backend
+ {
+ public:
+ virtual Item *getEquipment(int index) const = 0;
+ virtual void clear() = 0;
+ virtual ~Backend() { }
+ };
+
+ /**
+ * Get equipment at the given slot.
+ */
+ Item *getEquipment(int index) const
+ { return mBackend ? mBackend->getEquipment(index) : 0; }
+
+ /**
+ * Clears equipment.
+ */
+ void clear()
+ { if (mBackend) mBackend->clear(); }
+
+ /**
+ * Set equipment at the given slot.
+ */
+ void setEquipment(int index, int id, int quantity = 0);
+
+ void setBackend(Backend *backend)
+ { mBackend = backend; }
+
+ private:
+ Backend *mBackend;
+};
+
+#endif
diff --git a/src/event.cpp b/src/event.cpp
new file mode 100644
index 000000000..1a48bddf8
--- /dev/null
+++ b/src/event.cpp
@@ -0,0 +1,142 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "event.h"
+
+#include "listener.h"
+#include "variabledata.h"
+
+namespace Mana
+{
+
+ListenMap Event::mBindings;
+
+Event::~Event()
+{
+ VariableMap::iterator it = mData.begin();
+ while (it != mData.end())
+ {
+ delete it->second;
+ it->second = 0;
+ it++;
+ }
+}
+
+void Event::setInt(const std::string &key, int value) throw (BadEvent)
+{
+ if (mData.find(key) != mData.end())
+ throw KEY_ALREADY_EXISTS;
+
+ mData[key] = new IntData(value);
+}
+
+int Event::getInt(const std::string &key) const throw (BadEvent)
+{
+ VariableMap::const_iterator it = mData.find(key);
+ if (it == mData.end())
+ throw BAD_KEY;
+
+ if (it->second->getType() != VariableData::DATA_INT)
+ throw BAD_VALUE;
+
+ return static_cast<IntData *>(it->second)->getData();
+}
+
+void Event::setString(const std::string &key,
+ const std::string &value) throw (BadEvent)
+{
+ if (mData.find(key) != mData.end())
+ throw KEY_ALREADY_EXISTS;
+
+ mData[key] = new StringData(value);
+}
+
+const std::string &Event::getString(const std::string &key)
+ const throw (BadEvent)
+{
+ VariableMap::const_iterator it = mData.find(key);
+ if (it == mData.end())
+ throw BAD_KEY;
+
+ if (it->second->getType() != VariableData::DATA_STRING)
+ throw BAD_VALUE;
+
+ return static_cast<StringData *>(it->second)->getData();
+}
+
+
+void Event::setFloat(const std::string &key, double value) throw (BadEvent)
+{
+ if (mData.find(key) != mData.end())
+ throw KEY_ALREADY_EXISTS;
+
+ mData[key] = new FloatData(value);
+}
+
+double Event::getFloat(const std::string &key) const throw (BadEvent)
+{
+ VariableMap::const_iterator it = mData.find(key);
+ if (it == mData.end())
+ throw BAD_KEY;
+
+ if (it->second->getType() != VariableData::DATA_FLOAT)
+ throw BAD_VALUE;
+
+ return static_cast<FloatData *>(it->second)->getData();
+}
+
+void Event::trigger(Channels channel, const Event &event)
+{
+ ListenMap::iterator it = mBindings.find(channel);
+
+ // Make sure something is listening
+ if (it == mBindings.end())
+ return;
+
+ // Loop though all listeners
+ ListenerSet::iterator lit = it->second.begin();
+ while (lit != it->second.end())
+ {
+ (*lit)->event(channel, event);
+ lit++;
+ }
+}
+
+void Event::remove(Listener *listener)
+{
+ ListenMap::iterator it = mBindings.begin();
+ while (it != mBindings.end())
+ {
+ it->second.erase(listener);
+ it++;
+ }
+}
+
+void Event::bind(Listener *listener, Channels channel)
+{
+ mBindings[channel].insert(listener);
+}
+
+void Event::unbind(Listener *listener, Channels channel)
+{
+ mBindings[channel].erase(listener);
+}
+
+}
diff --git a/src/event.h b/src/event.h
new file mode 100644
index 000000000..2b878537d
--- /dev/null
+++ b/src/event.h
@@ -0,0 +1,175 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EVENT_H
+#define EVENT_H
+
+#include <map>
+#include <set>
+#include <string>
+
+enum Channels
+{
+ CHANNEL_ACTORSPRITE = 0,
+ CHANNEL_ATTRIBUTES,
+ CHANNEL_BUYSELL,
+ CHANNEL_CHAT,
+ CHANNEL_CLIENT,
+ CHANNEL_GAME,
+ CHANNEL_ITEM,
+ CHANNEL_NOTICES,
+ CHANNEL_NPC,
+ CHANNEL_STATUS,
+ CHANNEL_STORAGE
+};
+
+enum Events
+{
+ EVENT_ANNOUNCEMENT = 0,
+ EVENT_BEING,
+ EVENT_CLOSE,
+ EVENT_CLOSEALL,
+ EVENT_CONSTRUCTED,
+ EVENT_DBSLOADING,
+ EVENT_DESTROYED,
+ EVENT_DESTRUCTED,
+ EVENT_DESTRUCTING,
+ EVENT_DOCLOSE,
+ EVENT_DOCLOSEINVENTORY,
+ EVENT_DODROP,
+ EVENT_DOEQUIP,
+ EVENT_DOINTEGERINPUT,
+ EVENT_DOMENU,
+ EVENT_DOMOVE,
+ EVENT_DONEXT,
+ EVENT_DOSENDLETTER,
+ EVENT_DOSPLIT,
+ EVENT_DOSTRINGINPUT,
+ EVENT_DOTALK,
+ EVENT_DOUNEQUIP,
+ EVENT_DOUSE,
+ EVENT_END,
+ EVENT_ENGINESINITALIZED,
+ EVENT_ENGINESINITALIZING,
+ EVENT_GUIWINDOWSLOADED,
+ EVENT_GUIWINDOWSLOADING,
+ EVENT_GUIWINDOWSUNLOADED,
+ EVENT_GUIWINDOWSUNLOADING,
+ EVENT_INTEGERINPUT,
+ EVENT_MAPLOADED,
+ EVENT_MENU,
+ EVENT_MESSAGE,
+ EVENT_NEXT,
+ EVENT_NPCCOUNT,
+ EVENT_PLAYER,
+ EVENT_POST,
+ EVENT_POSTCOUNT,
+ EVENT_SERVERNOTICE,
+ EVENT_STATECHANGE,
+ EVENT_STORAGECOUNT,
+ EVENT_STRINGINPUT,
+ EVENT_STUN,
+ EVENT_TRADING,
+ EVENT_UPDATEATTRIBUTE,
+ EVENT_UPDATESTAT,
+ EVENT_UPDATESTATUSEFFECT,
+ EVENT_WHISPER,
+ EVENT_WHISPERERROR
+};
+
+namespace Mana
+{
+
+// Possible exception that can be thrown
+enum BadEvent
+{
+ BAD_KEY = 0,
+ BAD_VALUE,
+ KEY_ALREADY_EXISTS
+};
+
+class Listener;
+class VariableData;
+typedef std::map<std::string, VariableData *> VariableMap;
+
+typedef std::set<Listener *> ListenerSet;
+typedef std::map<Channels, ListenerSet > ListenMap;
+
+#define SERVER_NOTICE(message) { \
+Mana::Event event(EVENT_SERVERNOTICE); \
+event.setString("message", message); \
+Mana::Event::trigger(CHANNEL_NOTICES, event); }
+
+class Event
+{
+ public:
+ // String passed can be retivered with getName()
+ // and is to used to identify what type of event
+ // this is.
+ Event(Events name)
+ { mEventName = name; }
+
+ ~Event();
+
+ Events getName() const
+ { return mEventName; }
+
+ // Sets or gets a interger with a key to identify
+ void setInt(const std::string &key, int value)
+ throw (BadEvent);
+
+ int getInt(const std::string &key)
+ const throw (BadEvent);
+
+ // Sets or gets a string with a key to identify
+ void setString(const std::string &key,
+ const std::string &value)
+ throw (BadEvent);
+
+ const std::string &getString(const std::string &key)
+ const throw (BadEvent);
+
+ // Sets or gets a floating point number with key to identify
+ void setFloat(const std::string &key, double value)
+ throw (BadEvent);
+ double getFloat(const std::string &key)
+ const throw (BadEvent);
+
+ // Sends event to all listener on the channel
+ static void trigger(Channels channel, const Event &event);
+
+ // Removes a listener from all channels
+ static void remove(Listener *listener);
+
+ // Adds or removes a listener to a channel.
+ static void bind(Listener *listener, Channels channel);
+ static void unbind(Listener *listener, Channels channel);
+
+ private:
+ Events mEventName;
+
+ static ListenMap mBindings;
+
+ VariableMap mData;
+};
+
+} // namespace Mana
+
+#endif
diff --git a/src/filefilter.txt b/src/filefilter.txt
new file mode 100644
index 000000000..87431bf29
--- /dev/null
+++ b/src/filefilter.txt
@@ -0,0 +1,26 @@
+~ RULE_3_1_A_do_not_start_filename_with_underbar
+~ RULE_3_2_B_do_not_use_same_filename_more_than_once
+~ RULE_3_2_CD_do_not_use_special_characters_in_filename
+~ RULE_3_2_H_do_not_use_uppercase_for_c_filename
+~ RULE_3_3_A_start_function_name_with_lowercase_unix
+~ RULE_4_1_A_B_use_space_for_indentation
+~ RULE_4_1_B_indent_each_enum_item_in_enum_block
+~ RULE_4_1_B_locate_each_enum_item_in_seperate_line
+~ RULE_4_1_C_align_long_function_parameter_list
+~ RULE_4_1_E_align_conditions
+~ RULE_4_2_A_A_space_around_operator
+~ RULE_4_2_A_B_space_around_word
+~ RULE_4_4_A_do_not_write_over_80_columns_per_line
+~ RULE_4_5_A_brace_for_namespace_should_be_located_in_seperate_line
+~ RULE_4_5_A_braces_for_function_definition_should_be_located_in_seperate_line
+~ RULE_4_5_A_braces_for_type_definition_should_be_located_in_seperate_line
+~ RULE_4_5_A_indent_blocks_inside_of_function
+~ RULE_4_5_A_matching_braces_inside_of_function_should_be_located_same_column
+~ RULE_6_1_A_do_not_omit_function_parameter_names
+~ RULE_6_4_B_initialize_first_item_of_enum
+~ RULE_6_5_B_do_not_use_lowercase_for_macro_constants
+~ RULE_7_1_B_A_do_not_use_double_assignment
+~ RULE_7_2_B_do_not_use_goto_statement
+~ RULE_8_1_A_provide_file_info_comment
+~ RULE_9_1_A_do_not_use_hardcorded_include_path
+~ RULE_9_2_D_use_reentrant_function
diff --git a/src/filefilter_more.txt b/src/filefilter_more.txt
new file mode 100644
index 000000000..f0f37e03a
--- /dev/null
+++ b/src/filefilter_more.txt
@@ -0,0 +1,12 @@
+~ RULE_6_2_A_do_not_use_system_dependent_type
+~ RULE_3_2_F_use_representitive_classname_for_cpp_filename
+~ RULE_6_5_B_do_not_use_macro_for_constants
+~ RULE_A_3_avoid_too_deep_blocks
+~ RULE_6_1_G_write_less_than_200_lines_for_function
+
+~ RULE_5_2_C_provide_doxygen_class_comment_on_class_def
+~ RULE_5_2_C_provide_doxygen_namespace_comment_on_namespace_def
+~ RULE_5_2_C_provide_doxygen_struct_comment_on_struct_def
+~ RULE_5_3_A_provide_doxygen_function_comment_on_function_in_header
+~ RULE_5_3_A_provide_doxygen_function_comment_on_function_in_impl
+~ RULE_6_1_E_do_not_use_more_than_5_paramters_in_function
diff --git a/src/flooritem.cpp b/src/flooritem.cpp
new file mode 100644
index 000000000..b669bece3
--- /dev/null
+++ b/src/flooritem.cpp
@@ -0,0 +1,133 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "flooritem.h"
+
+#include "client.h"
+#include "graphics.h"
+#include "item.h"
+#include "map.h"
+#include "configuration.h"
+
+#include "gui/gui.h"
+#include "gui/truetypefont.h"
+
+#include "net/net.h"
+
+#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
+
+FloorItem::FloorItem(int id,
+ int itemId,
+ int x,
+ int y,
+ Map *map,
+ int amount):
+ ActorSprite(id),
+ mItemId(itemId),
+ mX(x),
+ mY(y),
+ mMap(map),
+// mAlpha(1.0f),
+ mAmount(amount),
+ mPickupCount(0)
+{
+ mDropTime = cur_time;
+
+ setMap(map);
+ if (map)
+ {
+ // TODO: Eventually, we probably should fix all sprite offsets so that
+ // these translations aren't necessary anymore. The sprites know
+ // best where their base point should be.
+ mPos.x = static_cast<float>(x * map->getTileWidth() + 16);
+ mPos.y = static_cast<float>(y * map->getTileHeight() +
+ ((Net::getNetworkType() == ServerInfo::MANASERV) ? 15 : 32));
+ }
+ else
+ {
+ mPos.x = 0;
+ mPos.y = 0;
+ }
+
+ setupSpriteDisplay(ItemDB::get(itemId).getDisplay());
+}
+
+const ItemInfo &FloorItem::getInfo() const
+{
+ return ItemDB::get(mItemId);
+}
+
+bool FloorItem::draw(Graphics *graphics, int offsetX, int offsetY) const
+{
+ if (!mMap)
+ return false;
+
+ const int dx = 32;
+ const int dy = 32;
+
+ const int x = mX * mMap->getTileWidth() + offsetX;
+ const int y = mY * mMap->getTileHeight() + offsetY;
+ gcn::Font *font = 0;
+ const bool highl = config.getBoolValue("floorItemsHighlight");
+
+ if (highl)
+ {
+ int curTime = cur_time;
+ font = gui->getFont();
+ if (mDropTime < curTime)
+ {
+ if (curTime > mDropTime + 28 && curTime < mDropTime + 50)
+ {
+ graphics->setColor(gcn::Color(80, 200, 20, 200));
+ graphics->fillRectangle(gcn::Rectangle(
+ x, y, dx, dy));
+ }
+ else if (curTime > mDropTime + 19
+ && curTime < mDropTime + 28)
+ {
+ graphics->setColor(gcn::Color(200, 80, 20,
+ 80 + 10 * (curTime - mDropTime - 18)));
+ graphics->fillRectangle(gcn::Rectangle(
+ x, y, dx, dy));
+ }
+ else if (curTime > mDropTime && curTime < mDropTime + 20)
+ {
+ graphics->setColor(gcn::Color(20, 20, 255,
+ 7 * (curTime - mDropTime)));
+ graphics->fillRectangle(gcn::Rectangle(
+ x, y, dx, dy));
+ }
+ }
+ }
+
+ const bool res = ActorSprite::draw(graphics, offsetX, offsetY);
+
+ if (highl)
+ {
+ if (font && mAmount > 1)
+ {
+ graphics->setColor(gcn::Color(255, 255, 255, 100));
+ font->drawString(graphics, toString(mAmount), x, y);
+ }
+ }
+ return res;
+}
diff --git a/src/flooritem.h b/src/flooritem.h
new file mode 100644
index 000000000..2cb47b9bb
--- /dev/null
+++ b/src/flooritem.h
@@ -0,0 +1,92 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef FLOORITEM_H
+#define FLOORITEM_H
+
+#include "actorsprite.h"
+
+class ItemInfo;
+
+/**
+ * An item lying on the floor.
+ */
+class FloorItem : public ActorSprite
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param id the unique ID of this item instance
+ * @param itemId the item ID
+ * @param x the x position in tiles
+ * @param y the y position in tiles
+ * @param map the map this item is on
+ * @param amount the item amount
+ */
+ FloorItem(int id,
+ int itemId,
+ int x,
+ int y,
+ Map *map,
+ int amount);
+
+ Type getType() const
+ { return FLOOR_ITEM; }
+
+ bool draw(Graphics *graphics, int offsetX, int offsetY) const;
+
+ /**
+ * Returns the item ID.
+ */
+ int getItemId() const
+ { return mItemId; }
+
+ /**
+ * Returns the item info for this floor item. Useful for adding an item
+ * link for the floor item to chat.
+ */
+ const ItemInfo &getInfo() const;
+
+ virtual int getTileX() const
+ { return mX; }
+
+ virtual int getTileY() const
+ { return mY; }
+
+ void incrementPickup()
+ { mPickupCount ++; }
+
+ unsigned getPickupCount() const
+ { return mPickupCount; }
+
+ private:
+ int mItemId;
+ int mX, mY;
+// Item *mItem;
+ Map *mMap;
+// float mAlpha;
+ int mDropTime;
+ int mAmount;
+ unsigned mPickupCount;
+};
+
+#endif
diff --git a/src/game.cpp b/src/game.cpp
new file mode 100644
index 000000000..c0abdf543
--- /dev/null
+++ b/src/game.cpp
@@ -0,0 +1,1501 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "game.h"
+
+#include "gui/npcdialog.h"
+
+#include "actorspritemanager.h"
+#include "actorsprite.h"
+#include "channelmanager.h"
+#include "client.h"
+#include "commandhandler.h"
+#include "configuration.h"
+#include "effectmanager.h"
+#include "event.h"
+#include "spellmanager.h"
+#include "emoteshortcut.h"
+#include "graphics.h"
+#include "itemshortcut.h"
+#include "dropshortcut.h"
+#include "spellshortcut.h"
+#include "joystick.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "log.h"
+#include "map.h"
+#include "particle.h"
+#include "playerrelations.h"
+#include "sound.h"
+
+#include "gui/botcheckerwindow.h"
+#include "gui/buysell.h"
+#include "gui/chat.h"
+#include "gui/confirmdialog.h"
+#include "gui/debugwindow.h"
+#include "gui/equipmentwindow.h"
+#include "gui/gui.h"
+#include "gui/help.h"
+#include "gui/inventorywindow.h"
+#include "gui/killstats.h"
+#include "gui/minimap.h"
+#include "gui/ministatus.h"
+#include "gui/npcpostdialog.h"
+#include "gui/okdialog.h"
+#include "gui/outfitwindow.h"
+#include "gui/sdlinput.h"
+#include "gui/setup.h"
+#include "gui/shopwindow.h"
+#include "gui/shortcutwindow.h"
+#include "gui/socialwindow.h"
+#include "gui/specialswindow.h"
+#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
+#include "gui/quitdialog.h"
+#include "gui/textdialog.h"
+#include "gui/trade.h"
+#include "gui/viewport.h"
+#include "gui/windowmenu.h"
+#include "gui/whoisonline.h"
+
+#include "gui/widgets/battletab.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/dropshortcutcontainer.h"
+#include "gui/widgets/emoteshortcutcontainer.h"
+#include "gui/widgets/itemshortcutcontainer.h"
+#include "gui/widgets/spellshortcutcontainer.h"
+#include "gui/widgets/tradetab.h"
+
+#include "net/gamehandler.h"
+#include "net/generalhandler.h"
+#include "net/net.h"
+#include "net/packetcounters.h"
+#include "net/playerhandler.h"
+
+#include "resources/imagewriter.h"
+#include "resources/mapreader.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+#include "utils/mkdir.h"
+
+#include <guichan/exception.hpp>
+#include <guichan/focushandler.hpp>
+
+#include <physfs.h>
+
+#include <fstream>
+#include <sstream>
+#include <string>
+
+#include "mumblemanager.h"
+
+Joystick *joystick = NULL;
+
+OkDialog *weightNotice = NULL;
+OkDialog *deathNotice = NULL;
+QuitDialog *quitDialog = NULL;
+OkDialog *disconnectedDialog = NULL;
+
+ChatWindow *chatWindow;
+StatusWindow *statusWindow;
+MiniStatusWindow *miniStatusWindow;
+InventoryWindow *inventoryWindow;
+ShopWindow *shopWindow;
+SkillDialog *skillDialog;
+Minimap *minimap;
+EquipmentWindow *equipmentWindow;
+TradeWindow *tradeWindow;
+HelpWindow *helpWindow;
+DebugWindow *debugWindow;
+ShortcutWindow *itemShortcutWindow;
+ShortcutWindow *emoteShortcutWindow;
+OutfitWindow *outfitWindow;
+SpecialsWindow *specialsWindow;
+ShortcutWindow *dropShortcutWindow;
+ShortcutWindow *spellShortcutWindow;
+WhoIsOnline *whoIsOnline;
+KillStats *killStats;
+BotCheckerWindow *botCheckerWindow;
+SocialWindow *socialWindow;
+WindowMenu *windowMenu;
+
+ActorSpriteManager *actorSpriteManager = NULL;
+ChannelManager *channelManager = NULL;
+CommandHandler *commandHandler = NULL;
+MumbleManager *mumbleManager = NULL;
+Particle *particleEngine = NULL;
+EffectManager *effectManager = NULL;
+SpellManager *spellManager = NULL;
+Viewport *viewport = NULL; /**< Viewport on the map. */
+
+ChatTab *localChatTab = NULL;
+ChatTab *debugChatTab = NULL;
+TradeTab *tradeChatTab = NULL;
+BattleTab *battleChatTab = NULL;
+
+/**
+ * Initialize every game sub-engines in the right order
+ */
+static void initEngines()
+{
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_ENGINESINITALIZING));
+
+ actorSpriteManager = new ActorSpriteManager;
+ commandHandler = new CommandHandler;
+ channelManager = new ChannelManager;
+ effectManager = new EffectManager;
+
+ particleEngine = new Particle(NULL);
+ particleEngine->setupEngine();
+
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_ENGINESINITALIZED));
+}
+
+/**
+ * Create all the various globally accessible gui windows
+ */
+static void createGuiWindows()
+{
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_GUIWINDOWSLOADING));
+
+ if (setupWindow)
+ setupWindow->clearWindowsForReset();
+
+ if (emoteShortcut)
+ emoteShortcut->load();
+
+ // Create dialogs
+ chatWindow = new ChatWindow;
+ tradeWindow = new TradeWindow;
+ equipmentWindow = new EquipmentWindow(PlayerInfo::getEquipment());
+ statusWindow = new StatusWindow;
+ miniStatusWindow = new MiniStatusWindow;
+ inventoryWindow = new InventoryWindow(PlayerInfo::getInventory());
+ shopWindow = new ShopWindow;
+ skillDialog = new SkillDialog;
+ minimap = new Minimap;
+ helpWindow = new HelpWindow;
+ debugWindow = new DebugWindow;
+ itemShortcutWindow = new ShortcutWindow("ItemShortcut");
+ for (int f = 0; f < SHORTCUT_TABS; f ++)
+ {
+ itemShortcutWindow->addTab(toString(f + 1),
+ new ItemShortcutContainer(f));
+ }
+
+ emoteShortcutWindow = new ShortcutWindow("EmoteShortcut",
+ new EmoteShortcutContainer);
+ outfitWindow = new OutfitWindow();
+ specialsWindow = new SpecialsWindow();
+ dropShortcutWindow = new ShortcutWindow("DropShortcut",
+ new DropShortcutContainer);
+ spellShortcutWindow = new ShortcutWindow("SpellShortcut",
+ new SpellShortcutContainer,
+ 265, 310);
+ botCheckerWindow = new BotCheckerWindow();
+ whoIsOnline = new WhoIsOnline();
+ killStats = new KillStats;
+ socialWindow = new SocialWindow();
+
+ localChatTab = new ChatTab(_("General"));
+ localChatTab->setAllowHighlight(false);
+ localChatTab->loadFromLogFile("#General");
+
+ debugChatTab = new ChatTab(_("Debug"));
+ debugChatTab->setAllowHighlight(false);
+
+ if (config.getBoolValue("enableTradeTab"))
+ {
+ tradeChatTab = new TradeTab;
+ tradeChatTab->setAllowHighlight(false);
+ }
+ else
+ {
+ tradeChatTab = 0;
+ }
+
+ if (config.getBoolValue("enableBattleTab"))
+ {
+ battleChatTab = new BattleTab;
+ battleChatTab->setAllowHighlight(false);
+ }
+ else
+ {
+ battleChatTab = 0;
+ }
+
+ if (config.getBoolValue("logToChat"))
+ logger->setChatWindow(chatWindow);
+
+ if (!isSafeMode && chatWindow)
+ chatWindow->loadState();
+
+ if (setupWindow)
+ setupWindow->externalUpdate();
+
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_GUIWINDOWSLOADED));
+}
+
+#define del_0(X) { delete X; X = 0; }
+
+/**
+ * Destroy all the globally accessible gui windows
+ */
+static void destroyGuiWindows()
+{
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_GUIWINDOWSUNLOADING));
+
+ logger->setChatWindow(NULL);
+ if (whoIsOnline)
+ whoIsOnline->setAllowUpdate(false);
+
+ del_0(windowMenu);
+ del_0(localChatTab) // Need to do this first, so it can remove itself
+ del_0(debugChatTab)
+ del_0(tradeChatTab)
+ del_0(battleChatTab)
+ logger->log("start deleting");
+ del_0(chatWindow)
+ logger->log("end deleting");
+ del_0(statusWindow)
+ del_0(miniStatusWindow)
+ del_0(inventoryWindow)
+ del_0(shopWindow)
+ del_0(skillDialog)
+ del_0(minimap)
+ del_0(equipmentWindow)
+ del_0(tradeWindow)
+ del_0(helpWindow)
+ del_0(debugWindow)
+ del_0(itemShortcutWindow)
+ del_0(emoteShortcutWindow)
+ del_0(outfitWindow)
+ del_0(specialsWindow)
+ del_0(socialWindow)
+ del_0(dropShortcutWindow);
+ del_0(spellShortcutWindow);
+ del_0(botCheckerWindow);
+ del_0(whoIsOnline);
+ del_0(killStats);
+
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_GUIWINDOWSUNLOADED));
+}
+
+Game *Game::mInstance = 0;
+
+Game::Game():
+ mLastTarget(ActorSprite::UNKNOWN),
+ mCurrentMap(0), mMapName(""),
+ mValidSpeed(true), mLastAction(0)
+{
+ spellManager = new SpellManager;
+ spellShortcut = new SpellShortcut;
+
+ assert(!mInstance);
+ mInstance = this;
+
+ disconnectedDialog = NULL;
+
+ // Create the viewport
+ viewport = new Viewport;
+ viewport->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(),
+ graphics->getHeight()));
+
+ gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
+ top->add(viewport);
+ viewport->requestMoveToBottom();
+
+ createGuiWindows();
+
+ windowMenu = new WindowMenu;
+// mWindowMenu = windowMenu;
+
+ windowContainer->add(windowMenu);
+
+ initEngines();
+
+ // Initialize beings
+ actorSpriteManager->setPlayer(player_node);
+
+ /*
+ * To prevent the server from sending data before the client
+ * has initialized, I've modified it to wait for a "ping"
+ * from the client to complete its initialization
+ *
+ * Note: This only affects the latest eAthena version. This
+ * packet is handled by the older version, but its response
+ * is ignored by the client
+ */
+ Net::getGameHandler()->ping(tick_time);
+
+ Joystick::init();
+ // TODO: The user should be able to choose which one to use
+ // Open the first device
+ if (Joystick::getNumberOfJoysticks() > 0)
+ joystick = new Joystick(0);
+
+ if (setupWindow)
+ setupWindow->setInGame(true);
+ clearKeysArray();
+
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_CONSTRUCTED));
+}
+
+Game::~Game()
+{
+ config.write();
+ serverConfig.write();
+// delete mWindowMenu;
+// mWindowMenu = 0;
+
+ destroyGuiWindows();
+
+ del_0(actorSpriteManager)
+ if (Client::getState() != STATE_CHANGE_MAP)
+ del_0(player_node)
+ del_0(channelManager)
+ del_0(commandHandler)
+ del_0(effectManager);
+ del_0(joystick)
+ del_0(particleEngine)
+ del_0(viewport)
+ del_0(mCurrentMap)
+ del_0(spellManager);
+ del_0(spellShortcut);
+ del_0(mumbleManager);
+
+ mInstance = 0;
+
+ Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_DESTRUCTED));
+}
+
+static bool saveScreenshot()
+{
+ static unsigned int screenshotCount = 0;
+
+ SDL_Surface *screenshot = graphics->getScreenshot();
+ if (!screenshot)
+ return false;
+
+ // Search for an unused screenshot name
+ std::stringstream filenameSuffix;
+ std::stringstream filename;
+ std::fstream testExists;
+ std::string screenshotDirectory = Client::getScreenshotDirectory();
+ bool found = false;
+
+ if (mkdir_r(screenshotDirectory.c_str()) != 0)
+ {
+ logger->log("Directory %s doesn't exist and can't be created! "
+ "Setting screenshot directory to home.",
+ screenshotDirectory.c_str());
+ screenshotDirectory = std::string(PHYSFS_getUserDir());
+ }
+
+ do
+ {
+ screenshotCount++;
+ filenameSuffix.str("");
+ filename.str("");
+ filename << screenshotDirectory << "/";
+ filenameSuffix << branding.getValue("appShort", "ManaPlus")
+ << "_Screenshot_" << screenshotCount << ".png";
+ filename << filenameSuffix.str();
+ testExists.open(filename.str().c_str(), std::ios::in);
+ found = !testExists.is_open();
+ testExists.close();
+ }
+ while (!found);
+
+ const bool success = ImageWriter::writePNG(screenshot, filename.str());
+
+ if (success)
+ {
+ std::stringstream chatlogentry;
+ // TODO: Make it one complete gettext string below
+ chatlogentry << _("Screenshot saved as ") << filenameSuffix.str();
+ if (localChatTab)
+ localChatTab->chatLog(chatlogentry.str(), BY_SERVER);
+ }
+ else
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(_("Saving screenshot failed!"),
+ BY_SERVER);
+ }
+ logger->log1("Error: could not save screenshot.");
+ }
+
+ SDL_FreeSurface(screenshot);
+
+ return success;
+}
+
+void Game::logic()
+{
+ handleInput();
+
+ // Handle all necessary game logic
+ ActorSprite::actorLogic();
+ if (actorSpriteManager)
+ actorSpriteManager->logic();
+ if (particleEngine)
+ particleEngine->update();
+ if (mCurrentMap)
+ mCurrentMap->update();
+
+ cur_time = static_cast<int>(time(0));
+ Being::reReadConfig();
+ if (killStats)
+ killStats->recalcStats();
+ if (shopWindow)
+ shopWindow->updateTimes();
+ PacketCounters::update();
+
+ // Handle network stuff
+ if (!Net::getGameHandler()->isConnected())
+ {
+ if (Client::getState() == STATE_CHANGE_MAP)
+ return; // Not a problem here
+
+ if (Client::getState() != STATE_ERROR)
+ errorMessage = _("The connection to the server was lost.");
+
+
+ if (!disconnectedDialog)
+ {
+ disconnectedDialog = new OkDialog(_("Network Error"),
+ errorMessage);
+ disconnectedDialog->addActionListener(&errorListener);
+ disconnectedDialog->requestMoveToTop();
+ }
+ }
+}
+
+/**
+ * The huge input handling method.
+ */
+void Game::handleInput()
+{
+ if (joystick)
+ joystick->update();
+
+ // Events
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ {
+ bool used = false;
+
+ updateHistory(event);
+ checkKeys();
+
+ // Keyboard events (for discontinuous keys)
+ if (event.type == SDL_KEYDOWN)
+ {
+ gcn::Window *requestedWindow = NULL;
+
+ if (setupWindow && setupWindow->isVisible() &&
+ keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE)
+ {
+ keyboard.setNewKey((int) event.key.keysym.sym);
+ keyboard.callbackNewKey();
+ keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE);
+ return;
+ }
+
+ // send straight to gui for certain windows
+ if (quitDialog || TextDialog::isActive() ||
+ NpcPostDialog::isActive())
+ {
+ try
+ {
+ guiInput->pushInput(event);
+ }
+ catch (gcn::Exception e)
+ {
+ const char* err = e.getMessage().c_str();
+ logger->log("Warning: guichan input exception: %s", err);
+ }
+ return;
+ }
+
+ if (chatWindow && !chatWindow->isInputFocused()
+ && keyboard.isKeyActive(keyboard.KEY_RIGHT_CLICK))
+ {
+ int mouseX, mouseY;
+ SDL_GetMouseState(&mouseX, &mouseY);
+
+ gcn::MouseEvent event2(viewport, false, false, false, false,
+ 0, gcn::MouseEvent::RIGHT, mouseX, mouseY, 1);
+ if (viewport)
+ viewport->mousePressed(event2);
+ continue;
+ }
+
+ // Mode switch to emotes
+ if (keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ {
+ // Emotions
+ int emotion = keyboard.getKeyEmoteOffset(event.key.keysym.sym);
+ if (emotion)
+ {
+ if (emoteShortcut)
+ emoteShortcut->useEmote(emotion);
+ used = true;
+ setValidSpeed();
+ return;
+ }
+ }
+
+ if (keyboard.isEnabled()
+ && !chatWindow->isInputFocused()
+ && !setupWindow->isVisible()
+ && !player_node->getAwayMode()
+ && !NpcDialog::isAnyInputFocused())
+ {
+ bool wearOutfit = false;
+ bool copyOutfit = false;
+ if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT))
+ wearOutfit = true;
+
+ if (keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT))
+ copyOutfit = true;
+
+ if (wearOutfit || copyOutfit)
+ {
+ int outfitNum = outfitWindow->keyToNumber(
+ event.key.keysym.sym);
+ if (outfitNum >= 0)
+ {
+ used = true;
+ if (wearOutfit)
+ outfitWindow->wearOutfit(outfitNum);
+ else if (copyOutfit)
+ outfitWindow->copyOutfit(outfitNum);
+ }
+ else
+ {
+ if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT))
+ outfitWindow->wearNextOutfit();
+ else if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT))
+ outfitWindow->wearPreviousOutfit();
+ }
+ setValidSpeed();
+ continue;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_MOVE_TO_POINT))
+ {
+ int num = outfitWindow->keyToNumber(
+ event.key.keysym.sym);
+ if (socialWindow && num >= 0)
+ {
+ socialWindow->selectPortal(num);
+ continue;
+ }
+ }
+ }
+
+ if (!chatWindow->isInputFocused()
+ && !gui->getFocusHandler()->getModalFocused()
+ && !player_node->getAwayMode())
+ {
+ NpcDialog *dialog = NpcDialog::getActive();
+ if (keyboard.isKeyActive(keyboard.KEY_OK)
+ && (!dialog || !dialog->isTextInputFocused()))
+ {
+ // Close the Browser if opened
+ if (helpWindow->isVisible())
+ helpWindow->setVisible(false);
+ // Close the config window, cancelling changes if opened
+ else if (setupWindow->isVisible())
+ setupWindow->action(gcn::ActionEvent(NULL, "cancel"));
+ else if (dialog)
+ dialog->action(gcn::ActionEvent(NULL, "ok"));
+ }
+ if (keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT))
+ {
+ if (chatWindow->requestChatFocus())
+ used = true;
+ }
+ if (dialog)
+ {
+ if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP))
+ dialog->move(1);
+ else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN))
+ dialog->move(-1);
+ }
+ }
+
+ if ((!chatWindow->isInputFocused() &&
+ !NpcDialog::isAnyInputFocused())
+ || (event.key.keysym.mod & KMOD_ALT))
+ {
+ if (keyboard.isKeyActive(keyboard.KEY_PREV_CHAT_TAB))
+ {
+ chatWindow->prevTab();
+ return;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_NEXT_CHAT_TAB))
+ {
+ chatWindow->nextTab();
+ return;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_PREV_SOCIAL_TAB))
+ {
+ socialWindow->prevTab();
+ return;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_NEXT_SOCIAL_TAB))
+ {
+ socialWindow->nextTab();
+ return;
+ }
+ }
+
+ const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
+ switch (tKey)
+ {
+ case KeyboardConfig::KEY_SCROLL_CHAT_UP:
+ if (chatWindow->isVisible())
+ {
+ chatWindow->scroll(-DEFAULT_CHAT_WINDOW_SCROLL);
+ used = true;
+ }
+ break;
+ case KeyboardConfig::KEY_SCROLL_CHAT_DOWN:
+ if (chatWindow->isVisible())
+ {
+ chatWindow->scroll(DEFAULT_CHAT_WINDOW_SCROLL);
+ used = true;
+ return;
+ }
+ break;
+ case KeyboardConfig::KEY_WINDOW_HELP:
+ // In-game Help
+ if (helpWindow->isVisible())
+ helpWindow->setVisible(false);
+ else
+ {
+ helpWindow->loadHelp("index");
+ helpWindow->requestMoveToTop();
+ }
+ used = true;
+ break;
+
+
+
+ // Quitting confirmation dialog
+ case KeyboardConfig::KEY_QUIT:
+ if (!chatWindow->isInputFocused())
+ {
+ quitDialog = new QuitDialog(&quitDialog);
+ quitDialog->requestMoveToTop();
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (keyboard.isEnabled() && !chatWindow->isInputFocused()
+ && !gui->getFocusHandler()->getModalFocused()
+ && mValidSpeed
+ && !setupWindow->isVisible()
+ && !player_node->getAwayMode()
+ && !NpcDialog::isAnyInputFocused())
+ {
+ switch (tKey)
+ {
+ case KeyboardConfig::KEY_QUICK_DROP:
+ dropShortcut->dropFirst();
+ break;
+
+ case KeyboardConfig::KEY_QUICK_DROPN:
+ dropShortcut->dropItems();
+ break;
+
+ case KeyboardConfig::KEY_SWITCH_QUICK_DROP:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changeQuickDropCounter();
+ break;
+
+ case KeyboardConfig::KEY_MAGIC_INMA1:
+ actorSpriteManager->healTarget(player_node);
+ setValidSpeed();
+ break;
+
+ case KeyboardConfig::KEY_MAGIC_ITENPLZ:
+ if (Net::getPlayerHandler()->canUseMagic()
+ && PlayerInfo::getAttribute(MP) >= 3)
+ {
+ actorSpriteManager->itenplz();
+ }
+ setValidSpeed();
+ break;
+
+ case KeyboardConfig::KEY_CRAZY_MOVES:
+ player_node->crazyMove();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_CRAZY_MOVES_TYPE:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changeCrazyMoveType();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_PICKUP_TYPE:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changePickUpType();
+ break;
+
+ case KeyboardConfig::KEY_MOVE_TO_TARGET:
+ if (!keyboard.isKeyActive(keyboard.KEY_TARGET_ATTACK)
+ && !keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ {
+ player_node->moveToTarget();
+ }
+ break;
+
+ case KeyboardConfig::KEY_MOVE_TO_HOME:
+ if (!keyboard.isKeyActive(keyboard.KEY_TARGET_ATTACK)
+ && !keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ {
+ player_node->moveToHome();
+ }
+ setValidSpeed();
+ break;
+
+ case KeyboardConfig::KEY_SET_HOME:
+ player_node->setHome();
+ break;
+
+ case KeyboardConfig::KEY_INVERT_DIRECTION:
+ if (!player_node->getDisableGameModifiers())
+ player_node->invertDirection();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_ATTACK_WEAPON_TYPE:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changeAttackWeaponType();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_ATTACK_TYPE:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changeAttackType();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_FOLLOW_MODE:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changeFollowMode();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_IMITATION_MODE:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changeImitationMode();
+ break;
+
+ case KeyboardConfig::KEY_MAGIC_ATTACK:
+ player_node->magicAttack();
+ break;
+
+ case KeyboardConfig::KEY_SWITCH_MAGIC_ATTACK:
+ if (!player_node->getDisableGameModifiers())
+ player_node->switchMagicAttack();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_MOVE_TO_TARGET:
+ if (!player_node->getDisableGameModifiers())
+ player_node->changeMoveToTargetType();
+ break;
+
+ case KeyboardConfig::KEY_COPY_EQUIPED_OUTFIT:
+ outfitWindow->copyFromEquiped();
+ break;
+
+ case KeyboardConfig::KEY_DISABLE_GAME_MODIFIERS:
+ player_node->switchGameModifiers();
+ break;
+
+ case KeyboardConfig::KEY_CHANGE_AUDIO:
+ sound.changeAudio();
+ break;
+
+ case KeyboardConfig::KEY_AWAY:
+ player_node->changeAwayMode();
+ setValidSpeed();
+ break;
+
+ case KeyboardConfig::KEY_CAMERA:
+ if (!player_node->getDisableGameModifiers())
+ viewport->toggleCameraMode();
+ setValidSpeed();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (keyboard.isEnabled()
+ && !chatWindow->isInputFocused()
+ && !NpcDialog::isAnyInputFocused()
+ && !setupWindow->isVisible()
+ && !player_node->getAwayMode()
+ && !keyboard.isKeyActive(keyboard.KEY_TARGET))
+ {
+ const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
+
+ // Do not activate shortcuts if tradewindow is visible
+ if (itemShortcutWindow && !tradeWindow->isVisible()
+ && !setupWindow->isVisible())
+ {
+ int num = itemShortcutWindow->getTabIndex();
+ if (num >= 0 && num < SHORTCUT_TABS)
+ {
+ // Checks if any item shortcut is pressed.
+ for (int i = KeyboardConfig::KEY_SHORTCUT_1;
+ i <= KeyboardConfig::KEY_SHORTCUT_20;
+ i++)
+ {
+ if (tKey == i && !used)
+ {
+ itemShortcut[num]->useItem(
+ i - KeyboardConfig::KEY_SHORTCUT_1);
+ break;
+ }
+ }
+ }
+ }
+
+ switch (tKey)
+ {
+ case KeyboardConfig::KEY_PICKUP:
+ player_node->pickUpItems();
+ used = true;
+ break;
+ case KeyboardConfig::KEY_SIT:
+ // Player sit action
+ if (keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ player_node->updateSit();
+ else
+ player_node->toggleSit();
+ used = true;
+ break;
+ case KeyboardConfig::KEY_HIDE_WINDOWS:
+ // Hide certain windows
+ if (!chatWindow->isInputFocused())
+ {
+ statusWindow->setVisible(false);
+ inventoryWindow->setVisible(false);
+ shopWindow->setVisible(false);
+ skillDialog->setVisible(false);
+ setupWindow->setVisible(false);
+ equipmentWindow->setVisible(false);
+ helpWindow->setVisible(false);
+ debugWindow->setVisible(false);
+ outfitWindow->setVisible(false);
+ dropShortcutWindow->setVisible(false);
+ spellShortcutWindow->setVisible(false);
+ botCheckerWindow->setVisible(false);
+ socialWindow->setVisible(false);
+ }
+ break;
+ case KeyboardConfig::KEY_WINDOW_STATUS:
+ requestedWindow = statusWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_INVENTORY:
+ requestedWindow = inventoryWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SHOP:
+ requestedWindow = shopWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_EQUIPMENT:
+ requestedWindow = equipmentWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SKILL:
+ requestedWindow = skillDialog;
+ break;
+ case KeyboardConfig::KEY_WINDOW_KILLS:
+ requestedWindow = killStats;
+ break;
+ case KeyboardConfig::KEY_WINDOW_MINIMAP:
+ minimap->toggle();
+ break;
+ case KeyboardConfig::KEY_WINDOW_CHAT:
+ requestedWindow = chatWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SHORTCUT:
+ requestedWindow = itemShortcutWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SETUP:
+ requestedWindow = setupWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_DEBUG:
+ requestedWindow = debugWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SOCIAL:
+ requestedWindow = socialWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_EMOTE_SHORTCUT:
+ requestedWindow = emoteShortcutWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_OUTFIT:
+ requestedWindow = outfitWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_DROP:
+ requestedWindow = dropShortcutWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SPELLS:
+ requestedWindow = spellShortcutWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_BOT_CHECKER:
+ requestedWindow = botCheckerWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_ONLINE:
+ requestedWindow = whoIsOnline;
+ break;
+ case KeyboardConfig::KEY_SCREENSHOT:
+ // Screenshot (picture, hence the p)
+ saveScreenshot();
+ used = true;
+ break;
+ case KeyboardConfig::KEY_PATHFIND:
+ // Find path to mouse (debug purpose)
+ if (!player_node->getDisableGameModifiers())
+ {
+ viewport->toggleDebugPath();
+ miniStatusWindow->updateStatus();
+ used = true;
+ }
+ break;
+ case KeyboardConfig::KEY_TRADE:
+ {
+ // Toggle accepting of incoming trade requests
+ unsigned int deflt = player_relations.getDefault();
+ if (deflt & PlayerRelation::TRADE)
+ {
+ localChatTab->chatLog(
+ _("Ignoring incoming trade requests"),
+ BY_SERVER);
+ deflt &= ~PlayerRelation::TRADE;
+ }
+ else
+ {
+ localChatTab->chatLog(
+ _("Accepting incoming trade requests"),
+ BY_SERVER);
+ deflt |= PlayerRelation::TRADE;
+ }
+
+ player_relations.setDefault(deflt);
+
+ used = true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (requestedWindow)
+ {
+ requestedWindow->setVisible(!requestedWindow->isVisible());
+ if (requestedWindow->isVisible())
+ requestedWindow->requestMoveToTop();
+ used = true;
+ }
+ }
+ // Active event
+ else if (event.type == SDL_ACTIVEEVENT)
+ {
+// logger->log("SDL_ACTIVEEVENT");
+// logger->log("state: %d", (int)event.active.state);
+// logger->log("gain: %d", (int)event.active.gain);
+
+ int fpsLimit = 0;
+ if (event.active.state & SDL_APPACTIVE)
+ {
+ if (event.active.gain)
+ { // window restore
+ Client::setIsMinimized(false);
+ if (player_node && !player_node->getAwayMode())
+ fpsLimit = config.getIntValue("fpslimit");
+ }
+ else
+ { // window minimisation
+ Client::setIsMinimized(true);
+ if (player_node && !player_node->getAwayMode())
+ fpsLimit = config.getIntValue("altfpslimit");
+ }
+ Client::setFramerate(fpsLimit);
+ }
+
+ if (event.active.state & SDL_APPINPUTFOCUS)
+ Client::setInputFocused(event.active.gain);
+ if (event.active.state & SDL_APPMOUSEFOCUS)
+ Client::setMouseFocused(event.active.gain);
+
+ if (player_node->getAwayMode())
+ {
+ if (Client::getInputFocused() || Client::getMouseFocused())
+ fpsLimit = config.getIntValue("fpslimit");
+ else
+ fpsLimit = config.getIntValue("altfpslimit");
+ Client::setFramerate(fpsLimit);
+ }
+ }
+ // Quit event
+ else if (event.type == SDL_QUIT)
+ {
+ Client::setState(STATE_EXIT);
+ }
+
+ // Push input to GUI when not used
+ if (!used)
+ {
+ try
+ {
+ guiInput->pushInput(event);
+ }
+ catch (gcn::Exception e)
+ {
+ const char *err = e.getMessage().c_str();
+ logger->log("Warning: guichan input exception: %s", err);
+ }
+ }
+
+ } // End while
+
+ // If the user is configuring the keys then don't respond.
+ if (!keyboard.isEnabled() || player_node->getAwayMode())
+ return;
+
+ if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT)
+ || keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT)
+ || setupWindow->isVisible())
+ {
+ return;
+ }
+
+ // Moving player around
+ if (player_node->isAlive() && (!Being::isTalking()
+ || keyboard.getKeyIndex(event.key.keysym.sym)
+ == KeyboardConfig::KEY_TALK)
+ && !chatWindow->isInputFocused() && !quitDialog)
+ {
+ // Get the state of the keyboard keys
+ keyboard.refreshActiveKeys();
+
+ // Ignore input if either "ignore" key is pressed
+ // Stops the character moving about if the user's window manager
+ // uses "ignore+arrow key" to switch virtual desktops.
+ if (keyboard.isKeyActive(keyboard.KEY_IGNORE_INPUT_1) ||
+ keyboard.isKeyActive(keyboard.KEY_IGNORE_INPUT_2))
+ {
+ return;
+ }
+
+ unsigned char direction = 0;
+
+ // Translate pressed keys to movement and direction
+ if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP) ||
+ (joystick && joystick->isUp()))
+ {
+ direction |= Being::UP;
+ setValidSpeed();
+ player_node->cancelFollow();
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN) ||
+ (joystick && joystick->isDown()))
+ {
+ direction |= Being::DOWN;
+ setValidSpeed();
+ player_node->cancelFollow();
+ }
+
+ if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT) ||
+ (joystick && joystick->isLeft()))
+ {
+ direction |= Being::LEFT;
+ setValidSpeed();
+ player_node->cancelFollow();
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT) ||
+ (joystick && joystick->isRight()))
+ {
+ direction |= Being::RIGHT;
+ setValidSpeed();
+ player_node->cancelFollow();
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_DIRECT_UP))
+ {
+ if (player_node->getDirection() != Being::UP)
+ {
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ player_node->setDirection(Being::UP);
+ Net::getPlayerHandler()->setDirection(Being::UP);
+ }
+ }
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_DIRECT_DOWN))
+ {
+ if (player_node->getDirection() != Being::DOWN)
+ {
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ player_node->setDirection(Being::DOWN);
+ Net::getPlayerHandler()->setDirection(Being::DOWN);
+ }
+ }
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_DIRECT_LEFT))
+ {
+ if (player_node->getDirection() != Being::LEFT)
+ {
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ player_node->setDirection(Being::LEFT);
+ Net::getPlayerHandler()->setDirection(Being::LEFT);
+ }
+ }
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_DIRECT_RIGHT))
+ {
+ if (player_node->getDirection() != Being::RIGHT)
+ {
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ player_node->setDirection(Being::RIGHT);
+ Net::getPlayerHandler()->setDirection(Being::RIGHT);
+ }
+ }
+ }
+
+ if (keyboard.isKeyActive(keyboard.KEY_EMOTE) && direction != 0)
+ {
+ if (player_node->getDirection() != direction)
+ {
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ player_node->setDirection(direction);
+ Net::getPlayerHandler()->setDirection(direction);
+ }
+ }
+ direction = 0;
+ }
+ else
+ {
+ if (!viewport->getCameraMode())
+ {
+ player_node->specialMove(direction);
+ }
+ else
+ {
+ int dx = 0;
+ int dy = 0;
+ if (direction & Being::LEFT)
+ dx = -5;
+ else if (direction & Being::RIGHT)
+ dx = 5;
+
+ if (direction & Being::UP)
+ dy = -5;
+ else if (direction & Being::DOWN)
+ dy = 5;
+ viewport->moveCamera(dx, dy);
+ }
+ }
+
+ if (((player_node->getAttackType() == 0
+ && player_node->getFollow().empty()) || event.type == SDL_KEYDOWN)
+ && mValidSpeed)
+ {
+ // Attacking monsters
+ if (keyboard.isKeyActive(keyboard.KEY_ATTACK) ||
+ (joystick && joystick->buttonPressed(0)))
+ {
+ if (player_node->getTarget())
+ player_node->attack(player_node->getTarget(), true);
+ }
+
+ if (keyboard.isKeyActive(keyboard.KEY_TARGET_ATTACK)
+ && !keyboard.isKeyActive(keyboard.KEY_MOVE_TO_TARGET))
+ {
+ Being *target = 0;
+
+ bool newTarget = !keyboard.isKeyActive(keyboard.KEY_TARGET);
+ // A set target has highest priority
+ if (!player_node->getTarget())
+ {
+ // Only auto target Monsters
+ target = actorSpriteManager->findNearestLivingBeing(
+ player_node, 90, ActorSprite::MONSTER);
+ }
+ else
+ {
+ target = player_node->getTarget();
+ }
+
+ player_node->attack2(target, newTarget);
+ }
+ }
+
+ if (!keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ {
+ // Target the nearest player/monster/npc
+ if ((keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) ||
+ keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
+ keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) ||
+ (joystick && joystick->buttonPressed(3))) &&
+ !keyboard.isKeyActive(keyboard.KEY_TARGET))
+ {
+ ActorSprite::Type currentTarget = ActorSprite::UNKNOWN;
+ if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
+ (joystick && joystick->buttonPressed(3)))
+ {
+ currentTarget = ActorSprite::MONSTER;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER))
+ {
+ currentTarget = ActorSprite::PLAYER;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_TARGET_NPC))
+ {
+ currentTarget = ActorSprite::NPC;
+ }
+
+ Being *target = actorSpriteManager->findNearestLivingBeing(
+ player_node, 20, currentTarget);
+
+ if (target && (target != player_node->getTarget() ||
+ currentTarget != mLastTarget))
+ {
+ player_node->setTarget(target);
+ mLastTarget = currentTarget;
+ }
+ }
+ else
+ {
+ mLastTarget = ActorSprite::UNKNOWN; // Reset last target
+ }
+ }
+
+ // Talk to the nearest NPC if 't' pressed
+ if (event.type == SDL_KEYDOWN &&
+ keyboard.getKeyIndex(event.key.keysym.sym)
+ == KeyboardConfig::KEY_TALK &&
+ !keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ {
+ Being *target = player_node->getTarget();
+
+ if (target)
+ {
+ if (target->canTalk())
+ target->talkTo();
+ else if (target->getType() == Being::PLAYER)
+ new BuySellDialog(target->getName());
+ }
+ }
+
+ // Stop attacking if the right key is pressed
+ if (!keyboard.isKeyActive(keyboard.KEY_ATTACK)
+ && keyboard.isKeyActive(keyboard.KEY_TARGET)
+ && !keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ {
+ player_node->stopAttack();
+ }
+
+ if (joystick)
+ {
+ if (joystick->buttonPressed(1))
+ player_node->pickUpItems();
+ else if (joystick->buttonPressed(2))
+ player_node->toggleSit();
+ }
+ }
+}
+
+/**
+ * Changes the currently active map. Should only be called while the game is
+ * running.
+ */
+void Game::changeMap(const std::string &mapPath)
+{
+ // Clean up floor items, beings and particles
+ actorSpriteManager->clear();
+
+ // Close the popup menu on map change so that invalid options can't be
+ // executed.
+ viewport->closePopupMenu();
+ viewport->cleanHoverItems();
+
+ // Unset the map of the player so that its particles are cleared before
+ // being deleted in the next step
+ if (player_node)
+ player_node->setMap(0);
+
+ particleEngine->clear();
+
+ mMapName = mapPath;
+
+ std::string fullMap = paths.getValue("maps", "maps/")
+ + mMapName + ".tmx";
+ ResourceManager *resman = ResourceManager::getInstance();
+ if (!resman->exists(fullMap))
+ fullMap += ".gz";
+
+ // Attempt to load the new map
+ Map *newMap = MapReader::readMap(fullMap);
+
+ if (!newMap)
+ {
+ logger->log("Error while loading %s", fullMap.c_str());
+ new OkDialog(_("Could Not Load Map"),
+ strprintf(_("Error while loading %s"), fullMap.c_str()));
+ }
+
+ if (newMap)
+ newMap->addExtraLayer();
+
+ if (socialWindow)
+ socialWindow->setMap(newMap);
+
+ // Notify the minimap and actorSpriteManager about the map change
+ minimap->setMap(newMap);
+ actorSpriteManager->setMap(newMap);
+ particleEngine->setMap(newMap);
+ viewport->setMap(newMap);
+
+ // Initialize map-based particle effects
+ if (newMap)
+ newMap->initializeParticleEffects(particleEngine);
+
+ // Start playing new music file when necessary
+ std::string oldMusic = mCurrentMap ? mCurrentMap->getMusicFile() : "";
+ std::string newMusic = newMap ? newMap->getMusicFile() : "";
+ if (newMusic != oldMusic)
+ sound.playMusic(newMusic);
+
+ if (mCurrentMap)
+ mCurrentMap->saveExtraLayer();
+
+ delete mCurrentMap;
+ mCurrentMap = newMap;
+// mCurrentMap = 0;
+
+ if (mumbleManager)
+ mumbleManager->setMap(mapPath);
+ Mana::Event event(EVENT_MAPLOADED);
+ event.setString("mapPath", mapPath);
+ Mana::Event::trigger(CHANNEL_GAME, event);
+}
+
+void Game::updateHistory(SDL_Event &event)
+{
+ if (!player_node->getAttackType())
+ return;
+
+ bool old = false;
+
+ if (event.key.keysym.sym != -1)
+ {
+ int key = keyboard.getKeyIndex(event.key.keysym.sym);
+ int time = cur_time;
+ int idx = -1;
+ for (int f = 0; f < MAX_LASTKEYS; f ++)
+ {
+ if (mLastKeys[f].key == key)
+ {
+ idx = f;
+ old = true;
+ break;
+ }
+ else if (idx >= 0 && mLastKeys[f].time < mLastKeys[idx].time)
+ idx = f;
+ }
+ if (idx < 0)
+ {
+ idx = 0;
+ for (int f = 0; f < MAX_LASTKEYS; f ++)
+ {
+ if (mLastKeys[f].key == -1
+ || mLastKeys[f].time < mLastKeys[idx].time)
+ {
+ idx = f;
+ }
+ }
+ }
+
+ if (idx < 0)
+ idx = 0;
+
+ if (!old)
+ {
+ mLastKeys[idx].time = time;
+ mLastKeys[idx].key = key;
+ mLastKeys[idx].cnt = 0;
+ }
+ else
+ {
+ mLastKeys[idx].cnt++;
+ }
+ }
+}
+
+void Game::checkKeys()
+{
+ const int timeRange = 120;
+ const int cntInTime = 130;
+
+ if (!player_node->getAttackType())
+ return;
+
+ for (int f = 0; f < MAX_LASTKEYS; f ++)
+ {
+ if (mLastKeys[f].key != -1)
+ {
+ if (mLastKeys[f].time + timeRange < cur_time)
+ {
+ if (mLastKeys[f].cnt > cntInTime)
+ mValidSpeed = false;
+ mLastKeys[f].key = -1;
+ }
+ }
+ }
+}
+
+void Game::setValidSpeed()
+{
+ clearKeysArray();
+ mValidSpeed = true;
+}
+
+void Game::clearKeysArray()
+{
+ for (int f = 0; f < MAX_LASTKEYS; f ++)
+ {
+ mLastKeys[f].time = 0;
+ mLastKeys[f].key = -1;
+ mLastKeys[f].cnt = 0;
+ }
+}
diff --git a/src/game.h b/src/game.h
new file mode 100644
index 000000000..53ec2ae15
--- /dev/null
+++ b/src/game.h
@@ -0,0 +1,110 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GAME_H
+#define GAME_H
+
+#include <string>
+#include "gui/sdlinput.h"
+
+#define MAX_LASTKEYS 10
+
+extern volatile int cur_time;
+//extern std::string map_path; // TODO: Get rid of this global
+
+class Map;
+class WindowMenu;
+
+struct LastKey
+{
+ int key;
+ int time;
+ int cnt;
+};
+
+/**
+ * The main class responsible for running the game. The game starts after you
+ * have selected your character.
+ */
+class Game
+{
+ public:
+ /**
+ * Constructs the game, creating all the managers, handlers, engines
+ * and GUI windows that make up the game.
+ */
+ Game();
+
+ /**
+ * Destructor, cleans up the game.
+ */
+ ~Game();
+
+ /**
+ * Provides access to the game instance.
+ */
+ static Game *instance()
+ { return mInstance; }
+
+ /**
+ * This method takes the game a small step further. It is called 100
+ * times per second.
+ */
+ void logic();
+
+ void handleInput();
+
+ void changeMap(const std::string &mapName);
+
+ /**
+ * Returns the currently active map.
+ */
+ Map *getCurrentMap()
+ { return mCurrentMap; }
+
+ const std::string &getCurrentMapName() const
+ { return mMapName; }
+
+ void setValidSpeed();
+
+ private:
+
+ void updateHistory(SDL_Event &event);
+
+ void checkKeys();
+
+ void clearKeysArray();
+
+
+ int mLastTarget;
+
+// WindowMenu *mWindowMenu;
+
+ Map *mCurrentMap;
+ std::string mMapName;
+ bool mValidSpeed;
+ int mLastAction;
+ LastKey mLastKeys[MAX_LASTKEYS];
+
+ static Game *mInstance;
+};
+
+#endif
diff --git a/src/graphics.cpp b/src/graphics.cpp
new file mode 100644
index 000000000..afda085dd
--- /dev/null
+++ b/src/graphics.cpp
@@ -0,0 +1,426 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <cassert>
+
+#include "graphics.h"
+#include "log.h"
+
+#include "resources/image.h"
+#include "resources/imageloader.h"
+
+#include "utils/stringutils.h"
+
+//<SDL_gfxBlitFunc.h>
+#include "SDL_gfxBlitFunc.h"
+
+Graphics::Graphics():
+ mWidth(0),
+ mHeight(0),
+ mBpp(0),
+ mFullscreen(false),
+ mHWAccel(false),
+ mBlitMode(BLIT_NORMAL)
+{
+}
+
+Graphics::~Graphics()
+{
+ _endDraw();
+}
+
+bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+{
+ logger->log("Setting video mode %dx%d %s",
+ w, h, fs ? "fullscreen" : "windowed");
+
+ logger->log("Bits per pixel: %d", bpp);
+
+ int displayFlags = SDL_ANYFORMAT;
+
+ mWidth = w;
+ mHeight = h;
+ mBpp = bpp;
+ mFullscreen = fs;
+ mHWAccel = hwaccel;
+
+ if (fs)
+ displayFlags |= SDL_FULLSCREEN;
+
+ if (hwaccel)
+ displayFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
+ else
+ displayFlags |= SDL_SWSURFACE;
+
+ setTarget(SDL_SetVideoMode(w, h, bpp, displayFlags));
+
+ if (!mTarget)
+ return false;
+
+ char videoDriverName[65];
+
+ if (SDL_VideoDriverName(videoDriverName, 64))
+ logger->log("Using video driver: %s", videoDriverName);
+ else
+ logger->log1("Using video driver: unknown");
+
+ const SDL_VideoInfo *vi = SDL_GetVideoInfo();
+
+ logger->log("Possible to create hardware surfaces: %s",
+ ((vi->hw_available) ? "yes" : "no"));
+ logger->log("Window manager available: %s",
+ ((vi->wm_available) ? "yes" : "no"));
+ logger->log("Accelerated hardware to hardware blits: %s",
+ ((vi->blit_hw) ? "yes" : "no"));
+ logger->log("Accelerated hardware to hardware colorkey blits: %s",
+ ((vi->blit_hw_CC) ? "yes" : "no"));
+ logger->log("Accelerated hardware to hardware alpha blits: %s",
+ ((vi->blit_hw_A) ? "yes" : "no"));
+ logger->log("Accelerated software to hardware blits: %s",
+ ((vi->blit_sw) ? "yes" : "no"));
+ logger->log("Accelerated software to hardware colorkey blits: %s",
+ ((vi->blit_sw_CC) ? "yes" : "no"));
+ logger->log("Accelerated software to hardware alpha blits: %s",
+ ((vi->blit_sw_A) ? "yes" : "no"));
+ logger->log("Accelerated color fills: %s",
+ ((vi->blit_fill) ? "yes" : "no"));
+ logger->log("Available video memory: %d", vi->video_mem);
+
+ return true;
+}
+
+bool Graphics::setFullscreen(bool fs)
+{
+ if (mFullscreen == fs)
+ return true;
+
+ return setVideoMode(mWidth, mHeight, mBpp, fs, mHWAccel);
+}
+
+int Graphics::getWidth() const
+{
+ return mWidth;
+}
+
+int Graphics::getHeight() const
+{
+ return mHeight;
+}
+
+bool Graphics::drawImage(Image *image, int x, int y)
+{
+ if (image)
+ {
+ return drawImage(image, 0, 0, x, y,
+ image->mBounds.w, image->mBounds.h);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor _UNUSED_)
+{
+ // Check that preconditions for blitting are met.
+ if (!mTarget || !image)
+ return false;
+ if (!image->mSDLSurface)
+ return false;
+
+ Image *tmpImage = image->SDLgetScaledImage(desiredWidth, desiredHeight);
+// logger->log("SDLgetScaledImage " + tmpImage->getIdPath()
+// + toString(desiredWidth) + "," + toString(desiredHeight));
+
+ bool returnValue = false;
+
+ if (!tmpImage)
+ return false;
+ if (!tmpImage->mSDLSurface)
+ return false;
+
+ dstX += mClipStack.top().xOffset;
+ dstY += mClipStack.top().yOffset;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = static_cast<short>(dstX);
+ dstRect.y = static_cast<short>(dstY);
+ srcRect.x = static_cast<short>(srcX);
+ srcRect.y = static_cast<short>(srcY);
+ srcRect.w = static_cast<Uint16>(width);
+ srcRect.h = static_cast<Uint16>(height);
+
+ returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface,
+ &srcRect, mTarget, &dstRect) < 0);
+
+ delete tmpImage;
+
+ return returnValue;
+}
+
+bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY,
+ int width, int height, bool)
+{
+ // Check that preconditions for blitting are met.
+ if (!mTarget || !image || !image->mSDLSurface)
+ return false;
+
+ dstX += mClipStack.top().xOffset;
+ dstY += mClipStack.top().yOffset;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = static_cast<short>(dstX);
+ dstRect.y = static_cast<short>(dstY);
+ srcRect.x = static_cast<short>(srcX);
+ srcRect.y = static_cast<short>(srcY);
+ srcRect.w = static_cast<Uint16>(width);
+ srcRect.h = static_cast<Uint16>(height);
+
+ if (mBlitMode == BLIT_NORMAL)
+ {
+ return !(SDL_BlitSurface(image->mSDLSurface, &srcRect,
+ mTarget, &dstRect) < 0);
+ }
+ else
+ {
+ return !(SDL_gfxBlitRGBA(image->mSDLSurface, &srcRect,
+ mTarget, &dstRect) < 0);
+ }
+}
+
+void Graphics::drawImage(gcn::Image const *image, int srcX, int srcY,
+ int dstX, int dstY, int width, int height)
+{
+ ProxyImage const *srcImage =
+ dynamic_cast< ProxyImage const * >(image);
+ if (!srcImage)
+ return;
+ drawImage(srcImage->getImage(), srcX, srcY, dstX, dstY,
+ width, height, true);
+}
+
+void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
+{
+ // Check that preconditions for blitting are met.
+ if (!mTarget || !image)
+ return;
+ if (!image->mSDLSurface)
+ return;
+
+ const int iw = image->getWidth();
+ const int ih = image->getHeight();
+
+ if (iw == 0 || ih == 0) return;
+
+ for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ {
+ int dh = (py + ih >= h) ? h - py : ih;
+ int srcY = image->mBounds.y;
+ int dstY = y + py + mClipStack.top().yOffset;
+
+ for (int px = 0; px < w; px += iw) // X position on pattern plane
+ {
+ int dw = (px + iw >= w) ? w - px : iw;
+ int srcX = image->mBounds.x;
+ int dstX = x + px + mClipStack.top().xOffset;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = static_cast<short>(dstX);
+ dstRect.y = static_cast<short>(dstY);
+ srcRect.x = static_cast<short>(srcX);
+ srcRect.y = static_cast<short>(srcY);
+ srcRect.w = static_cast<Uint16>(dw);
+ srcRect.h = static_cast<Uint16>(dh);
+
+ SDL_BlitSurface(image->mSDLSurface, &srcRect, mTarget, &dstRect);
+ }
+ }
+}
+
+void Graphics::drawRescaledImagePattern(Image *image, int x, int y,
+ int w, int h, int scaledWidth,
+ int scaledHeight)
+{
+ // Check that preconditions for blitting are met.
+ if (!mTarget || !image)
+ return;
+ if (!image->mSDLSurface)
+ return;
+
+ if (scaledHeight == 0 || scaledWidth == 0)
+ return;
+
+ Image *tmpImage = image->SDLgetScaledImage(scaledWidth, scaledHeight);
+ if (!tmpImage)
+ return;
+
+// logger->log("SDLgetScaledImageS " + tmpImage->getIdPath()
+// + toString(scaledWidth) + "," + toString(scaledHeight));
+
+ const int iw = tmpImage->getWidth();
+ const int ih = tmpImage->getHeight();
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ {
+ int dh = (py + ih >= h) ? h - py : ih;
+ int srcY = tmpImage->mBounds.y;
+ int dstY = y + py + mClipStack.top().yOffset;
+
+ for (int px = 0; px < w; px += iw) // X position on pattern plane
+ {
+ int dw = (px + iw >= w) ? w - px : iw;
+ int srcX = tmpImage->mBounds.x;
+ int dstX = x + px + mClipStack.top().xOffset;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = static_cast<short>(dstX);
+ dstRect.y = static_cast<short>(dstY);
+ srcRect.x = static_cast<short>(srcX);
+ srcRect.y = static_cast<short>(srcY);
+ srcRect.w = static_cast<Uint16>(dw);
+ srcRect.h = static_cast<Uint16>(dh);
+
+ SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
+ mTarget, &dstRect);
+ }
+ }
+
+ delete tmpImage;
+}
+
+void Graphics::drawImageRect(int x, int y, int w, int h,
+ Image *topLeft, Image *topRight,
+ Image *bottomLeft, Image *bottomRight,
+ Image *top, Image *right,
+ Image *bottom, Image *left,
+ Image *center)
+{
+ pushClipArea(gcn::Rectangle(x, y, w, h));
+
+ const bool drawMain = center && topLeft && topRight
+ && bottomLeft && bottomRight;
+
+ // Draw the center area
+ if (center && drawMain)
+ {
+ drawImagePattern(center,
+ topLeft->getWidth(), topLeft->getHeight(),
+ w - topLeft->getWidth() - topRight->getWidth(),
+ h - topLeft->getHeight() - bottomLeft->getHeight());
+ }
+
+ // Draw the sides
+ if (top && left && bottom && right)
+ {
+ drawImagePattern(top,
+ left->getWidth(), 0,
+ w - left->getWidth() - right->getWidth(), top->getHeight());
+ drawImagePattern(bottom,
+ left->getWidth(), h - bottom->getHeight(),
+ w - left->getWidth() - right->getWidth(),
+ bottom->getHeight());
+ drawImagePattern(left,
+ 0, top->getHeight(),
+ left->getWidth(),
+ h - top->getHeight() - bottom->getHeight());
+ drawImagePattern(right,
+ w - right->getWidth(), top->getHeight(),
+ right->getWidth(),
+ h - top->getHeight() - bottom->getHeight());
+ }
+
+ // Draw the corners
+ if (drawMain)
+ {
+ drawImage(topLeft, 0, 0);
+ drawImage(topRight, w - topRight->getWidth(), 0);
+ drawImage(bottomLeft, 0, h - bottomLeft->getHeight());
+ drawImage(bottomRight,
+ w - bottomRight->getWidth(),
+ h - bottomRight->getHeight());
+ }
+
+ popClipArea();
+}
+
+void Graphics::drawImageRect(int x, int y, int w, int h,
+ const ImageRect &imgRect)
+{
+ drawImageRect(x, y, w, h,
+ imgRect.grid[0], imgRect.grid[2], imgRect.grid[6], imgRect.grid[8],
+ imgRect.grid[1], imgRect.grid[5], imgRect.grid[7], imgRect.grid[3],
+ imgRect.grid[4]);
+}
+
+void Graphics::updateScreen()
+{
+ SDL_Flip(mTarget);
+}
+
+SDL_Surface *Graphics::getScreenshot()
+{
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ int rmask = 0xff000000;
+ int gmask = 0x00ff0000;
+ int bmask = 0x0000ff00;
+#else
+ int rmask = 0x000000ff;
+ int gmask = 0x0000ff00;
+ int bmask = 0x00ff0000;
+#endif
+ int amask = 0x00000000;
+
+ SDL_Surface *screenshot = SDL_CreateRGBSurface(SDL_SWSURFACE, mTarget->w,
+ mTarget->h, 24, rmask, gmask, bmask, amask);
+
+ if (screenshot)
+ SDL_BlitSurface(mTarget, NULL, screenshot, NULL);
+
+ return screenshot;
+}
+
+bool Graphics::drawNet(int x1, int y1, int x2, int y2, int width, int height)
+{
+ for (int y = y1; y < y2; y += height)
+ drawLine(x1, y, x2, y);
+
+ for (int x = x1; x < x2; x += width)
+ drawLine(x, y1, x, y2);
+
+ return true;
+}
diff --git a/src/graphics.h b/src/graphics.h
new file mode 100644
index 000000000..01224533e
--- /dev/null
+++ b/src/graphics.h
@@ -0,0 +1,241 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+#include <guichan/sdl/sdlgraphics.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+class ImageRect;
+
+struct SDL_Surface;
+
+static const int defaultScreenWidth = 800;
+static const int defaultScreenHeight = 600;
+
+/**
+ * 9 images defining a rectangle. 4 corners, 4 sides and a middle area. The
+ * topology is as follows:
+ *
+ * <pre>
+ * !-----!-----------------!-----!
+ * ! 0 ! 1 ! 2 !
+ * !-----!-----------------!-----!
+ * ! 3 ! 4 ! 5 !
+ * !-----!-----------------!-----!
+ * ! 6 ! 7 ! 8 !
+ * !-----!-----------------!-----!
+ * </pre>
+ *
+ * Sections 0, 2, 6 and 8 will remain as is. 1, 3, 4, 5 and 7 will be
+ * repeated to fit the size of the widget.
+ */
+struct ImageRect
+{
+ enum ImagePosition
+ {
+ UPPER_LEFT = 0,
+ UPPER_CENTER = 1,
+ UPPER_RIGHT = 2,
+ LEFT = 3,
+ CENTER = 4,
+ RIGHT = 5,
+ LOWER_LEFT = 6,
+ LOWER_CENTER = 7,
+ LOWER_RIGHT = 8
+ };
+
+ Image *grid[9];
+};
+
+/**
+ * A central point of control for graphics.
+ */
+class Graphics : public gcn::SDLGraphics
+{
+ public:
+ enum BlitMode
+ {
+ BLIT_NORMAL = 0,
+ BLIT_GFX
+ };
+
+ /**
+ * Constructor.
+ */
+ Graphics();
+
+ /**
+ * Destructor.
+ */
+ virtual ~Graphics();
+
+ /**
+ * Try to create a window with the given settings.
+ */
+ virtual bool setVideoMode(int w, int h, int bpp,
+ bool fs, bool hwaccel);
+
+ /**
+ * Set fullscreen mode.
+ */
+ bool setFullscreen(bool fs);
+
+ /**
+ * Blits an image onto the screen.
+ *
+ * @return <code>true</code> if the image was blitted properly
+ * <code>false</code> otherwise.
+ */
+ bool drawImage(Image *image, int x, int y);
+
+ /**
+ * Overrides with our own drawing method.
+ */
+ void drawImage(gcn::Image const *image, int srcX, int srcY,
+ int dstX, int dstY, int width, int height);
+
+ /**
+ * Draws a resclaled version of the image
+ */
+ bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight)
+ {
+ return drawRescaledImage(image, srcX, srcY,
+ dstX, dstY,
+ width, height,
+ desiredWidth, desiredHeight,
+ false);
+ };
+
+ /**
+ * Draws a resclaled version of the image
+ */
+ virtual bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor = false);
+
+ /**
+ * Blits an image onto the screen.
+ *
+ * @return <code>true</code> if the image was blitted properly
+ * <code>false</code> otherwise.
+ */
+ virtual bool drawImage(Image *image,
+ int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ bool useColor = false);
+
+ virtual void drawImagePattern(Image *image,
+ int x, int y,
+ int w, int h);
+
+ /**
+ * Draw a pattern based on a rescaled version of the given image...
+ */
+ virtual void drawRescaledImagePattern(Image *image,
+ int x, int y, int w, int h,
+ int scaledWidth,
+ int scaledHeight);
+
+ /**
+ * Draws a rectangle using images. 4 corner images, 4 side images and 1
+ * image for the inside.
+ */
+ void drawImageRect(int x, int y, int w, int h,
+ Image *topLeft, Image *topRight,
+ Image *bottomLeft, Image *bottomRight,
+ Image *top, Image *right,
+ Image *bottom, Image *left,
+ Image *center);
+
+ /**
+ * Draws a rectangle using images. 4 corner images, 4 side images and 1
+ * image for the inside.
+ */
+ void drawImageRect(int x, int y, int w, int h,
+ const ImageRect &imgRect);
+
+ /**
+ * Draws a rectangle using images. 4 corner images, 4 side images and 1
+ * image for the inside.
+ */
+ inline void drawImageRect(const gcn::Rectangle &area,
+ const ImageRect &imgRect)
+ { drawImageRect(area.x, area.y, area.width, area.height, imgRect); }
+
+ void setBlitMode(BlitMode mode)
+ { mBlitMode = mode; }
+
+ BlitMode getBlitMode()
+ { return mBlitMode; }
+
+ /**
+ * Updates the screen. This is done by either copying the buffer to the
+ * screen or swapping pages.
+ */
+ virtual void updateScreen();
+
+ /**
+ * Returns the width of the screen.
+ */
+ int getWidth() const;
+
+ /**
+ * Returns the height of the screen.
+ */
+ int getHeight() const;
+
+ /**
+ * Takes a screenshot and returns it as SDL surface.
+ */
+ virtual SDL_Surface *getScreenshot();
+
+ virtual bool drawNet(int x1, int y1, int x2, int y2,
+ int width, int height);
+
+ gcn::Font *getFont() const
+ { return mFont; }
+
+ protected:
+ int mWidth;
+ int mHeight;
+ int mBpp;
+ bool mFullscreen;
+ bool mHWAccel;
+ BlitMode mBlitMode;
+};
+
+extern Graphics *graphics;
+
+#endif
diff --git a/src/gui/beingpopup.cpp b/src/gui/beingpopup.cpp
new file mode 100644
index 000000000..6b3a25ee4
--- /dev/null
+++ b/src/gui/beingpopup.cpp
@@ -0,0 +1,142 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/beingpopup.h"
+
+#include "being.h"
+#include "graphics.h"
+#include "units.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+
+#include "gui/widgets/label.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+
+
+BeingPopup::BeingPopup():
+ Popup("BeingPopup")
+{
+ // Being Name
+ mBeingName = new Label("A");
+ mBeingName->setFont(boldFont);
+ mBeingName->setPosition(getPadding(), getPadding());
+
+ const int fontHeight = mBeingName->getHeight() + getPadding();
+
+ // Being's party
+ mBeingParty = new Label("A");
+ mBeingParty->setPosition(getPadding(), fontHeight);
+
+ // Being's party
+ mBeingGuild = new Label("A");
+ mBeingGuild->setPosition(getPadding(), 2 * fontHeight);
+
+ mBeingRank = new Label("A");
+ mBeingRank->setPosition(getPadding(), 3 * fontHeight);
+
+ add(mBeingName);
+ add(mBeingParty);
+ add(mBeingGuild);
+ add(mBeingRank);
+}
+
+BeingPopup::~BeingPopup()
+{
+}
+
+void BeingPopup::show(int x, int y, Being *b)
+{
+ if (!b)
+ {
+ setVisible(false);
+ return;
+ }
+
+ Label *label1 = mBeingParty;
+ Label *label2 = mBeingGuild;
+ Label *label3 = mBeingRank;
+
+ mBeingName->setCaption(b->getName());
+ mBeingName->adjustSize();
+ label1->setCaption("");
+ label2->setCaption("");
+ label3->setCaption("");
+
+ if (!(b->getPartyName().empty()))
+ {
+ label1->setCaption(strprintf(_("Party: %s"),
+ b->getPartyName().c_str()));
+ label1->adjustSize();
+ }
+ else
+ {
+ label3 = label2;
+ label2 = label1;
+ label1 = 0;
+ }
+
+ if (!(b->getGuildName().empty()))
+ {
+ label2->setCaption(strprintf(_("Guild: %s"),
+ b->getGuildName().c_str()));
+ label2->adjustSize();
+ }
+ else
+ {
+ label3 = label2;
+ label2 = 0;
+ }
+
+ if (b->getPvpRank() > 0)
+ {
+ label3->setCaption(strprintf(_("Pvp rank: %d"), b->getPvpRank()));
+ label3->adjustSize();
+ }
+ else
+ {
+ label3 = 0;
+ }
+
+ int minWidth = mBeingName->getWidth();
+ if (label1 && label1->getWidth() > minWidth)
+ minWidth = label1->getWidth();
+ if (label2 && label2->getWidth() > minWidth)
+ minWidth = label2->getWidth();
+ if (label3 && label3->getWidth() > minWidth)
+ minWidth = label3->getWidth();
+
+ int height = getFont()->getHeight();
+ if (label1)
+ height += getFont()->getHeight();
+ if (label2)
+ height += getFont()->getHeight();
+ if (label3)
+ height += getFont()->getHeight();
+
+ setContentSize(minWidth + 10, height + 10);
+
+ position(x, y);
+ return;
+}
diff --git a/src/gui/beingpopup.h b/src/gui/beingpopup.h
new file mode 100644
index 000000000..d43f8e105
--- /dev/null
+++ b/src/gui/beingpopup.h
@@ -0,0 +1,59 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BEINGPOPUP_H
+#define BEINGPOPUP_H
+
+#include "gui/widgets/popup.h"
+
+class Being;
+class Label;
+
+/**
+ * A popup that displays information about a being.
+ */
+class BeingPopup : public Popup
+{
+ public:
+ /**
+ * Constructor. Initializes the being popup.
+ */
+ BeingPopup();
+
+ /**
+ * Destructor. Cleans up the being popup on deletion.
+ */
+ ~BeingPopup();
+
+ /**
+ * Sets the info to be displayed given a particular player.
+ */
+ void show(int x, int y, Being *b);
+
+ // TODO: Add a version for monsters, NPCs, etc?
+
+ private:
+ Label *mBeingName;
+ Label *mBeingParty;
+ Label *mBeingGuild;
+ Label *mBeingRank;
+};
+
+#endif // BEINGPOPUP_H
diff --git a/src/gui/botcheckerwindow.cpp b/src/gui/botcheckerwindow.cpp
new file mode 100644
index 000000000..f7bd7d060
--- /dev/null
+++ b/src/gui/botcheckerwindow.cpp
@@ -0,0 +1,413 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "botcheckerwindow.h"
+
+#include <SDL.h>
+#include <SDL_thread.h>
+#include <vector>
+#include <algorithm>
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/table.h"
+
+#include "actorspritemanager.h"
+#include "chat.h"
+#include "configuration.h"
+#include "localplayer.h"
+#include "main.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+
+#define COLUMNS_NR 5 // name plus listbox
+#define NAME_COLUMN 0
+#define TIME_COLUMN 1
+
+#define ROW_HEIGHT 12
+// The following column widths really shouldn't be hardcoded but should scale with the size of the widget... excep
+// that, right now, the widget doesn't exactly scale either.
+#define NAME_COLUMN_WIDTH 185
+#define TIME_COLUMN_WIDTH 70
+
+#define WIDGET_AT(row, column) (((row) * COLUMNS_NR) + column)
+
+class UsersTableModel : public TableModel
+{
+public:
+ UsersTableModel() :
+ mPlayers(0)
+ {
+ playersUpdated();
+ }
+
+ virtual ~UsersTableModel()
+ {
+ freeWidgets();
+ }
+
+ virtual int getRows() const
+ {
+ return static_cast<int>(mPlayers.size());
+ }
+
+ virtual int getColumns() const
+ {
+ return COLUMNS_NR;
+ }
+
+ virtual int getRowHeight() const
+ {
+ return ROW_HEIGHT;
+ }
+
+ virtual int getColumnWidth(int index) const
+ {
+ if (index == NAME_COLUMN)
+ return NAME_COLUMN_WIDTH;
+ else
+ return TIME_COLUMN_WIDTH;
+ }
+
+ virtual void playersUpdated()
+ {
+ signalBeforeUpdate();
+
+ freeWidgets();
+ mPlayers.clear();
+ if (actorSpriteManager && botCheckerWindow
+ && botCheckerWindow->mEnabled)
+ {
+ std::set<ActorSprite*> beings = actorSpriteManager->getAll();
+ ActorSprites::iterator i = beings.begin();
+ for (ActorSprites::const_iterator i = beings.begin();
+ i != beings.end(); i++)
+ {
+ Being *being = dynamic_cast<Being*>(*i);
+
+ if (being && being->getType() == Being::PLAYER
+ && being != player_node && being->getName() != "")
+ {
+ mPlayers.push_back(being);
+ }
+ }
+ }
+
+ unsigned int curTime = cur_time;
+ // set up widgets
+ for (unsigned int r = 0; r < mPlayers.size(); ++r)
+ {
+ if (!mPlayers.at(r))
+ continue;
+
+ std::string name = mPlayers.at(r)->getName();
+ gcn::Widget *widget = new Label(name);
+
+ mWidgets.push_back(widget);
+
+ if (mPlayers.at(r)->getAttackTime() != 0)
+ {
+ widget = new Label(toString(curTime
+ - mPlayers.at(r)->getAttackTime()));
+ }
+ else
+ {
+ widget = new Label(toString(curTime
+ - mPlayers.at(r)->getTestTime()) + "?");
+ }
+ mWidgets.push_back(widget);
+
+ if (mPlayers.at(r)->getTalkTime() != 0)
+ {
+ widget = new Label(toString(curTime
+ - mPlayers.at(r)->getTalkTime()));
+ }
+ else
+ {
+ widget = new Label(toString(curTime
+ - mPlayers.at(r)->getTestTime()) + "?");
+ }
+ mWidgets.push_back(widget);
+
+ if (mPlayers.at(r)->getMoveTime() != 0)
+ {
+ widget = new Label(toString(curTime
+ - mPlayers.at(r)->getMoveTime()));
+ }
+ else
+ {
+ widget = new Label(toString(curTime
+ - mPlayers.at(r)->getTestTime()) + "?");
+ }
+ mWidgets.push_back(widget);
+
+ std::string str;
+ bool talkBot = false;
+ bool moveBot = false;
+ bool attackBot = false;
+ bool otherBot = false;
+
+ if (curTime - mPlayers.at(r)->getTestTime() > 2 * 60)
+ {
+ int attack = curTime - (mPlayers.at(r)->getAttackTime()
+ ? mPlayers.at(r)->getAttackTime()
+ : mPlayers.at(r)->getTestTime());
+ int talk = curTime - (mPlayers.at(r)->getTalkTime()
+ ? mPlayers.at(r)->getTalkTime()
+ : mPlayers.at(r)->getTestTime()) - attack;
+ int move = curTime - (mPlayers.at(r)->getMoveTime()
+ ? mPlayers.at(r)->getMoveTime()
+ : mPlayers.at(r)->getTestTime()) - attack;
+ int other = curTime - (mPlayers.at(r)->getOtherTime()
+ ? mPlayers.at(r)->getMoveTime()
+ : mPlayers.at(r)->getOtherTime()) - attack;
+
+ if (attack < 2 * 60)
+ attackBot = true;
+
+ // attacking but not talking more than 2 minutes
+ if (talk > 2 * 60 && talk > 2 * 60)
+ {
+ talkBot = true;
+ str += toString((talk) / 60) + " ";
+ }
+
+ // attacking but not moving more than 2 minutes
+ if (move > 2 * 60 && move > 2 * 60)
+ {
+ moveBot = true;
+ str += toString((move) / 60);
+ }
+
+ // attacking but not other activity more than 2 minutes
+ if (move > 2 * 60 && other > 2 * 60)
+ otherBot = true;
+ }
+
+ if (str.length() > 0)
+ {
+ if (attackBot && talkBot && moveBot && otherBot)
+ str = "bot!! " + str;
+ else if (attackBot && talkBot && moveBot)
+ str = "bot! " + str;
+ else if (talkBot && moveBot)
+ str = "bot " + str;
+ else if (talkBot || moveBot)
+ str = "bot? " + str;
+ }
+ else
+ {
+ str = "ok";
+ }
+
+ widget = new Label(str);
+ mWidgets.push_back(widget);
+
+ }
+
+ signalAfterUpdate();
+ }
+
+ virtual void updateModelInRow(int row _UNUSED_)
+ {
+ }
+
+
+ virtual gcn::Widget *getElementAt(int row, int column) const
+ {
+ return mWidgets[WIDGET_AT(row, column)];
+ }
+
+ virtual void freeWidgets()
+ {
+ for (std::vector<gcn::Widget *>::const_iterator it = mWidgets.begin();
+ it != mWidgets.end(); it++)
+ {
+ delete *it;
+ }
+
+ mWidgets.clear();
+ }
+
+protected:
+ std::vector<Being*> mPlayers;
+ std::vector<gcn::Widget*> mWidgets;
+};
+
+
+BotCheckerWindow::BotCheckerWindow():
+ Window(_("Bot Checker")),
+ mEnabled(false)
+{
+ int w = 500;
+ int h = 250;
+
+ mLastUpdateTime = 0;
+ mNeedUpdate = false;
+
+ mTableModel = new UsersTableModel();
+ mTable = new GuiTable(mTableModel);
+ mTable->setOpaque(false);
+ mTable->setLinewiseSelection(true);
+ mTable->setWrappingEnabled(true);
+ mTable->setActionEventId("skill");
+ mTable->addActionListener(this);
+
+ mPlayerTableTitleModel = new StaticTableModel(1, COLUMNS_NR);
+ mPlayerTableTitleModel->fixColumnWidth(NAME_COLUMN, NAME_COLUMN_WIDTH);
+
+ for (int f = 0; f < 4; f++)
+ {
+ mPlayerTableTitleModel->fixColumnWidth(TIME_COLUMN + f,
+ TIME_COLUMN_WIDTH);
+ }
+
+ mPlayerTitleTable = new GuiTable(mPlayerTableTitleModel);
+ //mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf));
+ mPlayerTitleTable->setHeight(1);
+
+ mPlayerTableTitleModel->set(0, 0, new Label(_("Name")));
+ mPlayerTableTitleModel->set(0, 1, new Label(_("Attack")));
+ mPlayerTableTitleModel->set(0, 2, new Label(_("Talk")));
+ mPlayerTableTitleModel->set(0, 3, new Label(_("Move")));
+ mPlayerTableTitleModel->set(0, 4, new Label(_("Result")));
+
+ mPlayerTitleTable->setLinewiseSelection(true);
+
+ setWindowName("BotCheckerWindow");
+ setCloseButton(true);
+ setDefaultSize(w, h, ImageRect::CENTER);
+
+ playersScrollArea = new ScrollArea(mTable);
+
+ mIncButton = new Button(_("Reset"), "reset", this);
+ playersScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mPlayerTitleTable->setPosition(getPadding(), getPadding());
+ mPlayerTitleTable->setWidth(w - 10);
+ mPlayerTitleTable->setHeight(20);
+
+ playersScrollArea->setPosition(getPadding(), 20 + 2*getPadding());
+ playersScrollArea->setWidth(w - 15);
+ playersScrollArea->setHeight(h - 80);
+
+ mIncButton->setPosition(getPadding(), 190 + 3*getPadding());
+ mIncButton->setWidth(80);
+ mIncButton->setHeight(20);
+
+ add(mPlayerTitleTable);
+ add(playersScrollArea);
+ add(mIncButton);
+
+ center();
+
+ setWidth(w);
+ setHeight(h);
+ loadWindowState();
+
+ config.addListener("enableBotCheker", this);
+ mEnabled = config.getBoolValue("enableBotCheker");
+}
+
+BotCheckerWindow::~BotCheckerWindow()
+{
+ config.removeListener("enableBotCheker", this);
+}
+
+void BotCheckerWindow::logic()
+{
+ if (mEnabled && mTableModel)
+ {
+ unsigned int nowTime = cur_time;
+ if (nowTime - mLastUpdateTime > 5 && mNeedUpdate)
+ {
+ mTableModel->playersUpdated();
+ mNeedUpdate = false;
+ mLastUpdateTime = nowTime;
+ }
+ else if (nowTime - mLastUpdateTime > 15)
+ {
+ mTableModel->playersUpdated();
+ mNeedUpdate = false;
+ mLastUpdateTime = nowTime;
+ }
+ }
+
+ Window::logic();
+}
+
+void BotCheckerWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "reset")
+ {
+ reset();
+ mNeedUpdate = true;
+ }
+
+}
+
+void BotCheckerWindow::update()
+{
+}
+
+void BotCheckerWindow::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+}
+
+void BotCheckerWindow::updateList()
+{
+ if (mTableModel)
+ mNeedUpdate = true;
+}
+
+void BotCheckerWindow::reset()
+{
+ if (actorSpriteManager)
+ {
+ std::set<ActorSprite*> beings = actorSpriteManager->getAll();
+ ActorSprites::iterator i = beings.begin();
+ for (ActorSprites::const_iterator i = beings.begin();
+ i != beings.end(); i++)
+ {
+ Being *being = dynamic_cast<Being*>(*i);
+
+ if (being && being->getType() == Being::PLAYER
+ && being != player_node && being->getName() != "")
+ {
+ being->resetCounters();
+ }
+ }
+ }
+}
+
+void BotCheckerWindow::optionChanged(const std::string &name)
+{
+ if (name == "enableBotCheker")
+ mEnabled = config.getBoolValue("enableBotCheker");
+}
diff --git a/src/gui/botcheckerwindow.h b/src/gui/botcheckerwindow.h
new file mode 100644
index 000000000..cb225d3e7
--- /dev/null
+++ b/src/gui/botcheckerwindow.h
@@ -0,0 +1,95 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef BOTCHECKER_H
+#define BOTCHECKER_H
+
+#include "configlistener.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <vector>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+struct BOTCHK
+{
+ short id; /**< Index into "botchecker_db" array */
+ short lv, sp;
+};
+
+class GuiTable;
+class ScrollArea;
+class UsersTableModel;
+class StaticTableModel;
+
+class BotCheckerWindow : public Window, public gcn::ActionListener,
+ public ConfigListener
+{
+ public:
+ friend class UsersTableModel;
+
+ /**
+ * Constructor.
+ */
+ BotCheckerWindow();
+
+ /**
+ * Destructor.
+ */
+ ~BotCheckerWindow();
+
+ void action(const gcn::ActionEvent &event);
+
+ void update();
+
+ void logic();
+
+ void widgetResized(const gcn::Event &event);
+
+ void updateList();
+
+ void reset();
+
+ void optionChanged(const std::string &name);
+
+ private:
+ GuiTable *mTable;
+ ScrollArea *playersScrollArea;
+ UsersTableModel *mTableModel;
+ StaticTableModel *mPlayerTableTitleModel;
+ GuiTable *mPlayerTitleTable;
+ gcn::Button *mIncButton;
+ int mLastUpdateTime;
+ bool mNeedUpdate;
+ bool mEnabled;
+};
+
+extern BotCheckerWindow *botCheckerWindow;
+
+#endif
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
new file mode 100644
index 000000000..2be6c65a4
--- /dev/null
+++ b/src/gui/buy.cpp
@@ -0,0 +1,323 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/buy.h"
+
+#include "shopitem.h"
+#include "units.h"
+
+#include "gui/setup.h"
+#include "gui/trade.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/shopitems.h"
+#include "gui/widgets/shoplistbox.h"
+#include "gui/widgets/slider.h"
+
+#include "shopitem.h"
+#include "units.h"
+
+#include "net/buysellhandler.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+BuyDialog::DialogList BuyDialog::instances;
+
+BuyDialog::BuyDialog(int npcId):
+ Window(_("Buy")),
+ mNpcId(npcId), mMoney(0), mAmountItems(0), mMaxItems(0), mNick("")
+{
+ init();
+}
+
+BuyDialog::BuyDialog(std::string nick):
+ Window(_("Buy")),
+ mNpcId(-1), mMoney(0), mAmountItems(0), mMaxItems(0), mNick(nick)
+{
+ init();
+ logger->log("BuyDialog::BuyDialog nick:" + mNick);
+}
+
+void BuyDialog::init()
+{
+ setWindowName("Buy");
+ setResizable(true);
+ setCloseButton(true);
+ setMinWidth(260);
+ setMinHeight(230);
+ setDefaultSize(260, 230, ImageRect::CENTER);
+
+ mShopItems = new ShopItems;
+
+ mShopItemList = new ShopListBox(mShopItems, mShopItems);
+ mScrollArea = new ScrollArea(mShopItemList);
+ mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mSlider = new Slider(1.0);
+ mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mQuantityLabel->setAlignment(gcn::Graphics::CENTER);
+ mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"),
+ "", ""));
+
+ // TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+ // You may change this symbol if your language uses another.
+ mIncreaseButton = new Button(_("+"), "inc", this);
+ // TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+ // You may change this symbol if your language uses another.
+ mDecreaseButton = new Button(_("-"), "dec", this);
+ mBuyButton = new Button(_("Buy"), "buy", this);
+ mQuitButton = new Button(_("Quit"), "quit", this);
+ mAddMaxButton = new Button(_("Max"), "max", this);
+
+ mDecreaseButton->adjustSize();
+ mDecreaseButton->setWidth(mIncreaseButton->getWidth());
+
+ mIncreaseButton->setEnabled(false);
+ mDecreaseButton->setEnabled(false);
+ mBuyButton->setEnabled(false);
+ mSlider->setEnabled(false);
+
+ mSlider->setActionEventId("slider");
+ mSlider->addActionListener(this);
+ mShopItemList->addSelectionListener(this);
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mScrollArea, 8, 5).setPadding(3);
+ place(0, 5, mDecreaseButton);
+ place(1, 5, mSlider, 3);
+ place(4, 5, mIncreaseButton);
+ place(5, 5, mQuantityLabel, 2);
+ place(7, 5, mAddMaxButton);
+ place(0, 6, mMoneyLabel, 8);
+ place(6, 7, mBuyButton);
+ place(7, 7, mQuitButton);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+
+ center();
+ loadWindowState();
+
+ instances.push_back(this);
+ setVisible(true);
+}
+
+BuyDialog::~BuyDialog()
+{
+ delete mShopItems;
+ mShopItems = 0;
+
+ instances.remove(this);
+}
+
+void BuyDialog::setMoney(int amount)
+{
+ mMoney = amount;
+ mShopItemList->setPlayersMoney(amount);
+
+ updateButtonsAndLabels();
+}
+
+void BuyDialog::reset()
+{
+ mShopItems->clear();
+ mShopItemList->adjustSize();
+
+ // Reset previous selected items to prevent failing asserts
+ mShopItemList->setSelected(-1);
+ mSlider->setValue(0);
+
+ setMoney(0);
+}
+
+void BuyDialog::addItem(int id, int amount, int price)
+{
+ mShopItems->addItem(id, amount, price);
+ mShopItemList->adjustSize();
+}
+
+void BuyDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "quit")
+ {
+ close();
+ return;
+ }
+
+ int selectedItem = mShopItemList->getSelected();
+
+ // The following actions require a valid selection
+ if (selectedItem < 0 ||
+ selectedItem >= static_cast<int>(mShopItems->getNumberOfElements()))
+ {
+ return;
+ }
+
+ if (event.getId() == "slider")
+ {
+ mAmountItems = static_cast<int>(mSlider->getValue());
+ updateButtonsAndLabels();
+ }
+ else if (event.getId() == "inc" && mAmountItems < mMaxItems)
+ {
+ mAmountItems++;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
+ else if (event.getId() == "dec" && mAmountItems > 1)
+ {
+ mAmountItems--;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
+ else if (event.getId() == "max")
+ {
+ mAmountItems = mMaxItems;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
+ // TODO: Actually we'd have a bug elsewhere if this check for the number
+ // of items to be bought ever fails, Bertram removed the assertions, is
+ // there a better way to ensure this fails in an _obvious_ way in C++?
+ else if (event.getId() == "buy" && mAmountItems > 0 &&
+ mAmountItems <= mMaxItems)
+ {
+ if (mNpcId != -1)
+ {
+ Net::getNpcHandler()->buyItem(mNpcId,
+ mShopItems->at(selectedItem)->getId(), mAmountItems);
+
+ // Update money and adjust the max number of items that can be bought
+ mMaxItems -= mAmountItems;
+ setMoney(mMoney -
+ mAmountItems * mShopItems->at(selectedItem)->getPrice());
+
+ // Reset selection
+ mAmountItems = 1;
+ mSlider->setValue(1);
+ mSlider->gcn::Slider::setScale(1, mMaxItems);
+ }
+ else if (tradeWindow)
+ {
+ ShopItem *item = mShopItems->at(selectedItem);
+ if (item)
+ {
+ Net::getBuySellHandler()->sendBuyRequest(mNick,
+ item, mAmountItems);
+// logger->log("buy button mNick:" + mNick);
+ if (tradeWindow)
+ {
+ tradeWindow->addAutoMoney(mNick,
+ item->getPrice() * mAmountItems);
+ }
+ }
+ }
+ }
+}
+
+void BuyDialog::valueChanged(const gcn::SelectionEvent &event _UNUSED_)
+{
+ // Reset amount of items and update labels
+ mAmountItems = 1;
+ mSlider->setValue(1);
+
+ updateButtonsAndLabels();
+ mSlider->gcn::Slider::setScale(1, mMaxItems);
+}
+
+void BuyDialog::updateButtonsAndLabels()
+{
+ const int selectedItem = mShopItemList->getSelected();
+ int price = 0;
+
+ if (selectedItem > -1)
+ {
+ ShopItem * item = mShopItems->at(selectedItem);
+ if (item)
+ {
+ int itemPrice = item->getPrice();
+
+ // Calculate how many the player can afford
+ if (itemPrice)
+ mMaxItems = mMoney / itemPrice;
+ else
+ mMaxItems = 1;
+
+ if (item->getQuantity() > 0 && mMaxItems > item->getQuantity())
+ mMaxItems = item->getQuantity();
+
+ if (mAmountItems > mMaxItems)
+ mAmountItems = mMaxItems;
+
+ // Calculate price of pending purchase
+ price = mAmountItems * itemPrice;
+ }
+ }
+ else
+ {
+ mMaxItems = 0;
+ mAmountItems = 0;
+ }
+
+ // Enable or disable buttons and slider
+ mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
+ mDecreaseButton->setEnabled(mAmountItems > 1);
+ mBuyButton->setEnabled(mAmountItems > 0);
+ mSlider->setEnabled(mMaxItems > 1);
+
+ // Update quantity and money labels
+ mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"),
+ Units::formatCurrency(price).c_str(),
+ Units::formatCurrency(mMoney - price).c_str()));
+}
+
+void BuyDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (visible && mShopItemList)
+ mShopItemList->requestFocus();
+ else
+ scheduleDelete();
+}
+
+void BuyDialog::closeAll()
+{
+ DialogList::iterator it = instances.begin();
+ DialogList::iterator it_end = instances.end();
+
+ for (; it != it_end; it++)
+ {
+ if (*it)
+ (*it)->close();
+ }
+}
diff --git a/src/gui/buy.h b/src/gui/buy.h
new file mode 100644
index 000000000..5133414c1
--- /dev/null
+++ b/src/gui/buy.h
@@ -0,0 +1,151 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BUY_H
+#define BUY_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class ShopItems;
+class ShopListBox;
+class ListBox;
+
+/**
+ * The buy dialog.
+ *
+ * \ingroup Interface
+ */
+class BuyDialog : public Window, public gcn::ActionListener,
+ public gcn::SelectionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ BuyDialog(int npcId);
+
+ /**
+ * Constructor.
+ */
+ BuyDialog(std::string nick);
+
+ /**
+ * Destructor
+ */
+ ~BuyDialog();
+
+ void init();
+
+ /**
+ * Resets the dialog, clearing shop inventory.
+ */
+ void reset();
+
+ /**
+ * Sets the amount of available money.
+ */
+ void setMoney(int amount);
+
+ /**
+ * Adds an item to the shop inventory.
+ */
+ void addItem(int id, int amount, int price);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Returns the number of items in the shop inventory.
+ */
+ int getNumberOfElements();
+
+ /**
+ * Updates the labels according to the selected item.
+ */
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ /**
+ * Returns the name of item number i in the shop inventory.
+ */
+ std::string getElementAt(int i);
+
+ /**
+ * Updates the state of buttons and labels.
+ */
+ void updateButtonsAndLabels();
+
+ /**
+ * Sets the visibility of this window.
+ */
+ void setVisible(bool visible);
+
+ /**
+ * Returns true if any instances exist.
+ */
+ static bool isActive()
+ { return !instances.empty(); }
+
+ /**
+ * Closes all instances.
+ */
+ static void closeAll();
+
+ private:
+ typedef std::list<BuyDialog*> DialogList;
+ static DialogList instances;
+
+ int mNpcId;
+
+ gcn::Button *mBuyButton;
+ gcn::Button *mQuitButton;
+ gcn::Button *mAddMaxButton;
+ gcn::Button *mIncreaseButton;
+ gcn::Button *mDecreaseButton;
+ ShopListBox *mShopItemList;
+ gcn::ScrollArea *mScrollArea;
+ gcn::Label *mMoneyLabel;
+ gcn::Label *mQuantityLabel;
+ gcn::Slider *mSlider;
+
+ ShopItems *mShopItems;
+
+ int mMoney;
+ int mAmountItems;
+ int mMaxItems;
+ std::string mNick;
+};
+
+#endif
diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp
new file mode 100644
index 000000000..f6a1fc193
--- /dev/null
+++ b/src/gui/buysell.cpp
@@ -0,0 +1,137 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/buysell.h"
+
+#include "gui/setup.h"
+
+#include "gui/widgets/button.h"
+
+#include "net/buysellhandler.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+
+#include "utils/gettext.h"
+
+BuySellDialog::DialogList BuySellDialog::instances;
+
+BuySellDialog::BuySellDialog(int npcId):
+ Window(_("Shop")),
+ mNpcId(npcId),
+ mNick(""),
+ mBuyButton(0)
+{
+ init();
+}
+
+BuySellDialog::BuySellDialog(std::string nick):
+ Window(_("Shop")),
+ mNpcId(-1),
+ mNick(nick),
+ mBuyButton(0)
+{
+ init();
+}
+
+void BuySellDialog::init()
+{
+ setWindowName("BuySell");
+ //setupWindow->registerWindowForReset(this);
+ setCloseButton(true);
+
+ static const char *buttonNames[] =
+ {
+ N_("Buy"), N_("Sell"), N_("Cancel"), 0
+ };
+ int x = 10, y = 10;
+
+ for (const char **curBtn = buttonNames; *curBtn; curBtn++)
+ {
+ Button *btn = new Button(gettext(*curBtn), *curBtn, this);
+ if (!mBuyButton)
+ mBuyButton = btn; // For focus request
+ btn->setPosition(x, y);
+ add(btn);
+ x += btn->getWidth() + 10;
+ }
+ mBuyButton->requestFocus();
+
+ setContentSize(x, 2 * y + mBuyButton->getHeight());
+
+ center();
+ setDefaultSize();
+ loadWindowState();
+
+ instances.push_back(this);
+ setVisible(true);
+}
+
+BuySellDialog::~BuySellDialog()
+{
+ instances.remove(this);
+}
+
+void BuySellDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (visible)
+ {
+ if (mBuyButton)
+ mBuyButton->requestFocus();
+ }
+ else
+ {
+ scheduleDelete();
+ }
+}
+
+void BuySellDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "Buy")
+ {
+ if (mNpcId != -1)
+ Net::getNpcHandler()->buy(mNpcId);
+ else
+ Net::getBuySellHandler()->requestSellList(mNick);
+ }
+ else if (event.getId() == "Sell")
+ {
+ if (mNpcId != -1)
+ Net::getNpcHandler()->sell(mNpcId);
+ else
+ Net::getBuySellHandler()->requestBuyList(mNick);
+ }
+
+ close();
+}
+
+void BuySellDialog::closeAll()
+{
+ DialogList::iterator it = instances.begin();
+ DialogList::iterator it_end = instances.end();
+
+ for (; it != it_end; it++)
+ {
+ if (*it)
+ (*it)->close();
+ }
+}
diff --git a/src/gui/buysell.h b/src/gui/buysell.h
new file mode 100644
index 000000000..f533252ee
--- /dev/null
+++ b/src/gui/buysell.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BUYSELL_H
+#define BUYSELL_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+/**
+ * A dialog to choose between buying or selling at a shop.
+ *
+ * \ingroup Interface
+ */
+class BuySellDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor. The action listener passed will receive "sell", "buy"
+ * or "cancel" events when the respective buttons are pressed.
+ *
+ * @see Window::Window
+ */
+ BuySellDialog(int npcId);
+
+ BuySellDialog(std::string nick);
+
+ virtual ~BuySellDialog();
+
+ void init();
+
+ void setVisible(bool visible);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Returns true if any instances exist.
+ */
+ static bool isActive()
+ { return !instances.empty(); }
+
+ /**
+ * Closes all instances.
+ */
+ static void closeAll();
+
+ private:
+ typedef std::list<BuySellDialog*> DialogList;
+ static DialogList instances;
+
+ int mNpcId;
+ std::string mNick;
+ gcn::Button *mBuyButton;
+};
+
+#endif
diff --git a/src/gui/changeemaildialog.cpp b/src/gui/changeemaildialog.cpp
new file mode 100644
index 000000000..4485e0199
--- /dev/null
+++ b/src/gui/changeemaildialog.cpp
@@ -0,0 +1,167 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/changeemaildialog.h"
+
+#include "client.h"
+#include "log.h"
+
+#include "gui/register.h"
+#include "gui/okdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
+#include <sstream>
+
+ChangeEmailDialog::ChangeEmailDialog(LoginData *loginData):
+ Window(_("Change Email Address"), true),
+ mWrongDataNoticeListener(new WrongDataNoticeListener),
+ mLoginData(loginData)
+{
+ gcn::Label *accountLabel = new Label(strprintf(_("Account: %s"),
+ mLoginData->username.c_str()));
+ gcn::Label *newEmailLabel = new Label(_("Type new email address twice:"));
+ mFirstEmailField = new TextField;
+ mSecondEmailField = new TextField;
+ mChangeEmailButton = new Button(_("Change Email Address"),
+ "change_email", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ const int width = 200;
+ const int height = 130;
+ setContentSize(width, height);
+
+ accountLabel->setPosition(5, 5);
+ accountLabel->setWidth(130);
+
+ newEmailLabel->setPosition(
+ 5, accountLabel->getY() + accountLabel->getHeight() + 7);
+ newEmailLabel->setWidth(width - 5);
+
+ mFirstEmailField->setPosition(
+ 5, newEmailLabel->getY() + newEmailLabel->getHeight() + 7);
+ mFirstEmailField->setWidth(130);
+
+ mSecondEmailField->setPosition(
+ 5, mFirstEmailField->getY() + mFirstEmailField->getHeight() + 7);
+ mSecondEmailField->setWidth(130);
+
+ mCancelButton->setPosition(
+ width - 5 - mCancelButton->getWidth(),
+ height - 5 - mCancelButton->getHeight());
+ mChangeEmailButton->setPosition(
+ mCancelButton->getX() - 5 - mChangeEmailButton->getWidth(),
+ mCancelButton->getY());
+
+ add(accountLabel);
+ add(newEmailLabel);
+ add(mFirstEmailField);
+ add(mSecondEmailField);
+ add(mChangeEmailButton);
+ add(mCancelButton);
+
+ center();
+ setVisible(true);
+ mFirstEmailField->requestFocus();
+
+ mFirstEmailField->setActionEventId("change_email");
+ mSecondEmailField->setActionEventId("change_email");
+}
+
+ChangeEmailDialog::~ChangeEmailDialog()
+{
+ delete mWrongDataNoticeListener;
+ mWrongDataNoticeListener = 0;
+}
+
+void ChangeEmailDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ Client::setState(STATE_CHAR_SELECT);
+ }
+ else if (event.getId() == "change_email")
+ {
+
+ const std::string username = mLoginData->username.c_str();
+ const std::string newFirstEmail = mFirstEmailField->getText();
+ const std::string newSecondEmail = mSecondEmailField->getText();
+ logger->log("ChangeEmailDialog::Email change, Username is %s",
+ username.c_str());
+
+ std::stringstream errorMessage;
+ int error = 0;
+
+ unsigned int min = Net::getLoginHandler()->getMinPasswordLength();
+ unsigned int max = Net::getLoginHandler()->getMaxPasswordLength();
+
+ if (newFirstEmail.length() < min)
+ {
+ // First email address too short
+ errorMessage << strprintf(_("The new email address needs to be at "
+ "least %d characters long."), min);
+ error = 1;
+ }
+ else if (newFirstEmail.length() > max - 1 )
+ {
+ // First email address too long
+ errorMessage << strprintf(_("The new email address needs to be "
+ "less than %d characters long."), max);
+ error = 1;
+ }
+ else if (newFirstEmail != newSecondEmail)
+ {
+ // Second Pass mismatch
+ errorMessage << _("The email address entries mismatch.");
+ error = 2;
+ }
+
+ if (error > 0)
+ {
+ if (error == 1)
+ mWrongDataNoticeListener->setTarget(this->mFirstEmailField);
+ else if (error == 2)
+ mWrongDataNoticeListener->setTarget(this->mSecondEmailField);
+
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str());
+ if (dlg)
+ dlg->addActionListener(mWrongDataNoticeListener);
+ }
+ else
+ {
+ // No errors detected, change account password.
+ mChangeEmailButton->setEnabled(false);
+ // Set the new email address
+ mLoginData->email = newFirstEmail;
+ Client::setState(STATE_CHANGEEMAIL_ATTEMPT);
+ }
+ }
+}
diff --git a/src/gui/changeemaildialog.h b/src/gui/changeemaildialog.h
new file mode 100644
index 000000000..7e5f04fa4
--- /dev/null
+++ b/src/gui/changeemaildialog.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_CHANGEEMAIL_H
+#define GUI_CHANGEEMAIL_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class LoginData;
+class OkDialog;
+class WrongDataNoticeListener;
+
+/**
+ * The Change email dialog.
+ *
+ * \ingroup Interface
+ */
+class ChangeEmailDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ ChangeEmailDialog(LoginData *loginData);
+
+ /**
+ * Destructor.
+ */
+ ~ChangeEmailDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * This is used to pass the pointer to where the new email should be
+ * put when the dialog finishes.
+ */
+ static void setEmail(std::string *email);
+
+ private:
+ gcn::TextField *mFirstEmailField;
+ gcn::TextField *mSecondEmailField;
+
+ gcn::Button *mChangeEmailButton;
+ gcn::Button *mCancelButton;
+
+ WrongDataNoticeListener *mWrongDataNoticeListener;
+
+ LoginData *mLoginData;
+};
+
+#endif // GUI_CHANGEEMAIL_H
diff --git a/src/gui/changepassworddialog.cpp b/src/gui/changepassworddialog.cpp
new file mode 100644
index 000000000..bc29c9264
--- /dev/null
+++ b/src/gui/changepassworddialog.cpp
@@ -0,0 +1,157 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "changepassworddialog.h"
+
+#include "client.h"
+#include "log.h"
+
+#include "gui/register.h"
+#include "gui/okdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/passwordfield.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
+#include <sstream>
+
+ChangePasswordDialog::ChangePasswordDialog(LoginData *loginData):
+ Window(_("Change Password"), true),
+ mWrongDataNoticeListener(new WrongDataNoticeListener),
+ mLoginData(loginData)
+{
+ gcn::Label *accountLabel = new Label(
+ strprintf(_("Account: %s"), mLoginData->username.c_str()));
+ mOldPassField = new PasswordField;
+ mFirstPassField = new PasswordField;
+ mSecondPassField = new PasswordField;
+ mChangePassButton = new Button(_("Change Password"), "change_password",
+ this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ place(0, 0, accountLabel, 3);
+ place(0, 1, new Label(_("Password:")), 3);
+ place(0, 2, mOldPassField, 3).setPadding(1);
+ place(0, 3, new Label(_("Type new password twice:")), 3);
+ place(0, 4, mFirstPassField, 3).setPadding(1);
+ place(0, 5, mSecondPassField, 3).setPadding(1);
+ place(1, 6, mCancelButton);
+ place(2, 6, mChangePassButton);
+ reflowLayout(200);
+
+ center();
+ setVisible(true);
+ mOldPassField->requestFocus();
+
+ mOldPassField->setActionEventId("change_password");
+ mFirstPassField->setActionEventId("change_password");
+ mSecondPassField->setActionEventId("change_password");
+}
+
+ChangePasswordDialog::~ChangePasswordDialog()
+{
+ delete mWrongDataNoticeListener;
+ mWrongDataNoticeListener = 0;
+}
+
+void ChangePasswordDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ Client::setState(STATE_CHAR_SELECT);
+ }
+ else if (event.getId() == "change_password")
+ {
+
+ const std::string username = mLoginData->username.c_str();
+ const std::string oldPassword = mOldPassField->getText();
+ const std::string newFirstPass = mFirstPassField->getText();
+ const std::string newSecondPass = mSecondPassField->getText();
+ logger->log("ChangePasswordDialog::Password change, Username is %s",
+ username.c_str());
+
+ std::stringstream errorMessage;
+ int error = 0;
+
+ unsigned int min = Net::getLoginHandler()->getMinPasswordLength();
+ unsigned int max = Net::getLoginHandler()->getMaxPasswordLength();
+
+ // Check old Password
+ if (oldPassword.empty())
+ {
+ // No old password
+ errorMessage << _("Enter the old password first.");
+ error = 1;
+ }
+ else if (newFirstPass.length() < min)
+ {
+ // First password too short
+ errorMessage << strprintf(_("The new password needs to be at least"
+ " %d characters long."), min);
+ error = 2;
+ }
+ else if (newFirstPass.length() > max - 1 )
+ {
+ // First password too long
+ errorMessage << strprintf(_("The new password needs to be less "
+ "than %d characters long."), max);
+ error = 2;
+ }
+ else if (newFirstPass != newSecondPass)
+ {
+ // Second Pass mismatch
+ errorMessage << _("The new password entries mismatch.");
+ error = 3;
+ }
+
+ if (error > 0)
+ {
+ if (error == 1)
+ mWrongDataNoticeListener->setTarget(this->mOldPassField);
+ else if (error == 2)
+ mWrongDataNoticeListener->setTarget(this->mFirstPassField);
+ else if (error == 3)
+ mWrongDataNoticeListener->setTarget(this->mSecondPassField);
+
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str());
+ dlg->addActionListener(mWrongDataNoticeListener);
+ }
+ else
+ {
+ // No errors detected, change account password.
+ mChangePassButton->setEnabled(false);
+ // Set the new password
+ mLoginData->password = oldPassword;
+ mLoginData->newPassword = newFirstPass;
+ Client::setState(STATE_CHANGEPASSWORD_ATTEMPT);
+ }
+ }
+}
diff --git a/src/gui/changepassworddialog.h b/src/gui/changepassworddialog.h
new file mode 100644
index 000000000..361debe45
--- /dev/null
+++ b/src/gui/changepassworddialog.h
@@ -0,0 +1,73 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHANGEPASSWORDDIALOG_H
+#define CHANGEPASSWORDDIALOG_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class LoginData;
+class OkDialog;
+class WrongDataNoticeListener;
+
+/**
+ * The Change password dialog.
+ *
+ * \ingroup Interface
+ */
+class ChangePasswordDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ ChangePasswordDialog(LoginData *loginData);
+
+ /**
+ * Destructor
+ */
+ ~ChangePasswordDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::TextField *mOldPassField;
+ gcn::TextField *mFirstPassField;
+ gcn::TextField *mSecondPassField;
+
+ gcn::Button *mChangePassButton;
+ gcn::Button *mCancelButton;
+
+ WrongDataNoticeListener *mWrongDataNoticeListener;
+
+ LoginData *mLoginData;
+};
+
+#endif
diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp
new file mode 100644
index 000000000..4dc6251b9
--- /dev/null
+++ b/src/gui/charcreatedialog.cpp
@@ -0,0 +1,372 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/charcreatedialog.h"
+
+#include "game.h"
+#include "localplayer.h"
+#include "main.h"
+#include "units.h"
+
+#include "gui/charselectdialog.h"
+#include "gui/confirmdialog.h"
+#include "gui/okdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/playerbox.h"
+#include "gui/widgets/radiobutton.h"
+#include "gui/widgets/slider.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/charhandler.h"
+#include "net/messageout.h"
+#include "net/net.h"
+
+#include "resources/colordb.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+
+CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
+ Window(_("Create Character"), true, parent),
+ mCharSelectDialog(parent),
+ mSlot(slot)
+{
+ mPlayer = new Being(0, ActorSprite::PLAYER, 0, NULL);
+ mPlayer->setGender(GENDER_MALE);
+
+ int numberOfHairColors = ColorDB::size();
+
+ mHairStyle = rand() % mPlayer->getNumOfHairstyles();
+ mHairColor = rand() % numberOfHairColors;
+ updateHair();
+
+ mNameField = new TextField("");
+ mNameLabel = new Label(_("Name:"));
+ // TRANSLATORS: This is a narrow symbol used to denote 'next'.
+ // You may change this symbol if your language uses another.
+ mNextHairColorButton = new Button(_(">"), "nextcolor", this);
+ // TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+ // You may change this symbol if your language uses another.
+ mPrevHairColorButton = new Button(_("<"), "prevcolor", this);
+ mHairColorLabel = new Label(_("Hair color:"));
+ mNextHairStyleButton = new Button(_(">"), "nextstyle", this);
+ mPrevHairStyleButton = new Button(_("<"), "prevstyle", this);
+ mHairStyleLabel = new Label(_("Hair style:"));
+ mCreateButton = new Button(_("Create"), "create", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mMale = new RadioButton(_("Male"), "gender");
+ mFemale = new RadioButton(_("Female"), "gender");
+
+ // Default to a Male character
+ mMale->setSelected(true);
+
+ mMale->setActionEventId("gender");
+ mFemale->setActionEventId("gender");
+
+ mMale->addActionListener(this);
+ mFemale->addActionListener(this);
+
+ mPlayerBox = new PlayerBox(mPlayer);
+ mPlayerBox->setWidth(74);
+
+ mNameField->setActionEventId("create");
+ mNameField->addActionListener(this);
+
+ mAttributesLeft = new Label(
+ strprintf(_("Please distribute %d points"), 99));
+
+ int w = 200;
+ int h = 330;
+ setContentSize(w, h);
+ mPlayerBox->setDimension(gcn::Rectangle(80, 30, 110, 85));
+ mNameLabel->setPosition(5, 5);
+ mNameField->setDimension(
+ gcn::Rectangle(45, 5, w - 45 - 7, mNameField->getHeight()));
+ mPrevHairColorButton->setPosition(90, 35);
+ mNextHairColorButton->setPosition(165, 35);
+ mHairColorLabel->setPosition(5, 40);
+ mPrevHairStyleButton->setPosition(90, 64);
+ mNextHairStyleButton->setPosition(165, 64);
+ mHairStyleLabel->setPosition(5, 70);
+ mAttributesLeft->setPosition(15, 280);
+ updateSliders();
+ mCancelButton->setPosition(
+ w - 5 - mCancelButton->getWidth(),
+ h - 5 - mCancelButton->getHeight());
+ mCreateButton->setPosition(
+ mCancelButton->getX() - 5 - mCreateButton->getWidth(),
+ h - 5 - mCancelButton->getHeight());
+
+ mMale->setPosition(30, 120);
+ mFemale->setPosition(100, 120);
+
+ add(mPlayerBox);
+ add(mNameField);
+ add(mNameLabel);
+ add(mNextHairColorButton);
+ add(mPrevHairColorButton);
+ add(mHairColorLabel);
+ add(mNextHairStyleButton);
+ add(mPrevHairStyleButton);
+ add(mHairStyleLabel);
+ add(mAttributesLeft);
+ add(mCreateButton);
+ add(mCancelButton);
+
+ add(mMale);
+ add(mFemale);
+
+ center();
+ setVisible(true);
+ mNameField->requestFocus();
+}
+
+CharCreateDialog::~CharCreateDialog()
+{
+ delete mPlayer;
+ mPlayer = 0;
+
+ // Make sure the char server handler knows that we're gone
+ Net::getCharHandler()->setCharCreateDialog(0);
+}
+
+void CharCreateDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "create")
+ {
+ if (Net::getNetworkType() == ServerInfo::MANASERV
+ || getName().length() >= 4)
+ {
+ // Attempt to create the character
+ mCreateButton->setEnabled(false);
+
+ std::vector<int> atts;
+ for (unsigned i = 0; i < mAttributeSlider.size(); i++)
+ {
+ atts.push_back(static_cast<int>(
+ mAttributeSlider[i]->getValue()));
+ }
+
+ int characterSlot = mSlot;
+ // On Manaserv, the slots start at 1, so we offset them.
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ ++characterSlot;
+
+ Net::getCharHandler()->newCharacter(getName(), characterSlot,
+ mFemale->isSelected(),
+ mHairStyle,
+ mHairColor, atts);
+ }
+ else
+ {
+ new OkDialog(_("Error"),
+ _("Your name needs to be at least 4 characters."),
+ true, this);
+ }
+ }
+ else if (event.getId() == "cancel")
+ {
+ scheduleDelete();
+ }
+ else if (event.getId() == "nextcolor")
+ {
+ mHairColor++;
+ updateHair();
+ }
+ else if (event.getId() == "prevcolor")
+ {
+ mHairColor--;
+ updateHair();
+ }
+ else if (event.getId() == "nextstyle")
+ {
+ mHairStyle++;
+ updateHair();
+ }
+ else if (event.getId() == "prevstyle")
+ {
+ mHairStyle--;
+ updateHair();
+ }
+ else if (event.getId() == "statslider")
+ {
+ updateSliders();
+ }
+ else if (event.getId() == "gender")
+ {
+ if (mMale->isSelected())
+ mPlayer->setGender(GENDER_MALE);
+ else
+ mPlayer->setGender(GENDER_FEMALE);
+ }
+}
+
+std::string CharCreateDialog::getName() const
+{
+ std::string name = mNameField->getText();
+ trim(name);
+ return name;
+}
+
+void CharCreateDialog::updateSliders()
+{
+ for (unsigned i = 0; i < mAttributeSlider.size(); i++)
+ {
+ // Update captions
+ mAttributeValue[i]->setCaption(
+ toString(static_cast<int>(mAttributeSlider[i]->getValue())));
+ mAttributeValue[i]->adjustSize();
+ }
+
+ // Update distributed points
+ int pointsLeft = mMaxPoints - getDistributedPoints();
+ if (pointsLeft == 0)
+ {
+ mAttributesLeft->setCaption(_("Character stats OK"));
+ mCreateButton->setEnabled(true);
+ }
+ else
+ {
+ mCreateButton->setEnabled(false);
+ if (pointsLeft > 0)
+ {
+ mAttributesLeft->setCaption(
+ strprintf(_("Please distribute %d points"), pointsLeft));
+ }
+ else
+ {
+ mAttributesLeft->setCaption(
+ strprintf(_("Please remove %d points"), -pointsLeft));
+ }
+ }
+
+ mAttributesLeft->adjustSize();
+}
+
+void CharCreateDialog::unlock()
+{
+ mCreateButton->setEnabled(true);
+}
+
+int CharCreateDialog::getDistributedPoints() const
+{
+ int points = 0;
+
+ for (unsigned i = 0; i < mAttributeSlider.size(); i++)
+ points += static_cast<int>(mAttributeSlider[i]->getValue());
+ return points;
+}
+
+void CharCreateDialog::setAttributes(const std::vector<std::string> &labels,
+ int available, int min, int max)
+{
+ mMaxPoints = available;
+
+ for (unsigned i = 0; i < mAttributeLabel.size(); i++)
+ {
+ remove(mAttributeLabel[i]);
+ delete mAttributeLabel[i];
+ mAttributeLabel[i] = 0;
+ remove(mAttributeSlider[i]);
+ delete mAttributeSlider[i];
+ mAttributeSlider[i] = 0;
+ remove(mAttributeValue[i]);
+ delete mAttributeValue[i];
+ mAttributeValue[i] = 0;
+ }
+
+ mAttributeLabel.resize(labels.size());
+ mAttributeSlider.resize(labels.size());
+ mAttributeValue.resize(labels.size());
+
+ int w = 200;
+ int h = 330;
+
+ for (unsigned i = 0; i < labels.size(); i++)
+ {
+ mAttributeLabel[i] = new Label(labels[i]);
+ mAttributeLabel[i]->setWidth(70);
+ mAttributeLabel[i]->setPosition(5, 140 + i*20);
+ add(mAttributeLabel[i]);
+
+ mAttributeSlider[i] = new Slider(min, max);
+ mAttributeSlider[i]->setDimension(gcn::Rectangle(75, 140 + i * 20,
+ 100, 10));
+ mAttributeSlider[i]->setActionEventId("statslider");
+ mAttributeSlider[i]->addActionListener(this);
+ add(mAttributeSlider[i]);
+
+ mAttributeValue[i] = new Label(toString(min));
+ mAttributeValue[i]->setPosition(180, 140 + i*20);
+ add(mAttributeValue[i]);
+ }
+
+ mAttributesLeft->setPosition(15, 280);
+ updateSliders();
+
+ mCancelButton->setPosition(
+ w - 5 - mCancelButton->getWidth(),
+ h - 5 - mCancelButton->getHeight());
+ mCreateButton->setPosition(
+ mCancelButton->getX() - 5 - mCreateButton->getWidth(),
+ h - 5 - mCancelButton->getHeight());
+}
+
+void CharCreateDialog::setFixedGender(bool fixed, Gender gender)
+{
+ if (gender == GENDER_FEMALE)
+ {
+ mFemale->setSelected(true);
+ mMale->setSelected(false);
+ }
+ else
+ {
+ mMale->setSelected(true);
+ mFemale->setSelected(false);
+ }
+
+ mPlayer->setGender(gender);
+
+ if (fixed)
+ {
+ mMale->setEnabled(false);
+ mFemale->setEnabled(false);
+ }
+}
+
+void CharCreateDialog::updateHair()
+{
+ mHairStyle %= Being::getNumOfHairstyles();
+ if (mHairStyle < 0)
+ mHairStyle += Being::getNumOfHairstyles();
+
+ mHairColor %= ColorDB::size();
+ if (mHairColor < 0)
+ mHairColor += ColorDB::size();
+
+ mPlayer->setSprite(Net::getCharHandler()->hairSprite(),
+ mHairStyle * -1, ColorDB::get(mHairColor));
+}
diff --git a/src/gui/charcreatedialog.h b/src/gui/charcreatedialog.h
new file mode 100644
index 000000000..018de3f59
--- /dev/null
+++ b/src/gui/charcreatedialog.h
@@ -0,0 +1,122 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHAR_CREATE_DIALOG_H
+#define CHAR_CREATE_DIALOG_H
+
+#include "being.h"
+#include "guichanfwd.h"
+
+#include "gui/charselectdialog.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <string>
+#include <vector>
+
+class LocalPlayer;
+class PlayerBox;
+
+/**
+ * Character creation dialog.
+ *
+ * \ingroup Interface
+ */
+class CharCreateDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ CharCreateDialog(CharSelectDialog *parent, int slot);
+
+ /**
+ * Destructor.
+ */
+ ~CharCreateDialog();
+
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Unlocks the dialog, enabling the create character button again.
+ */
+ void unlock();
+
+ void setAttributes(const std::vector<std::string> &labels,
+ int available,
+ int min, int max);
+
+ void setFixedGender(bool fixed, Gender gender = GENDER_FEMALE);
+
+ private:
+ int getDistributedPoints() const;
+
+ void updateSliders();
+
+ /**
+ * Returns the name of the character to create.
+ */
+ std::string getName() const;
+
+ /**
+ * Communicate character creation to the server.
+ */
+ void attemptCharCreate();
+
+ void updateHair();
+
+ CharSelectDialog *mCharSelectDialog;
+
+ gcn::TextField *mNameField;
+ gcn::Label *mNameLabel;
+ gcn::Button *mNextHairColorButton;
+ gcn::Button *mPrevHairColorButton;
+ gcn::Label *mHairColorLabel;
+ gcn::Button *mNextHairStyleButton;
+ gcn::Button *mPrevHairStyleButton;
+ gcn::Label *mHairStyleLabel;
+
+ gcn::RadioButton *mMale;
+ gcn::RadioButton *mFemale;
+
+ std::vector<gcn::Slider*> mAttributeSlider;
+ std::vector<gcn::Label*> mAttributeLabel;
+ std::vector<gcn::Label*> mAttributeValue;
+ gcn::Label *mAttributesLeft;
+
+ int mMaxPoints;
+ int mUsedPoints;
+
+ gcn::Button *mCreateButton;
+ gcn::Button *mCancelButton;
+
+ Being *mPlayer;
+ PlayerBox *mPlayerBox;
+
+ int mHairStyle;
+ int mHairColor;
+
+ int mSlot;
+};
+
+#endif // CHAR_CREATE_DIALOG_H
diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp
new file mode 100644
index 000000000..d95930108
--- /dev/null
+++ b/src/gui/charselectdialog.cpp
@@ -0,0 +1,456 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/charselectdialog.h"
+
+#include "client.h"
+#include "game.h"
+#include "localplayer.h"
+#include "units.h"
+#include "log.h"
+
+#include "gui/changeemaildialog.h"
+#include "gui/changepassworddialog.h"
+#include "gui/charcreatedialog.h"
+#include "gui/confirmdialog.h"
+#include "gui/okdialog.h"
+#include "gui/sdlinput.h"
+#include "gui/unregisterdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/container.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/playerbox.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/charhandler.h"
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/messageout.h"
+#include "net/net.h"
+
+#include "resources/colordb.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+
+#include <string>
+#include <cassert>
+
+// Character slots per row in the dialog
+static const int SLOTS_PER_ROW = 5;
+
+/**
+ * Listener for confirming character deletion.
+ */
+class CharDeleteConfirm : public ConfirmDialog
+{
+ public:
+ CharDeleteConfirm(CharSelectDialog *m, int index):
+ ConfirmDialog(_("Confirm Character Delete"),
+ _("Are you sure you want to delete this character?"),
+ false, false, m),
+ mMaster(m),
+ mIndex(index)
+ {
+ }
+
+ void action(const gcn::ActionEvent &event)
+ {
+ if (event.getId() == "yes" && mMaster)
+ mMaster->attemptCharacterDelete(mIndex);
+
+ ConfirmDialog::action(event);
+ }
+
+ private:
+ CharSelectDialog *mMaster;
+ int mIndex;
+};
+
+class CharacterDisplay : public Container
+{
+ public:
+ CharacterDisplay(CharSelectDialog *charSelectDialog);
+
+ void setCharacter(Net::Character *character);
+
+ Net::Character *getCharacter() const
+ { return mCharacter; }
+
+ void requestFocus();
+
+ void setActive(bool active);
+
+ private:
+ void update();
+
+ Net::Character *mCharacter;
+
+ PlayerBox *mPlayerBox;
+ Label *mName;
+ Label *mLevel;
+ Label *mMoney;
+ Button *mButton;
+ Button *mDelete;
+};
+
+CharSelectDialog::CharSelectDialog(LoginData *loginData):
+ Window(_("Account and Character Management")),
+ mLocked(false),
+ mUnregisterButton(0),
+ mChangeEmailButton(0),
+ mCharacterEntries(0),
+ mLoginData(loginData),
+ mCharHandler(Net::getCharHandler())
+{
+ setCloseButton(false);
+
+ mAccountNameLabel = new Label(loginData->username);
+ mSwitchLoginButton = new Button(_("Switch Login"), "switch", this);
+ mChangePasswordButton = new Button(_("Change Password"), "change_password",
+ this);
+
+ int optionalActions = Net::getLoginHandler()->supportedOptionalActions();
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mAccountNameLabel, 2);
+ place(0, 1, mSwitchLoginButton);
+
+ if (optionalActions & Net::LoginHandler::Unregister)
+ {
+ mUnregisterButton = new Button(_("Unregister"),
+ "unregister", this);
+ place(3, 1, mUnregisterButton);
+ }
+
+ place(0, 2, mChangePasswordButton);
+
+ if (optionalActions & Net::LoginHandler::ChangeEmail)
+ {
+ mChangeEmailButton = new Button(_("Change Email"),
+ "change_email", this);
+ place(3, 2, mChangeEmailButton);
+ }
+
+ place = getPlacer(0, 1);
+
+ for (int i = 0; i < (int)mLoginData->characterSlots; i++)
+ {
+ mCharacterEntries.push_back(new CharacterDisplay(this));
+ place(i % SLOTS_PER_ROW, (int)i / SLOTS_PER_ROW, mCharacterEntries[i]);
+ }
+
+ reflowLayout();
+
+ addKeyListener(this);
+
+ center();
+ setVisible(true);
+
+ Net::getCharHandler()->setCharSelectDialog(this);
+ if (mCharacterEntries[0])
+ mCharacterEntries[0]->requestFocus();
+}
+
+CharSelectDialog::~CharSelectDialog()
+{
+}
+
+void CharSelectDialog::action(const gcn::ActionEvent &event)
+{
+ // Check if a button of a character was pressed
+ const gcn::Widget *sourceParent = event.getSource()->getParent();
+ int selected = -1;
+ for (int i = 0; i < (int)mCharacterEntries.size(); ++i)
+ {
+ if (mCharacterEntries[i] == sourceParent)
+ {
+ selected = i;
+ break;
+ }
+ }
+
+ const std::string &eventId = event.getId();
+
+ if (selected != -1)
+ {
+ if (eventId == "use")
+ {
+ attemptCharacterSelect(selected);
+ }
+ else if (eventId == "new" &&
+ !mCharacterEntries[selected]->getCharacter())
+ {
+ // Start new character dialog
+ CharCreateDialog *charCreateDialog =
+ new CharCreateDialog(this, selected);
+ mCharHandler->setCharCreateDialog(charCreateDialog);
+ }
+ else if (eventId == "delete"
+ && mCharacterEntries[selected]->getCharacter())
+ {
+ new CharDeleteConfirm(this, selected);
+ }
+ }
+ else if (eventId == "switch")
+ {
+ Client::setState(STATE_SWITCH_LOGIN);
+ }
+ else if (eventId == "change_password")
+ {
+ Client::setState(STATE_CHANGEPASSWORD);
+ }
+ else if (eventId == "change_email")
+ {
+ Client::setState(STATE_CHANGEEMAIL);
+ }
+ else if (eventId == "unregister")
+ {
+ Client::setState(STATE_UNREGISTER);
+ }
+}
+
+void CharSelectDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ESCAPE)
+ {
+ action(gcn::ActionEvent(mSwitchLoginButton,
+ mSwitchLoginButton->getActionEventId()));
+ }
+}
+
+/**
+ * Communicate character deletion to the server.
+ */
+void CharSelectDialog::attemptCharacterDelete(int index)
+{
+ if (mLocked)
+ return;
+
+ mCharHandler->deleteCharacter(mCharacterEntries[index]->getCharacter());
+ lock();
+}
+
+/**
+ * Communicate character selection to the server.
+ */
+void CharSelectDialog::attemptCharacterSelect(int index)
+{
+ if (mLocked || !mCharacterEntries[index])
+ return;
+
+ setVisible(false);
+ if (mCharHandler && mCharacterEntries[index])
+ {
+ mCharHandler->chooseCharacter(
+ mCharacterEntries[index]->getCharacter());
+ }
+ lock();
+}
+
+void CharSelectDialog::setCharacters(const Net::Characters &characters)
+{
+ // Reset previous characters
+ std::vector<CharacterDisplay*>::iterator iter, iter_end;
+ for (iter = mCharacterEntries.begin(), iter_end = mCharacterEntries.end();
+ iter != iter_end; ++iter)
+ (*iter)->setCharacter(0);
+
+ Net::Characters::const_iterator i, i_end = characters.end();
+ for (i = characters.begin(); i != i_end; ++i)
+ {
+ if (!*i)
+ continue;
+
+ Net::Character *character = *i;
+
+ // Slots Number start at 1 for Manaserv, so we offset them by one.
+ int characterSlot = character->slot;
+ if (Net::getNetworkType() == ServerInfo::MANASERV && characterSlot > 0)
+ --characterSlot;
+
+ if (characterSlot >= (int)mCharacterEntries.size())
+ {
+ logger->log("Warning: slot out of range: %d", character->slot);
+ continue;
+ }
+
+ mCharacterEntries[characterSlot]->setCharacter(character);
+ }
+}
+
+void CharSelectDialog::lock()
+{
+ assert(!mLocked);
+ setLocked(true);
+}
+
+void CharSelectDialog::unlock()
+{
+ setLocked(false);
+}
+
+void CharSelectDialog::setLocked(bool locked)
+{
+ mLocked = locked;
+
+ if (mSwitchLoginButton)
+ mSwitchLoginButton->setEnabled(!locked);
+ if (mChangePasswordButton)
+ mChangePasswordButton->setEnabled(!locked);
+ if (mUnregisterButton)
+ mUnregisterButton->setEnabled(!locked);
+ if (mChangeEmailButton)
+ mChangeEmailButton->setEnabled(!locked);
+
+ for (int i = 0; i < (int)mCharacterEntries.size(); ++i)
+ {
+ if (mCharacterEntries[i])
+ mCharacterEntries[i]->setActive(!mLocked);
+ }
+}
+
+bool CharSelectDialog::selectByName(const std::string &name,
+ SelectAction action)
+{
+ if (mLocked)
+ return false;
+
+ for (int i = 0; i < (int)mCharacterEntries.size(); ++i)
+ {
+ Net::Character *character = mCharacterEntries[i]->getCharacter();
+ if (mCharacterEntries[i] && character)
+ {
+ if (character->dummy->getName() == name)
+ {
+ if (mCharacterEntries[i])
+ mCharacterEntries[i]->requestFocus();
+ if (action == Choose)
+ attemptCharacterSelect(i);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+CharacterDisplay::CharacterDisplay(CharSelectDialog *charSelectDialog):
+ mCharacter(0),
+ mPlayerBox(new PlayerBox)
+{
+ mButton = new Button("wwwwwwwww", "go", charSelectDialog);
+ mName = new Label("wwwwwwwwwwwwwwwwwwwwwwww");
+ mLevel = new Label("(888)");
+ mMoney = new Label("wwwwwwwww");
+
+ mDelete = new Button(_("Delete"), "delete", charSelectDialog);
+
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mPlayerBox, 3, 5);
+ place(0, 5, mName, 3);
+ place(0, 6, mLevel, 3);
+ place(0, 7, mMoney, 3);
+ place(0, 8, mButton, 3);
+ place(0, 9, mDelete, 3);
+
+ update();
+
+
+ // Setting the width so that the largest label fits.
+ mName->adjustSize();
+ mMoney->adjustSize();
+/*
+ int width = 74;
+ if (width - 20 < mName->getWidth())
+ width = 20 + mName->getWidth();
+ if (width - 20 < mMoney->getWidth())
+ width = 20 + mMoney->getWidth();
+ h.reflowLayout(width, 112 + mName->getHeight() + mLevel->getHeight() +
+ mMoney->getHeight() + mButton->getHeight() + mDelete->getHeight());
+*/
+
+ setWidth(100);
+ setHeight(200);
+}
+
+void CharacterDisplay::setCharacter(Net::Character *character)
+{
+ if (mCharacter == character)
+ return;
+
+ mCharacter = character;
+ mPlayerBox->setPlayer(character ? character->dummy : 0);
+ update();
+}
+
+void CharacterDisplay::requestFocus()
+{
+ mButton->requestFocus();
+}
+
+void CharacterDisplay::setActive(bool active)
+{
+ mButton->setEnabled(active);
+ mDelete->setEnabled(active);
+}
+
+void CharacterDisplay::update()
+{
+ if (mCharacter)
+ {
+ const LocalPlayer *character = mCharacter->dummy;
+ mButton->setCaption(_("Choose"));
+ mButton->setActionEventId("use");
+ mName->setCaption(strprintf("%s", character->getName().c_str()));
+ mLevel->setCaption(strprintf("Level %d",
+ mCharacter->data.mAttributes[LEVEL]));
+ mMoney->setCaption(Units::formatCurrency(
+ mCharacter->data.mAttributes[MONEY]));
+
+ mDelete->setVisible(true);
+ }
+ else
+ {
+ mButton->setCaption(_("Create"));
+ mButton->setActionEventId("new");
+ mName->setCaption(_("(empty)"));
+ mLevel->setCaption(_("(empty)"));
+ mMoney->setCaption(Units::formatCurrency(0));
+
+ mDelete->setVisible(false);
+ }
+
+ // Recompute layout
+ distributeResizedEvent();
+}
diff --git a/src/gui/charselectdialog.h b/src/gui/charselectdialog.h
new file mode 100644
index 000000000..7596e755b
--- /dev/null
+++ b/src/gui/charselectdialog.h
@@ -0,0 +1,113 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHAR_SELECT_H
+#define CHAR_SELECT_H
+
+#include "being.h"
+#include "guichanfwd.h"
+#include "main.h"
+
+#include "gui/widgets/window.h"
+
+#include "net/charhandler.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+
+class CharacterDisplay;
+class LocalPlayer;
+class LoginData;
+class PlayerBox;
+
+namespace Net
+{
+ class CharHandler;
+}
+
+/**
+ * Character selection dialog.
+ *
+ * \ingroup Interface
+ */
+class CharSelectDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ friend class CharDeleteConfirm;
+ friend class Net::CharHandler;
+
+ /**
+ * Constructor.
+ */
+ CharSelectDialog(LoginData *loginData);
+
+ ~CharSelectDialog();
+
+ void action(const gcn::ActionEvent &event);
+
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ enum SelectAction
+ {
+ Focus = 0,
+ Choose
+ };
+
+ /**
+ * Attempt to select the character with the given name. Returns whether
+ * a character with the given name was found.
+ *
+ * \param action determines what to do when a character with the given
+ * name was found (just focus or also try to choose this
+ * character).
+ */
+ bool selectByName(const std::string &name,
+ SelectAction action = Focus);
+
+ private:
+ void attemptCharacterDelete(int index);
+ void attemptCharacterSelect(int index);
+
+ void setCharacters(const Net::Characters &characters);
+
+ void lock();
+ void unlock();
+ void setLocked(bool locked);
+
+ bool mLocked;
+
+ gcn::Label *mAccountNameLabel;
+
+ gcn::Button *mSwitchLoginButton;
+ gcn::Button *mChangePasswordButton;
+ gcn::Button *mUnregisterButton;
+ gcn::Button *mChangeEmailButton;
+
+ /** The player boxes */
+ std::vector<CharacterDisplay*> mCharacterEntries;
+
+ LoginData *mLoginData;
+
+ Net::CharHandler *mCharHandler;
+};
+
+#endif
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
new file mode 100644
index 000000000..3ffa018c3
--- /dev/null
+++ b/src/gui/chat.cpp
@@ -0,0 +1,1350 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "chat.h"
+
+#include "actorspritemanager.h"
+#include "client.h"
+#include "configuration.h"
+#include "guild.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "party.h"
+#include "playerinfo.h"
+#include "playerrelations.h"
+#include "spellshortcut.h"
+#include "sound.h"
+
+#include "gui/setup.h"
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/battletab.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/dropdown.h"
+#include "gui/widgets/itemlinkhandler.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/tabbedarea.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/tradetab.h"
+#include "gui/widgets/whispertab.h"
+
+#include "net/chathandler.h"
+#include "net/net.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/focushandler.hpp>
+#include <guichan/focuslistener.hpp>
+
+#include <sstream>
+
+#include <sys/stat.h>
+
+/**
+ * The chat input hides when it loses focus. It is also invisible by default.
+ */
+class ChatInput : public TextField, public gcn::FocusListener
+{
+ public:
+ ChatInput():
+ TextField("", false)
+ {
+ setVisible(false);
+ addFocusListener(this);
+ }
+
+ /**
+ * Called if the chat input loses focus. It will set itself to
+ * invisible as result.
+ */
+ void focusLost(const gcn::Event &event _UNUSED_)
+ {
+ setVisible(false);
+ }
+};
+
+const char *COLOR_NAME[14] =
+{
+ N_("default"),
+ N_("black"),
+ N_("red"),
+ N_("green"),
+ N_("blue"),
+ N_("gold"),
+ N_("yellow"),
+ N_("pink"),
+ N_("purple"),
+ N_("grey"),
+ N_("brown"),
+ N_("rainbow 1"),
+ N_("rainbow 2"),
+ N_("rainbow 3"),
+};
+
+
+class ColorListModel : public gcn::ListModel
+{
+public:
+ virtual ~ColorListModel() { }
+
+ virtual int getNumberOfElements()
+ {
+ return 14;
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return COLOR_NAME[i];
+ }
+};
+
+#define ACTION_COLOR_PICKER "color picker"
+
+
+ChatWindow::ChatWindow():
+ Window(_("Chat")),
+ mTmpVisible(false),
+ mChatHistoryIndex(0)
+{
+ listen(CHANNEL_NOTICES);
+ listen(CHANNEL_ATTRIBUTES);
+
+ setWindowName("Chat");
+
+ if (setupWindow)
+ setupWindow->registerWindowForReset(this);
+
+ // no title presented, title bar is padding so window can be moved.
+ gcn::Window::setTitleBarHeight(gcn::Window::getPadding() + 4);
+ setShowTitle(false);
+ setResizable(true);
+ setDefaultVisible(true);
+ setSaveVisible(true);
+ setDefaultSize(600, 123, ImageRect::LOWER_LEFT);
+ setMinWidth(150);
+ setMinHeight(90);
+
+ mItemLinkHandler = new ItemLinkHandler;
+
+ mChatInput = new ChatInput;
+ mChatInput->setActionEventId("chatinput");
+ mChatInput->addActionListener(this);
+
+ mChatTabs = new TabbedArea;
+
+ mChatColor = config.getIntValue("chatColor");
+ mColorListModel = new ColorListModel;
+ mColorPicker = new DropDown(mColorListModel);
+
+ mColorPicker->setActionEventId(ACTION_COLOR_PICKER);
+ mColorPicker->addActionListener(this);
+ mColorPicker->setSelected(mChatColor);
+
+ add(mChatTabs);
+ add(mChatInput);
+ add(mColorPicker);
+
+ loadWindowState();
+
+ mColorPicker->setPosition(this->getWidth() - mColorPicker->getWidth()
+ - 2*getPadding() - 8, getPadding());
+
+ // Add key listener to chat input to be able to respond to up/down
+ mChatInput->addKeyListener(this);
+ mCurHist = mHistory.end();
+
+ mReturnToggles = config.getBoolValue("ReturnToggles");
+
+ mRainbowColor = 0;
+
+ mColorPicker->setVisible(config.getBoolValue("showChatColorsList"));
+
+ fillCommands();
+ initTradeFilter();
+}
+
+ChatWindow::~ChatWindow()
+{
+ config.setValue("ReturnToggles", mReturnToggles);
+ removeAllWhispers();
+ delete mItemLinkHandler;
+ mItemLinkHandler = 0;
+ delete mColorPicker;
+ mColorPicker = 0;
+ delete mColorListModel;
+ mColorListModel = 0;
+}
+
+void ChatWindow::fillCommands()
+{
+ mCommands.push_back("/all");
+ mCommands.push_back("/away ");
+ mCommands.push_back("/closeall");
+ mCommands.push_back("/clear");
+ mCommands.push_back("/create ");
+ mCommands.push_back("/close");
+ mCommands.push_back("/cacheinfo");
+ mCommands.push_back("/erase ");
+ mCommands.push_back("/follow ");
+ mCommands.push_back("/heal ");
+ mCommands.push_back("/ignoreall");
+ mCommands.push_back("/help");
+ mCommands.push_back("/announce ");
+ mCommands.push_back("/where");
+ mCommands.push_back("/who");
+ mCommands.push_back("/msg ");
+ mCommands.push_back("/mail ");
+ mCommands.push_back("/whisper ");
+ mCommands.push_back("/w ");
+ mCommands.push_back("/query ");
+ mCommands.push_back("/ignore ");
+ mCommands.push_back("/unignore ");
+ mCommands.push_back("/join ");
+ mCommands.push_back("/list");
+ mCommands.push_back("/party");
+ mCommands.push_back("/createparty ");
+ mCommands.push_back("/createguild ");
+ mCommands.push_back("/me ");
+ mCommands.push_back("/toggle");
+ mCommands.push_back("/present");
+ mCommands.push_back("/quit");
+ mCommands.push_back("/move ");
+ mCommands.push_back("/target ");
+ mCommands.push_back("/invite ");
+ mCommands.push_back("/leave");
+ mCommands.push_back("/kick ");
+ mCommands.push_back("/item");
+ mCommands.push_back("/imitation");
+ mCommands.push_back("/exp");
+ mCommands.push_back("/ping");
+ mCommands.push_back("/outfit ");
+ mCommands.push_back("/emote ");
+ mCommands.push_back("/navigate ");
+ mCommands.push_back("/priceload");
+ mCommands.push_back("/pricesave");
+ mCommands.push_back("/trade ");
+ mCommands.push_back("/friend ");
+ mCommands.push_back("/befriend ");
+ mCommands.push_back("/disregard ");
+ mCommands.push_back("/neutral ");
+ mCommands.push_back("/raw ");
+ mCommands.push_back("/disconnect");
+ mCommands.push_back("/undress ");
+ mCommands.push_back("/attack");
+ mCommands.push_back("/dirs");
+ mCommands.push_back("/info");
+ mCommands.push_back("/wait");
+}
+
+void ChatWindow::resetToDefaultSize()
+{
+ Window::resetToDefaultSize();
+}
+
+void ChatWindow::adjustTabSize()
+{
+ const gcn::Rectangle area = getChildrenArea();
+
+ mChatInput->setPosition(mChatInput->getFrameSize(),
+ area.height - mChatInput->getHeight() -
+ mChatInput->getFrameSize());
+ mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize());
+
+ mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize());
+ mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize() -
+ (mChatInput->getHeight() + mChatInput->getFrameSize() * 2));
+
+ ChatTab *tab = getFocused();
+ if (tab)
+ {
+ gcn::Widget *content = tab->mScrollArea;
+ if (content)
+ {
+ content->setSize(mChatTabs->getWidth()
+ - 2 * content->getFrameSize(),
+ mChatTabs->getContainerHeight()
+ - 2 * content->getFrameSize());
+ content->logic();
+ }
+ }
+
+ mColorPicker->setPosition(this->getWidth() - mColorPicker->getWidth()
+ - 2*getPadding() - 8, getPadding());
+
+}
+
+void ChatWindow::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+
+ adjustTabSize();
+}
+
+/*
+void ChatWindow::logic()
+{
+ Window::logic();
+
+ Tab *tab = getFocused();
+ if (tab != mCurrentTab)
+ mCurrentTab = tab;
+}
+*/
+
+ChatTab *ChatWindow::getFocused() const
+{
+ return static_cast<ChatTab*>(mChatTabs->getSelectedTab());
+}
+
+void ChatWindow::clearTab(ChatTab *tab)
+{
+ if (tab)
+ tab->clearText();
+}
+
+void ChatWindow::clearTab()
+{
+ clearTab(getFocused());
+}
+
+void ChatWindow::prevTab()
+{
+ if (!mChatTabs)
+ return;
+
+ int tab = mChatTabs->getSelectedTabIndex();
+
+ if (tab == 0)
+ tab = mChatTabs->getNumberOfTabs();
+ tab--;
+
+ mChatTabs->setSelectedTab(tab);
+}
+
+void ChatWindow::nextTab()
+{
+ if (!mChatTabs)
+ return;
+
+ int tab = mChatTabs->getSelectedTabIndex();
+
+ tab++;
+ if (tab == mChatTabs->getNumberOfTabs())
+ tab = 0;
+
+ mChatTabs->setSelectedTab(tab);
+}
+
+void ChatWindow::defaultTab()
+{
+ if (mChatTabs)
+ mChatTabs->setSelectedTab((unsigned)0);
+}
+
+void ChatWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "chatinput")
+ {
+ std::string message = mChatInput->getText();
+
+ if (!message.empty())
+ {
+ // If message different from previous, put it in the history
+ if (mHistory.empty() || message != mHistory.back())
+ mHistory.push_back(message);
+
+ // Reset history iterator
+ mCurHist = mHistory.end();
+
+ // Send the message to the server
+ chatInput(addColors(message));
+
+ // Clear the text from the chat input
+ mChatInput->setText("");
+ }
+
+ if (message.empty() || !mReturnToggles)
+ {
+ // Remove focus and hide input
+ if (mFocusHandler)
+ mFocusHandler->focusNone();
+
+ // If the chatWindow is shown up because you want to send a message
+ // It should hide now
+ if (mTmpVisible)
+ setVisible(false);
+ }
+ }
+ else if (event.getId() == ACTION_COLOR_PICKER)
+ {
+ mChatColor = mColorPicker->getSelected();
+ config.setValue("chatColor", mChatColor);
+ }
+
+ if (mColorPicker && mColorPicker->isVisible()
+ != config.getBoolValue("showChatColorsList"))
+ {
+ mColorPicker->setVisible(config.getBoolValue(
+ "showChatColorsList"));
+ }
+}
+
+bool ChatWindow::requestChatFocus()
+{
+ // Make sure chatWindow is visible
+ if (!isVisible())
+ {
+ setVisible(true);
+
+ /*
+ * This is used to hide chatWindow after sending the message. There is
+ * a trick here, because setVisible will set mTmpVisible to false, you
+ * have to put this sentence *after* setVisible, not before it
+ */
+ mTmpVisible = true;
+ }
+
+ // Don't do anything else if the input is already visible and has focus
+ if (mChatInput->isVisible() && mChatInput->isFocused())
+ return false;
+
+ // Give focus to the chat input
+ mChatInput->setVisible(true);
+ mChatInput->requestFocus();
+ return true;
+}
+
+bool ChatWindow::isInputFocused() const
+{
+ return mChatInput->isFocused();
+}
+
+void ChatWindow::removeTab(ChatTab *tab)
+{
+ mChatTabs->removeTab(tab);
+}
+
+void ChatWindow::addTab(ChatTab *tab)
+{
+ mChatTabs->addTab(tab, tab->mScrollArea);
+
+ // Update UI
+ logic();
+}
+
+void ChatWindow::removeWhisper(const std::string &nick)
+{
+ std::string tempNick = nick;
+ toLower(tempNick);
+ mWhispers.erase(tempNick);
+}
+
+void ChatWindow::removeAllWhispers()
+{
+ TabMap::iterator iter;
+ std::list<ChatTab*> tabs;
+
+ for (iter = mWhispers.begin(); iter != mWhispers.end(); ++iter)
+ tabs.push_back(iter->second);
+
+ for (std::list<ChatTab*>::iterator it = tabs.begin();
+ it != tabs.end(); ++it)
+ {
+ delete *it;
+ }
+
+ mWhispers.clear();
+}
+
+void ChatWindow::ignoreAllWhispers()
+{
+ TabMap::iterator iter;
+ for (iter = mWhispers.begin(); iter != mWhispers.end(); ++iter)
+ {
+ WhisperTab *tab = dynamic_cast<WhisperTab*>(iter->second);
+ if (tab && player_relations.getRelation(tab->getNick())
+ != PlayerRelation::IGNORED)
+ {
+ player_relations.setRelation(tab->getNick(),
+ PlayerRelation::IGNORED);
+ }
+
+ delete(iter->second);
+ iter->second = 0;
+ }
+}
+
+void ChatWindow::chatInput(const std::string &message)
+{
+ ChatTab *tab = NULL;
+ std::string msg = message;
+ trim(msg);
+
+ if (config.getBoolValue("allowCommandsInChatTabs")
+ && msg.length() > 1
+ && ((msg.at(0) == '#' && msg.at(1) != '#') || msg.at(0) == '@')
+ && localChatTab)
+ {
+ tab = localChatTab;
+ }
+ else
+ {
+ tab = getFocused();
+ }
+ if (tab)
+ tab->chatInput(msg);
+ Game::instance()->setValidSpeed();
+}
+
+void ChatWindow::localChatInput(const std::string &msg)
+{
+ if (localChatTab)
+ localChatTab->chatInput(msg);
+ else
+ chatInput(msg);
+}
+
+void ChatWindow::doPresent()
+{
+ if (!actorSpriteManager)
+ return;
+
+ const ActorSprites &actors = actorSpriteManager->getAll();
+ std::string response = "";
+ int playercount = 0;
+
+ for (ActorSpritesConstIterator it = actors.begin(), it_end = actors.end();
+ it != it_end; it++)
+ {
+ if ((*it)->getType() == ActorSprite::PLAYER)
+ {
+ if (!response.empty())
+ response += ", ";
+ response += static_cast<Being*>(*it)->getName();
+ ++playercount;
+ }
+ }
+
+ std::string log = strprintf(_("Present: %s; %d players are present."),
+ response.c_str(), playercount);
+
+ if (getFocused())
+ getFocused()->chatLog(log, BY_SERVER);
+}
+
+void ChatWindow::scroll(int amount)
+{
+ if (!isVisible())
+ return;
+
+ ChatTab *tab = getFocused();
+ if (tab)
+ tab->scroll(amount);
+}
+
+void ChatWindow::mousePressed(gcn::MouseEvent &event)
+{
+ if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ if (viewport)
+ {
+ gcn::Tab *tab = mChatTabs->getSelectedTab();
+ if (tab)
+ {
+ ChatTab *cTab = dynamic_cast<ChatTab*>(tab);
+ if (cTab)
+ viewport->showChatPopup(cTab);
+ }
+ }
+ }
+
+ Window::mousePressed(event);
+
+ if (event.isConsumed())
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ ChatTab *tab = getFocused();
+ if (tab)
+ mMoved = !isResizeAllowed(event);
+ }
+
+ mDragOffsetX = event.getX();
+ mDragOffsetY = event.getY();
+}
+
+void ChatWindow::mouseDragged(gcn::MouseEvent &event)
+{
+ Window::mouseDragged(event);
+
+ if (event.isConsumed())
+ return;
+
+ if (isMovable() && mMoved)
+ {
+ int newX = std::max(0, getX() + event.getX() - mDragOffsetX);
+ int newY = std::max(0, getY() + event.getY() - mDragOffsetY);
+ newX = std::min(graphics->getWidth() - getWidth(), newX);
+ newY = std::min(graphics->getHeight() - getHeight(), newY);
+ setPosition(newX, newY);
+ }
+}
+
+/*
+void ChatWindow::mouseReleased(gcn::MouseEvent &event _UNUSED_)
+{
+
+}
+*/
+
+void ChatWindow::keyPressed(gcn::KeyEvent &event)
+{
+ if (event.getKey().getValue() == Key::DOWN)
+ {
+ if (mCurHist != mHistory.end())
+ {
+ // Move forward through the history
+ HistoryIterator prevHist = mCurHist++;
+
+ if (mCurHist != mHistory.end())
+ {
+ mChatInput->setText(*mCurHist);
+ mChatInput->setCaretPosition(static_cast<unsigned>(
+ mChatInput->getText().length()));
+ }
+ else
+ {
+ mChatInput->setText("");
+ mCurHist = prevHist;
+ }
+ }
+ else if (mChatInput->getText() != "")
+ {
+ mChatInput->setText("");
+ }
+ }
+ else if (event.getKey().getValue() == Key::UP &&
+ mCurHist != mHistory.begin() && !mHistory.empty())
+ {
+ // Move backward through the history
+ mCurHist--;
+ mChatInput->setText(*mCurHist);
+ mChatInput->setCaretPosition(static_cast<unsigned>(
+ mChatInput->getText().length()));
+ }
+ else if (event.getKey().getValue() == Key::INSERT &&
+ mChatInput->getText() != "")
+ {
+ // Add the current message to the history and clear the text
+ if (mHistory.empty() || mChatInput->getText() != mHistory.back())
+ mHistory.push_back(mChatInput->getText());
+ mCurHist = mHistory.end();
+ mChatInput->setText("");
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_AUTOCOMPLETE_CHAT) &&
+ mChatInput->getText() != "")
+ {
+ autoComplete();
+ return;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_DEACTIVATE_CHAT) &&
+ mChatInput->isVisible())
+ {
+ mChatInput->setVisible(false);
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_CHAT_PREV_HISTORY) &&
+ mChatInput->isVisible())
+ {
+ ChatTab *tab = getFocused();
+ if (tab && tab->getRows().size() > 0)
+ {
+ if (!mChatHistoryIndex)
+ {
+ mChatHistoryIndex = static_cast<unsigned>(
+ tab->getRows().size());
+
+ mChatInput->setText("");
+ mChatInput->setCaretPosition(0);
+ return;
+ }
+ else
+ {
+ mChatHistoryIndex --;
+ }
+
+ std::list<std::string>::iterator it;
+ unsigned int f = 0;
+ for (it = tab->getRows().begin();
+ it != tab->getRows().end(); ++it, f++)
+ {
+ if (f == mChatHistoryIndex)
+ mChatInput->setText(*it);
+ }
+ mChatInput->setCaretPosition(static_cast<unsigned>(
+ mChatInput->getText().length()));
+ }
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_CHAT_NEXT_HISTORY) &&
+ mChatInput->isVisible())
+ {
+ ChatTab *tab = getFocused();
+ if (tab && !tab->getRows().empty())
+ {
+ if (mChatHistoryIndex + 1 < tab->getRows().size())
+ {
+ mChatHistoryIndex ++;
+ }
+ else if (mChatHistoryIndex < tab->getRows().size())
+ {
+ mChatHistoryIndex ++;
+ mChatInput->setText("");
+ mChatInput->setCaretPosition(0);
+ return;
+ }
+ else
+ {
+ mChatHistoryIndex = 0;
+ }
+
+ std::list<std::string>::iterator it;
+ unsigned int f = 0;
+ for (it = tab->getRows().begin();
+ it != tab->getRows().end(); ++it, f++)
+ {
+ if (f == mChatHistoryIndex)
+ mChatInput->setText(*it);
+ }
+ mChatInput->setCaretPosition(static_cast<unsigned>(
+ mChatInput->getText().length()));
+ }
+ }
+
+ std::string Temp;
+ switch (event.getKey().getValue())
+ {
+ case Key::F2: Temp = "\u2318"; break;
+ case Key::F3: Temp = "\u263A"; break;
+ case Key::F4: Temp = "\u2665"; break;
+ case Key::F5: Temp = "\u266A"; break;
+ case Key::F6: Temp = "\u266B"; break;
+ case Key::F7: Temp = "\u26A0"; break;
+ case Key::F8: Temp = "\u2622"; break;
+ case Key::F9: Temp = "\u262E"; break;
+ case Key::F10: Temp = "\u2605"; break;
+ case Key::F11: Temp = "\u2618"; break;
+ case Key::F12: Temp = "\u2592"; break;
+ default: break;
+ }
+
+ if (Temp != "")
+ addInputText(Temp, false);
+}
+
+void ChatWindow::event(Channels channel, const Mana::Event &event)
+{
+ if (channel == CHANNEL_NOTICES)
+ {
+ if (event.getName() == EVENT_SERVERNOTICE && localChatTab)
+ localChatTab->chatLog(event.getString("message"), BY_SERVER);
+ }
+ else if (channel == CHANNEL_ATTRIBUTES)
+ {
+ if (!config.getBoolValue("showBattleEvents"))
+ return;
+
+ if (event.getName() == EVENT_UPDATEATTRIBUTE)
+ {
+ switch (event.getInt("id"))
+ {
+ case EXP:
+ {
+ if (event.getInt("oldValue") > event.getInt("newValue"))
+ break;
+
+ int change = event.getInt("newValue")
+ - event.getInt("oldValue");
+
+ if (change != 0)
+ battleChatLog("+" + toString(change) + " xp");
+ break;
+ }
+ case LEVEL:
+ battleChatLog("Level: " + toString(
+ event.getInt("newValue")));
+ break;
+ default:
+ break;
+ };
+ }
+ }
+}
+
+void ChatWindow::addInputText(const std::string &text, bool space)
+{
+ int caretPos = mChatInput->getCaretPosition();
+ const std::string inputText = mChatInput->getText();
+
+ std::ostringstream ss;
+ ss << inputText.substr(0, caretPos) << text;
+ if (space)
+ ss << " ";
+
+ ss << inputText.substr(caretPos);
+
+ mChatInput->setText(ss.str());
+ mChatInput->setCaretPosition(caretPos + static_cast<int>(
+ text.length()) + static_cast<int>(space));
+ requestChatFocus();
+}
+
+void ChatWindow::addItemText(const std::string &item)
+{
+ std::ostringstream text;
+ text << "[" << item << "]";
+ addInputText(text.str());
+}
+
+void ChatWindow::setVisible(bool isVisible)
+{
+ Window::setVisible(isVisible);
+
+ /*
+ * For whatever reason, if setVisible is called, the mTmpVisible effect
+ * should be disabled.
+ */
+ mTmpVisible = false;
+}
+
+void ChatWindow::whisper(const std::string &nick,
+ const std::string &mes, Own own)
+{
+ if (mes.empty() || !player_node)
+ return;
+
+ std::string playerName = player_node->getName();
+ std::string tempNick = nick;
+
+ toLower(playerName);
+ toLower(tempNick);
+
+ if (tempNick.compare(playerName) == 0)
+ return;
+
+ ChatTab *tab = 0;
+ TabMap::const_iterator i = mWhispers.find(tempNick);
+
+ if (i != mWhispers.end())
+ tab = i->second;
+ else if (config.getBoolValue("whispertab"))
+ tab = addWhisperTab(nick);
+
+ if (tab)
+ {
+ if (own == BY_PLAYER)
+ {
+ tab->chatInput(mes);
+ }
+ else if (own == BY_SERVER)
+ {
+ tab->chatLog(mes);
+ }
+ else
+ {
+ tab->chatLog(nick, mes);
+ player_node->afkRespond(tab, nick);
+ }
+ }
+ else if (localChatTab)
+ {
+ if (own == BY_PLAYER)
+ {
+ Net::getChatHandler()->privateMessage(nick, mes);
+
+ localChatTab->chatLog(strprintf(_("Whispering to %s: %s"),
+ nick.c_str(), mes.c_str()), BY_PLAYER);
+ }
+ else
+ {
+ localChatTab->chatLog(nick + " : " + mes, ACT_WHISPER, false);
+ if (player_node)
+ player_node->afkRespond(0, nick);
+ }
+ }
+}
+
+ChatTab *ChatWindow::addWhisperTab(const std::string &nick, bool switchTo)
+{
+ if (!player_node)
+ return NULL;
+
+ std::string playerName = player_node->getName();
+ std::string tempNick = nick;
+
+ toLower(playerName);
+ toLower(tempNick);
+
+ TabMap::const_iterator i = mWhispers.find(tempNick);
+ ChatTab *ret;
+
+ if (tempNick.compare(playerName) == 0)
+ return NULL;
+
+ if (i != mWhispers.end())
+ {
+ ret = i->second;
+ }
+ else
+ {
+ ret = new WhisperTab(nick);
+ mWhispers[tempNick] = ret;
+ if (config.getBoolValue("showChatHistory"))
+ ret->loadFromLogFile(nick);
+ }
+
+ if (switchTo)
+ mChatTabs->setSelectedTab(ret);
+
+ return ret;
+}
+
+ChatTab *ChatWindow::getWhisperTab(const std::string &nick) const
+{
+ if (!player_node)
+ return NULL;
+
+ std::string playerName = player_node->getName();
+ std::string tempNick = nick;
+
+ toLower(playerName);
+ toLower(tempNick);
+
+ TabMap::const_iterator i = mWhispers.find(tempNick);
+ ChatTab *ret = 0;
+
+ if (tempNick.compare(playerName) == 0)
+ return NULL;
+
+ if (i != mWhispers.end())
+ ret = i->second;
+
+ return ret;
+}
+
+std::string ChatWindow::addColors(std::string &msg)
+{
+ // default color or chat command
+ if (mChatColor == 0 || msg.length() == 0 || msg.at(0) == '#'
+ || msg.at(0) == '/' || msg.at(0) == '@' || msg.at(0) == '!')
+ {
+ return msg;
+ }
+
+ std::string newMsg = "";
+ int cMap[] = {1, 4, 5, 2, 3, 6, 7, 9, 0, 8};
+
+ // rainbow
+ switch(mChatColor)
+ {
+ case 11:
+ msg = removeColors(msg);
+ for (unsigned int f = 0; f < msg.length(); f ++)
+ {
+ newMsg += "##" + toString(mRainbowColor++) + msg.at(f);
+ if (mRainbowColor > 9)
+ mRainbowColor = 0;
+ }
+ return newMsg;
+ case 12:
+ msg = removeColors(msg);
+ for (unsigned int f = 0; f < msg.length(); f ++)
+ {
+ newMsg += "##" + toString(cMap[mRainbowColor++]) + msg.at(f);
+ if (mRainbowColor > 9)
+ mRainbowColor = 0;
+ }
+ return newMsg;
+ case 13:
+ msg = removeColors(msg);
+ for (unsigned int f = 0; f < msg.length(); f ++)
+ {
+ newMsg += "##" + toString(cMap[9-mRainbowColor++]) + msg.at(f);
+ if (mRainbowColor > 9)
+ mRainbowColor = 0;
+ }
+ return newMsg;
+ default:
+ break;
+ }
+
+ // simple colors
+ return "##" + toString(mChatColor - 1) + msg;
+}
+
+void ChatWindow::autoComplete()
+{
+ int caretPos = mChatInput->getCaretPosition();
+ int startName = 0;
+ const std::string inputText = mChatInput->getText();
+ std::string name = inputText.substr(0, caretPos);
+ std::string newName("");
+
+ for (int f = caretPos - 1; f > -1; f --)
+ {
+ if (isWordSeparator(inputText[f]))
+ {
+ startName = f + 1;
+ name = inputText.substr(f + 1, caretPos - f);
+ break;
+ }
+ }
+
+ if (caretPos - 1 + 1 == startName)
+ return;
+
+ ChatTab *cTab = static_cast<ChatTab*>(mChatTabs->getSelectedTab());
+ std::vector<std::string> nameList;
+
+ cTab->getAutoCompleteList(nameList);
+ newName = autoComplete(nameList, name);
+
+ if (newName == "" && actorSpriteManager)
+ {
+ actorSpriteManager->getPlayerNames(nameList, true);
+ newName = autoComplete(nameList, name);
+ }
+ if (newName == "")
+ newName = autoCompleteHistory(name);
+ if (newName == "" && spellManager)
+ newName = spellManager->autoComplete(name);
+ if (newName == "")
+ newName = autoCompleteCommands(name);
+ if (newName == "" && actorSpriteManager)
+ {
+ actorSpriteManager->getMobNames(nameList);
+ newName = autoComplete(nameList, name);
+ }
+
+ if (newName != "")
+ {
+ mChatInput->setText(inputText.substr(0, startName) + newName
+ + inputText.substr(caretPos, inputText.length() - caretPos));
+
+ int len = caretPos - static_cast<int>(name.length())
+ + static_cast<int>(newName.length());
+
+ if (startName > 0)
+ mChatInput->setCaretPosition(len + 1);
+ else
+ mChatInput->setCaretPosition(len);
+ }
+}
+
+std::string ChatWindow::autoComplete(std::vector<std::string> &names,
+ std::string partName) const
+{
+ std::vector<std::string>::iterator i = names.begin();
+ toLower(partName);
+ std::string newName("");
+
+ while (i != names.end())
+ {
+ if (!i->empty())
+ {
+ std::string name = *i;
+ toLower(name);
+
+ std::string::size_type pos = name.find(partName, 0);
+ if (pos == 0)
+ {
+ if (newName != "")
+ {
+ toLower(newName);
+ newName = findSameSubstring(name, newName);
+ }
+ else
+ {
+ newName = *i;
+ }
+ }
+ }
+ ++i;
+ }
+
+ return newName;
+}
+
+std::string ChatWindow::autoCompleteCommands(std::string partName)
+{
+ Commands::iterator i = mCommands.begin();
+ std::vector<std::string> nameList;
+
+ while (i != mCommands.end())
+ {
+ std::string line = *i;
+ std::string::size_type pos = line.find(partName, 0);
+ if (pos == 0)
+ nameList.push_back(line);
+ ++i;
+ }
+ return autoComplete(nameList, partName);
+}
+
+/*
+void ChatWindow::moveTabLeft(ChatTab *tab)
+{
+ mChatTabs->moveLeft(tab);
+}
+
+void ChatWindow::moveTabRight(ChatTab *tab)
+{
+ mChatTabs->moveRight(tab);
+}
+*/
+
+std::string ChatWindow::autoCompleteHistory(std::string partName)
+{
+ History::iterator i = mHistory.begin();
+ std::vector<std::string> nameList;
+
+ while (i != mHistory.end())
+ {
+ std::string line = *i;
+ unsigned int f = 0;
+ while (f < line.length() && !isWordSeparator(line.at(f)))
+ f++;
+
+ line = line.substr(0, f);
+ if (line != "")
+ nameList.push_back(line);
+
+ ++i;
+ }
+ return autoComplete(nameList, partName);
+}
+
+void ChatWindow::resortChatLog(std::string line, Own own,
+ bool ignoreRecord, bool tryRemoveColors)
+{
+ if (own == -1)
+ own = BY_SERVER;
+
+ if (tradeChatTab)
+ {
+ if (findI(line, mTradeFilter) != std::string::npos)
+ {
+// logger->log("trade: " + line);
+ tradeChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
+ return;
+ }
+
+ unsigned long idx = line.find(": \302\202");
+ if (idx != std::string::npos)
+ {
+ line = line.erase(idx + 2, 2);
+ tradeChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
+ return;
+ }
+
+ unsigned long idx1 = line.find("@@");
+ if (idx1 != std::string::npos)
+ {
+ unsigned long idx2 = line.find("|", idx1);
+ if (idx2 != std::string::npos)
+ {
+ unsigned long idx3 = line.find("@@", idx2);
+ if (idx3 != std::string::npos)
+ {
+ tradeChatTab->chatLog(line, own, ignoreRecord,
+ tryRemoveColors);
+ return;
+ }
+ }
+ }
+ }
+
+ if (localChatTab)
+ localChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
+}
+
+void ChatWindow::battleChatLog(std::string line, Own own,
+ bool ignoreRecord, bool tryRemoveColors)
+{
+ if (own == -1)
+ own = BY_SERVER;
+ if (battleChatTab)
+ battleChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
+ else if (debugChatTab)
+ debugChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
+}
+
+void ChatWindow::initTradeFilter()
+{
+ std::string tradeListName = Client::getServerConfigDirectory()
+ + "/tradefilter.txt";
+
+ std::ifstream tradeFile;
+ struct stat statbuf;
+
+ if (!stat(tradeListName.c_str(), &statbuf) && S_ISREG(statbuf.st_mode))
+ {
+ tradeFile.open(tradeListName.c_str(), std::ios::in);
+ char line[100];
+ while (tradeFile.getline(line, 100))
+ {
+ std::string str = line;
+ if (!str.empty())
+ mTradeFilter.push_back(str);
+ }
+ tradeFile.close();
+ }
+}
+
+void ChatWindow::updateOnline(std::set<std::string> &onlinePlayers)
+{
+ TabMap::iterator iter;
+ const Party *party = 0;
+ const Guild *guild = 0;
+ if (player_node)
+ {
+ party = player_node->getParty();
+ guild = player_node->getGuild();
+ }
+ for (iter = mWhispers.begin(); iter != mWhispers.end(); ++iter)
+ {
+ if (!iter->second)
+ return;
+
+ WhisperTab *tab = static_cast<WhisperTab*>(iter->second);
+
+ if (!tab)
+ continue;
+
+ if (onlinePlayers.find(tab->getNick()) != onlinePlayers.end())
+ {
+ tab->setTabColor(&Theme::getThemeColor(Theme::WHISPER));
+ }
+ else
+ {
+ const std::string nick = tab->getNick();
+ if (actorSpriteManager)
+ {
+ const Being *being = actorSpriteManager->findBeingByName(
+ nick, ActorSprite::PLAYER);
+ if (being)
+ {
+ tab->setTabColor(&Theme::getThemeColor(Theme::WHISPER));
+ continue;
+ }
+ }
+ if (party)
+ {
+ const PartyMember *pm = party->getMember(nick);
+ if (pm && pm->getOnline())
+ {
+ tab->setTabColor(&Theme::getThemeColor(Theme::WHISPER));
+ continue;
+ }
+ }
+ if (guild)
+ {
+ const GuildMember *gm = guild->getMember(nick);
+ if (gm && gm->getOnline())
+ {
+ tab->setTabColor(&Theme::getThemeColor(Theme::WHISPER));
+ continue;
+ }
+ }
+ tab->setTabColor(&Theme::getThemeColor(Theme::WHISPER_OFFLINE));
+ }
+ }
+}
+
+void ChatWindow::loadState()
+{
+ int num = 0;
+ while (num < 50)
+ {
+ std::string nick = serverConfig.getValue(
+ "chatWhisper" + toString(num), "");
+
+ if (nick.empty())
+ break;
+ addWhisperTab(nick);
+ serverConfig.deleteKey("chatWhisper" + toString(num));
+ num ++;
+ }
+
+ while (num < 50)
+ {
+ serverConfig.deleteKey("chatWhisper" + toString(num));
+ num ++;
+ }
+}
+
+void ChatWindow::saveState()
+{
+ int num = 0;
+ TabMap::iterator iter;
+ for (iter = mWhispers.begin(); iter != mWhispers.end() && num < 50; ++iter)
+ {
+ if (!iter->second)
+ return;
+
+ WhisperTab *tab = static_cast<WhisperTab*>(iter->second);
+
+ if (!tab)
+ continue;
+
+ serverConfig.setValue("chatWhisper" + toString(num),
+ tab->getNick());
+
+ num ++;
+ }
+
+ while (num < 50)
+ {
+ serverConfig.deleteKey("chatWhisper" + toString(num));
+ num ++;
+ }
+}
+
+std::string ChatWindow::doReplace(const std::string &msg)
+{
+ if (Client::getServerName() == "server.themanaworld.org"
+ || Client::getServerName() == "themanaworld.org"
+ || Client::getServerName() == "81.161.192.4")
+ {
+ return msg;
+ }
+
+ std::string str = msg;
+ replaceSpecialChars(str);
+ return str;
+}
diff --git a/src/gui/chat.h b/src/gui/chat.h
new file mode 100644
index 000000000..444057b57
--- /dev/null
+++ b/src/gui/chat.h
@@ -0,0 +1,318 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHAT_H
+#define CHAT_H
+
+#include "listener.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/widget.hpp>
+#include <guichan/widgetlistener.hpp>
+
+#include <list>
+#include <string>
+#include <map>
+#include <vector>
+#include <set>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class BrowserBox;
+class ChatTab;
+class Channel;
+class ChatInput;
+class ColorListModel;
+class ScrollArea;
+class TabbedArea;
+class ItemLinkHandler;
+class Tab;
+class WhisperTab;
+
+#define DEFAULT_CHAT_WINDOW_SCROLL 7 // 1 means `1/8th of the window size'.
+
+enum Own
+{
+ BY_GM = 0,
+ BY_PLAYER,
+ BY_OTHER,
+ BY_SERVER,
+ BY_CHANNEL,
+ ACT_WHISPER, // getting whispered at
+ ACT_IS, // equivalent to "/me" on IRC
+ BY_LOGGER,
+ BY_UNKNOWN = -1
+};
+
+/** One item in the chat log */
+struct CHATLOG
+{
+ std::string nick;
+ std::string text;
+ Own own;
+};
+
+/**
+ * The chat window.
+ *
+ * \ingroup Interface
+ */
+class ChatWindow : public Window,
+ public gcn::ActionListener,
+ public gcn::KeyListener,
+ public Mana::Listener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ChatWindow();
+
+ /**
+ * Destructor: used to write back values to the config file
+ */
+ ~ChatWindow();
+
+ /**
+ * Reset the chat window to default positions.
+ */
+ void resetToDefaultSize();
+
+ /**
+ * Gets the focused tab.
+ */
+ ChatTab *getFocused() const;
+
+ /**
+ * Clear the given tab.
+ */
+ void clearTab(ChatTab *tab);
+
+ /**
+ * Clear the current tab.
+ */
+ void clearTab();
+
+ /**
+ * Switch to the previous tab in order
+ */
+ void prevTab();
+
+ /**
+ * Switch to the next tab in order
+ */
+ void nextTab();
+
+ /**
+ * Switch to the default tab
+ */
+ void defaultTab();
+
+ /**
+ * Performs action.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Request focus for typing chat message.
+ *
+ * \returns true if the input was shown
+ * false otherwise
+ */
+ bool requestChatFocus();
+
+ /**
+ * Checks whether ChatWindow is Focused or not.
+ */
+ bool isInputFocused() const;
+
+ /**
+ * Passes the text to the current tab as input
+ *
+ * @param msg The message text which is to be sent.
+ */
+ void chatInput(const std::string &msg);
+
+ /**
+ * Passes the text to the local chat tab as input
+ *
+ * @param msg The message text which is to be sent.
+ */
+ void localChatInput(const std::string &msg);
+
+ /** Called when key is pressed */
+ void keyPressed(gcn::KeyEvent &event);
+
+ /** Set the chat input as the given text. */
+ void setInputText(const std::string &text);
+
+ /** Add the given text to the chat input. */
+ void addInputText(const std::string &text, bool space = true);
+
+ /** Called to add item to chat */
+ void addItemText(const std::string &item);
+
+ /** Override to reset mTmpVisible */
+ void setVisible(bool visible);
+
+ /**
+ * Handles mouse when dragged.
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse when pressed.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+
+ void event(Channels channel, const Mana::Event &event);
+
+ /**
+ * Scrolls the chat window
+ *
+ * @param amount direction and amount to scroll. Negative numbers scroll
+ * up, positive numbers scroll down. The absolute amount indicates the
+ * amount of 1/8ths of chat window real estate that should be scrolled.
+ */
+ void scroll(int amount);
+
+ /**
+ * Sets the file being recorded to
+ *
+ * @param msg The file to write out to. If null, then stop recording.
+ */
+ void setRecordingFile(const std::string &msg);
+
+ bool getReturnTogglesChat() const
+ { return mReturnToggles; }
+
+ void setReturnTogglesChat(bool toggles)
+ { mReturnToggles = toggles; }
+
+ void doPresent();
+
+ void whisper(const std::string &nick, const std::string &mes,
+ Own own = BY_OTHER);
+
+ ChatTab *addWhisperTab(const std::string &nick, bool switchTo = false);
+
+ ChatTab *getWhisperTab(const std::string &nick) const;
+
+ void removeAllWhispers();
+
+ void ignoreAllWhispers();
+
+ void resortChatLog(std::string line, Own own = BY_UNKNOWN,
+ bool ignoreRecord = false,
+ bool tryRemoveColors = true);
+
+ void battleChatLog(std::string line, Own own = BY_UNKNOWN,
+ bool ignoreRecord = false,
+ bool tryRemoveColors = true);
+
+ void updateOnline(std::set<std::string> &onlinePlayers);
+
+ void loadState();
+
+ void saveState();
+
+ std::string doReplace(const std::string &msg);
+
+ protected:
+ friend class ChatTab;
+ friend class WhisperTab;
+ friend class PopupMenu;
+
+ /** Remove the given tab from the window */
+ void removeTab(ChatTab *tab);
+
+ /** Add the tab to the window */
+ void addTab(ChatTab *tab);
+
+ void removeWhisper(const std::string &nick);
+
+ void adjustTabSize();
+
+ void autoComplete();
+
+ std::string addColors(std::string &msg);
+
+ std::string autoCompleteHistory(std::string partName);
+
+ std::string autoCompleteCommands(std::string partName);
+
+ std::string autoComplete(std::vector<std::string> &names,
+ std::string partName) const;
+
+ /** Used for showing item popup on clicking links **/
+ ItemLinkHandler *mItemLinkHandler;
+
+ /** Input box for typing chat messages. */
+ ChatInput *mChatInput;
+
+ void widgetResized(const gcn::Event &event);
+
+ void initTradeFilter();
+
+ int mRainbowColor;
+
+ private:
+ void fillCommands();
+
+ bool mTmpVisible;
+
+ /** Tabbed area for holding each channel. */
+ TabbedArea *mChatTabs;
+
+ typedef std::map<const std::string, ChatTab*> TabMap;
+ /** Manage whisper tabs */
+ TabMap mWhispers;
+
+ typedef std::list<std::string> History;
+ typedef History::iterator HistoryIterator;
+ History mHistory; /**< Command history. */
+ HistoryIterator mCurHist; /**< History iterator. */
+
+ typedef std::list<std::string> Commands;
+ typedef Commands::iterator CommandsIterator;
+ History mCommands; /**< Command list. */
+
+ bool mReturnToggles; /**< Marks whether <Return> toggles the chat log
+ or not */
+
+ std::list<std::string> mTradeFilter;
+
+ gcn::DropDown *mColorPicker;
+ ColorListModel *mColorListModel;
+ int mChatColor;
+ unsigned int mChatHistoryIndex;
+};
+
+extern ChatWindow *chatWindow;
+
+#endif
diff --git a/src/gui/confirmdialog.cpp b/src/gui/confirmdialog.cpp
new file mode 100644
index 000000000..1d24a25bd
--- /dev/null
+++ b/src/gui/confirmdialog.cpp
@@ -0,0 +1,112 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/confirmdialog.h"
+
+#include "sound.h"
+
+#include "gui/gui.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/textbox.h"
+
+#include "utils/gettext.h"
+
+#include <guichan/font.hpp>
+
+ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
+ bool ignore, bool modal, Window *parent):
+ Window(title, modal, parent)
+{
+ mTextBox = new TextBox;
+ mTextBox->setEditable(false);
+ mTextBox->setOpaque(false);
+ mTextBox->setTextWrapped(msg, 260);
+
+ gcn::Button *yesButton = new Button(_("Yes"), "yes", this);
+ gcn::Button *noButton = new Button(_("No"), "no", this);
+ gcn::Button *ignoreButton = NULL;
+
+ if (ignore)
+ ignoreButton = new Button(_("Ignore"), "ignore", this);
+
+ const int numRows = mTextBox->getNumberOfRows();
+ int inWidth = yesButton->getWidth() + noButton->getWidth() +
+ (2 * getPadding());
+
+ if (ignoreButton)
+ inWidth += ignoreButton->getWidth();
+
+ const int fontHeight = getFont()->getHeight();
+ const int height = numRows * fontHeight;
+ int width = getFont()->getWidth(title);
+
+ if (width < mTextBox->getMinWidth())
+ width = mTextBox->getMinWidth();
+ if (width < inWidth)
+ width = inWidth;
+
+ setContentSize(mTextBox->getMinWidth() + fontHeight, height + fontHeight +
+ noButton->getHeight());
+ mTextBox->setPosition(getPadding(), getPadding());
+
+ // 8 is the padding that GUIChan adds to button widgets
+ // (top and bottom combined)
+ yesButton->setPosition((width - inWidth) / 2, height + 8);
+ noButton->setPosition(yesButton->getX() + yesButton->getWidth()
+ + (2 * getPadding()),
+ height + 8);
+ if (ignoreButton)
+ {
+ ignoreButton->setPosition(noButton->getX() + noButton->getWidth()
+ + (2 * getPadding()), height + 8);
+ }
+
+ add(mTextBox);
+ add(yesButton);
+ add(noButton);
+
+ if (ignore && ignoreButton)
+ add(ignoreButton);
+
+ if (getParent())
+ {
+ center();
+ getParent()->moveToTop(this);
+ }
+ setVisible(true);
+ yesButton->requestFocus();
+ sound.playGuiSfx("system/newmessage.ogg");
+}
+
+void ConfirmDialog::action(const gcn::ActionEvent &event)
+{
+ setActionEventId(event.getId());
+ distributeActionEvent();
+
+ // Can we receive anything else anyway?
+ if (event.getId() == "yes" || event.getId() == "no"
+ || event.getId() == "ignore")
+ {
+ scheduleDelete();
+ }
+}
+
diff --git a/src/gui/confirmdialog.h b/src/gui/confirmdialog.h
new file mode 100644
index 000000000..0ba9c869b
--- /dev/null
+++ b/src/gui/confirmdialog.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef OPTION_DIALOG_H
+#define OPTION_DIALOG_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class TextBox;
+
+/**
+ * An option dialog.
+ *
+ * \ingroup GUI
+ */
+class ConfirmDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ ConfirmDialog(const std::string &title, const std::string &msg,
+ bool ignore = false, bool modal = false,
+ Window *parent = NULL);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ TextBox *mTextBox;
+};
+
+#endif
diff --git a/src/gui/connectiondialog.cpp b/src/gui/connectiondialog.cpp
new file mode 100644
index 000000000..8f960d335
--- /dev/null
+++ b/src/gui/connectiondialog.cpp
@@ -0,0 +1,65 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "connectiondialog.h"
+
+#include "log.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/progressindicator.h"
+
+#include "utils/gettext.h"
+
+ConnectionDialog::ConnectionDialog(const std::string &text,
+ State cancelState):
+ Window(""),
+ mCancelState(cancelState)
+{
+ setTitleBarHeight(0);
+ setMovable(false);
+ setMinWidth(0);
+
+ ProgressIndicator *progressIndicator = new ProgressIndicator;
+ gcn::Label *label = new Label(text);
+ Button *cancelButton = new Button(_("Cancel"), "cancelButton", this);
+
+ place(0, 0, progressIndicator);
+ place(0, 1, label);
+ place(0, 2, cancelButton).setHAlign(LayoutCell::CENTER);
+ reflowLayout();
+
+ center();
+ setVisible(true);
+}
+
+void ConnectionDialog::action(const gcn::ActionEvent &)
+{
+ logger->log1("Cancel pressed");
+ Client::setState(mCancelState);
+}
+
+void ConnectionDialog::draw(gcn::Graphics *graphics)
+{
+ // Don't draw the window background, only draw the children
+ drawChildren(graphics);
+}
diff --git a/src/gui/connectiondialog.h b/src/gui/connectiondialog.h
new file mode 100644
index 000000000..623a66455
--- /dev/null
+++ b/src/gui/connectiondialog.h
@@ -0,0 +1,62 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CONNECTION_H
+#define CONNECTION_H
+
+#include "client.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+/**
+ * The connection dialog.
+ *
+ * \ingroup Interface
+ */
+class ConnectionDialog : public Window, gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param text The text to display
+ * @param cancelState The state to enter when Cancel is pressed
+ *
+ * @see Window::Window
+ */
+ ConnectionDialog(const std::string &text, State cancelState);
+
+ /**
+ * Called when the user presses Cancel. Restores the global state to
+ * the previous one.
+ */
+ void action(const gcn::ActionEvent &);
+
+ void draw(gcn::Graphics *graphics);
+
+ private:
+ gcn::Label *mLabel;
+ State mCancelState;
+};
+
+#endif
diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp
new file mode 100644
index 000000000..2feb30c80
--- /dev/null
+++ b/src/gui/debugwindow.cpp
@@ -0,0 +1,248 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/debugwindow.h"
+
+#include "client.h"
+#include "game.h"
+#include "localplayer.h"
+#include "main.h"
+#include "map.h"
+#include "particle.h"
+
+#include "gui/setup.h"
+#include "gui/setup_video.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/chattab.h"
+
+#include "resources/image.h"
+
+#include "net/packetcounters.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+DebugWindow::DebugWindow():
+ Window(_("Debug"))
+{
+ setWindowName("Debug");
+ if (setupWindow)
+ setupWindow->registerWindowForReset(this);
+
+ mUpdateTime = 0;
+ setResizable(true);
+ setCloseButton(true);
+ setSaveVisible(true);
+ setDefaultSize(500, 150, ImageRect::CENTER);
+
+#ifdef USE_OPENGL
+ switch (Image::getLoadAsOpenGL())
+ {
+ case 0:
+ mFPSText = _("%d FPS (Software)");
+ break;
+ case 1:
+ default:
+ mFPSText = _("%d FPS (fast OpenGL)");
+ break;
+ case 2:
+ mFPSText = _("%d FPS (old OpenGL)");
+ break;
+ };
+#else
+ mFPSText = _("%d FPS (Software)");
+#endif
+
+ mFPSLabel = new Label(strprintf(_("%d FPS"), 0));
+ mMusicFileLabel = new Label(strprintf(_("Music:")));
+ mMapLabel = new Label(strprintf(_("Map:")));
+ mMinimapLabel = new Label(strprintf(_("Minimap:")));
+ mTileMouseLabel = new Label(strprintf(_("Cursor: (%d, %d)"), 0, 0));
+ mParticleCountLabel = new Label(strprintf(_("Particle count: %d"), 88888));
+ mMapActorCountLabel = new Label(strprintf(
+ _("Map actors count: %d"), 88888));
+
+ mPingLabel = new Label(" ");
+ mInPackets1Label = new Label(" ");
+ mOutPackets1Label = new Label(" ");
+
+ mXYLabel = new Label(strprintf("%s (?,?)", _("Player Position:")));
+ mTargetLabel = new Label(strprintf("%s ?", _("Target:")));
+ mTargetIdLabel = new Label(strprintf("%s ? ", _("Target Id:")));
+ mTargetLevelLabel = new Label(strprintf("%s ?", _("Target Level:")));
+ mTargetPartyLabel = new Label(strprintf("%s ?", _("Target Party:")));
+ mTargetGuildLabel = new Label(strprintf("%s ?", _("Target Guild:")));
+
+ place(0, 0, mFPSLabel, 3);
+ place(4, 0, mTileMouseLabel, 2);
+ place(0, 1, mMusicFileLabel, 3);
+ place(4, 1, mParticleCountLabel, 2);
+ place(4, 2, mMapActorCountLabel, 2);
+ place(0, 2, mMapLabel, 4);
+ place(0, 3, mMinimapLabel, 4);
+ place(0, 4, mXYLabel, 4);
+ place(4, 3, mPingLabel, 2);
+ place(4, 4, mInPackets1Label, 2);
+ place(4, 5, mOutPackets1Label, 2);
+ place(0, 5, mTargetLabel, 4);
+ place(0, 6, mTargetIdLabel, 4);
+ place(0, 7, mTargetLevelLabel, 4);
+ place(0, 8, mTargetPartyLabel, 4);
+ place(0, 9, mTargetGuildLabel, 4);
+
+ loadWindowState();
+}
+
+void DebugWindow::logic()
+{
+ if (!isVisible())
+ return;
+
+ mFPSLabel->setCaption(strprintf(mFPSText.c_str(), fps));
+
+ if (player_node)
+ {
+ mXYLabel->setCaption(strprintf("%s (%d, %d)", _("Player Position:"),
+ player_node->getTileX(), player_node->getTileY()));
+ }
+ else
+ {
+ mXYLabel->setCaption(strprintf("%s (?, ?)", _("Player Position:")));
+ }
+
+ if (player_node && player_node->getTarget())
+ {
+ Being *target = player_node->getTarget();
+
+ mTargetLabel->setCaption(strprintf("%s %s (%d, %d)", _("Target:"),
+ target->getName().c_str(), target->getTileX(),
+ target->getTileY()));
+
+ mTargetIdLabel->setCaption(strprintf("%s %d",
+ _("Target Id:"), target->getId()));
+ if (target->getLevel())
+ {
+ mTargetLevelLabel->setCaption(strprintf("%s %d",
+ _("Target Level:"), target->getLevel()));
+ }
+ else
+ {
+ mTargetLevelLabel->setCaption(strprintf("%s ?",
+ _("Target Level:")));
+ }
+
+ mTargetPartyLabel->setCaption(strprintf("%s %s", _("Target Party:"),
+ target->getPartyName().c_str()));
+
+ mTargetGuildLabel->setCaption(strprintf("%s %s", _("Target Guild:"),
+ target->getGuildName().c_str()));
+ }
+ else
+ {
+ mTargetLabel->setCaption(strprintf("%s ?", _("Target:")));
+ mTargetIdLabel->setCaption(strprintf("%s ?", _("Target Id:")));
+ mTargetLevelLabel->setCaption(strprintf("%s ?", _("Target Level:")));
+ mTargetPartyLabel->setCaption(strprintf("%s ?", _("Target Party:")));
+ mTargetGuildLabel->setCaption(strprintf("%s ?", _("Target Guild:")));
+ }
+
+ const Map *map = Game::instance()->getCurrentMap();
+ if (map && viewport)
+ {
+ // Get the current mouse position
+ int mouseTileX = (viewport->getMouseX() + viewport->getCameraX())
+ / map->getTileWidth();
+ int mouseTileY = (viewport->getMouseY() + viewport->getCameraY())
+ / map->getTileHeight();
+ mTileMouseLabel->setCaption(strprintf("%s (%d, %d)",
+ _("Cursor:"), mouseTileX, mouseTileY));
+
+ mMusicFileLabel->setCaption(strprintf("%s %s", _("Music:"),
+ map->getProperty("music").c_str()));
+ mMinimapLabel->setCaption(strprintf("%s %s", _("Minimap:"),
+ map->getProperty("minimap").c_str()));
+ mMapLabel->setCaption(strprintf("%s %s", _("Map:"),
+ map->getProperty("_filename").c_str()));
+
+
+ if (mUpdateTime != cur_time)
+ {
+ mUpdateTime = cur_time;
+ mParticleCountLabel->setCaption(strprintf(_("Particle count: %d"),
+ Particle::particleCount));
+
+ mMapActorCountLabel->setCaption(
+ strprintf("%s %d", _("Map actors count:"),
+ map->getActorsCount()));
+ }
+ }
+ else
+ {
+ mTileMouseLabel->setCaption(strprintf("%s (?, ?)", _("Cursor:")));
+
+ mMusicFileLabel->setCaption(strprintf("%s ?", _("Music:")));
+ mMinimapLabel->setCaption(strprintf("%s ?", _("Minimap:")));
+ mMapLabel->setCaption(strprintf("%s ?", _("Map:")));
+
+ mMapActorCountLabel->setCaption(
+ strprintf("%s ?", _("Map actors count:")));
+ }
+
+ mMapActorCountLabel->adjustSize();
+ mParticleCountLabel->adjustSize();
+
+ if (player_node && player_node->getPingTime() != 0)
+ {
+ mPingLabel->setCaption(strprintf(_("Ping: %d ms"),
+ player_node->getPingTime()));
+ }
+ else
+ {
+ mPingLabel->setCaption(_("Ping: ? ms"));
+ }
+
+ mInPackets1Label->setCaption(strprintf(_("In: %d bytes/s"),
+ PacketCounters::getInBytes()));
+ mOutPackets1Label->setCaption(strprintf(_("Out: %d bytes/s"),
+ PacketCounters::getOutBytes()));
+
+ if (player_node)
+ player_node->tryPingRequest();
+}
+
+void DebugWindow::draw(gcn::Graphics *g)
+{
+ Window::draw(g);
+
+ if (player_node)
+ {
+ Being *target = player_node->getTarget();
+ if (target)
+ {
+ Graphics *g2 = static_cast<Graphics*>(g);
+ target->draw(g2, -target->getPixelX() + 16 + getWidth() / 2,
+ -target->getPixelY() + 32 + getHeight() / 2);
+ }
+ }
+}
diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h
new file mode 100644
index 000000000..1c97f8ca9
--- /dev/null
+++ b/src/gui/debugwindow.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef DEBUGWINDOW_H
+#define DEBUGWINDOW_H
+
+#include "gui/widgets/window.h"
+
+class Label;
+
+/**
+ * The debug window.
+ *
+ * \ingroup Interface
+ */
+class DebugWindow : public Window
+{
+ public:
+ /**
+ * Constructor.
+ */
+ DebugWindow();
+
+ /**
+ * Logic (updates components' size and infos)
+ */
+ void logic();
+
+ void draw(gcn::Graphics *g);
+
+ void setPing(int pingTime);
+
+ private:
+ Label *mMusicFileLabel, *mMapLabel, *mMinimapLabel;
+ Label *mTileMouseLabel, *mFPSLabel;
+ Label *mParticleCountLabel;
+ Label *mMapActorCountLabel;
+ Label *mXYLabel;
+ Label *mTargetLabel;
+ Label *mTargetIdLabel;
+ Label *mTargetLevelLabel;
+ Label *mTargetPartyLabel;
+ Label *mTargetGuildLabel;
+ Label *mPingLabel;
+ Label *mInPackets1Label;
+ Label *mOutPackets1Label;
+
+ std::string mFPSText;
+ int mUpdateTime;
+};
+
+extern DebugWindow *debugWindow;
+
+#endif
diff --git a/src/gui/editdialog.cpp b/src/gui/editdialog.cpp
new file mode 100644
index 000000000..b8d999ce7
--- /dev/null
+++ b/src/gui/editdialog.cpp
@@ -0,0 +1,73 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/editdialog.h"
+
+#include "gui/gui.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/textfield.h"
+
+#include "utils/gettext.h"
+
+#include <guichan/font.hpp>
+
+EditDialog::EditDialog(const std::string &title, const std::string &msg,
+ std::string eventOk, int width,
+ Window *parent, bool modal):
+ Window(title, modal, parent)
+{
+ mTextField = new TextField;
+ mTextField->setText(msg);
+
+ mEventOk = eventOk;
+
+ gcn::Button *okButton = new Button(_("OK"), mEventOk, this);
+
+ const int numRows = 1;
+ const int fontHeight = getFont()->getHeight();
+ const int height = numRows * fontHeight;
+
+ setContentSize(width, height + fontHeight + okButton->getHeight());
+ mTextField->setPosition(getPadding(), getPadding());
+ mTextField->setWidth(width - (2 * getPadding()));
+
+ okButton->setPosition((width - okButton->getWidth()) / 2, height + 8);
+
+ add(mTextField);
+ add(okButton);
+
+ center();
+ setVisible(true);
+ okButton->requestFocus();
+}
+
+void EditDialog::action(const gcn::ActionEvent &event)
+{
+ // Proxy button events to our listeners
+ ActionListenerIterator i;
+ for (i = mActionListeners.begin(); i != mActionListeners.end(); ++i)
+ (*i)->action(event);
+
+ if (event.getId() == mEventOk)
+ scheduleDelete();
+}
diff --git a/src/gui/editdialog.h b/src/gui/editdialog.h
new file mode 100644
index 000000000..55947b23d
--- /dev/null
+++ b/src/gui/editdialog.h
@@ -0,0 +1,66 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef EDIT_DIALOG_H
+#define EDIT_DIALOG_H
+
+#include "gui/widgets/window.h"
+#include "gui/widgets/textfield.h"
+
+#include <guichan/actionlistener.hpp>
+
+#define ACTION_EDIT_OK "edit ok"
+
+class TextField;
+
+/**
+ * An 'Ok' button dialog.
+ *
+ * \ingroup GUI
+ */
+class EditDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ EditDialog(const std::string &title, const std::string &msg,
+ std::string eventOk = ACTION_EDIT_OK, int width = 300,
+ Window *parent = NULL, bool modal = true);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ std::string getMsg()
+ { return mTextField->getText(); }
+
+ private:
+ std::string mEventOk;
+
+ TextField *mTextField;
+};
+
+#endif
diff --git a/src/gui/emotepopup.cpp b/src/gui/emotepopup.cpp
new file mode 100644
index 000000000..2a0d94aca
--- /dev/null
+++ b/src/gui/emotepopup.cpp
@@ -0,0 +1,214 @@
+/*
+ * Extended support for activating emotes
+ * Copyright (C) 2009 Aethyra Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/emotepopup.h"
+
+#include "animatedsprite.h"
+#include "configuration.h"
+#include "emoteshortcut.h"
+#include "graphics.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/theme.h"
+
+#include "resources/emotedb.h"
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+
+#include "utils/dtor.h"
+
+#include <guichan/mouseinput.hpp>
+#include <guichan/selectionlistener.hpp>
+
+const int EmotePopup::gridWidth = 34; // emote icon width + 4
+const int EmotePopup::gridHeight = 36; // emote icon height + 4
+
+static const int MAX_COLUMNS = 6;
+
+EmotePopup::EmotePopup():
+ mSelectedEmoteIndex(-1),
+ mHoveredEmoteIndex(-1),
+ mRowCount(1),
+ mColumnCount(1)
+{
+ // Setup emote sprites
+ for (int i = 0; i <= EmoteDB::getLast(); ++i)
+ {
+ const AnimatedSprite *sprite = EmoteDB::getAnimation(i, true);
+ if (sprite)
+ mEmotes.push_back(sprite);
+ }
+
+ mSelectionImage = Theme::getImageFromTheme("selection.png");
+ if (!mSelectionImage)
+ logger->log1("Error: Unable to load selection.png");
+
+ if (mSelectionImage)
+ mSelectionImage->setAlpha(Client::getGuiAlpha());
+
+ addMouseListener(this);
+ recalculateSize();
+ setVisible(true);
+}
+
+EmotePopup::~EmotePopup()
+{
+ if (mSelectionImage)
+ mSelectionImage->decRef();
+}
+
+void EmotePopup::draw(gcn::Graphics *graphics)
+{
+ Popup::draw(graphics);
+
+ if (!mColumnCount)
+ return;
+
+ const unsigned int emoteCount = static_cast<unsigned>(mEmotes.size());
+ const unsigned int emotesLeft
+ = static_cast<unsigned>(mEmotes.size() % mColumnCount);
+
+ for (unsigned int i = 0; i < emoteCount ; i++)
+ {
+ int row = i / mColumnCount;
+ int column = i % mColumnCount;
+
+ unsigned int emoteX = 4 + column * gridWidth;
+ unsigned int emoteY = 4 + row * gridHeight;
+
+ // Center the last row when there are less emotes than columns
+ if (emotesLeft > 0 && row == mRowCount - 1)
+ emoteX += (mColumnCount - emotesLeft) * gridWidth / 2;
+
+ // Draw selection image below hovered item
+ if (mSelectionImage && static_cast<int>(i) == mHoveredEmoteIndex)
+ {
+ static_cast<Graphics*>(graphics)->drawImage(
+ mSelectionImage, emoteX, emoteY + 4);
+ }
+
+ // Draw emote icon
+ if (mEmotes[i])
+ mEmotes[i]->draw(static_cast<Graphics*>(graphics), emoteX, emoteY);
+ }
+}
+
+void EmotePopup::mousePressed(gcn::MouseEvent &event)
+{
+ if (event.getButton() != gcn::MouseEvent::LEFT)
+ return;
+
+ const int index = getIndexAt(event.getX(), event.getY());
+ if (index != -1)
+ {
+ setSelectedEmoteIndex(index);
+ if (emoteShortcut)
+ {
+ emoteShortcut->setEmoteSelected(
+ static_cast<unsigned char>(index + 1));
+ }
+ }
+}
+
+void EmotePopup::mouseMoved(gcn::MouseEvent &event)
+{
+ Popup::mouseMoved(event);
+
+ mHoveredEmoteIndex = getIndexAt(event.getX(), event.getY());
+}
+
+int EmotePopup::getSelectedEmote() const
+{
+ return 1 + mSelectedEmoteIndex;
+}
+
+void EmotePopup::setSelectedEmoteIndex(int index)
+{
+ if (index == mSelectedEmoteIndex)
+ return;
+
+ mSelectedEmoteIndex = index;
+ distributeValueChangedEvent();
+}
+
+int EmotePopup::getIndexAt(int x, int y) const
+{
+ if (!gridWidth || !gridHeight)
+ return -1;
+
+ const unsigned int emotesLeft
+ = static_cast<unsigned>(mEmotes.size() % mColumnCount);
+ const unsigned int row = y / gridHeight;
+ unsigned int column;
+
+ // Take into account that the last row is centered
+ if (emotesLeft > 0 && static_cast<signed>(row) == mRowCount - 1)
+ {
+ int unsigned emotesMissing = mColumnCount - emotesLeft;
+ column = std::min((x - emotesMissing * gridWidth / 2) / gridWidth,
+ emotesLeft - 1);
+ }
+ else
+ {
+ column = std::min(x / gridWidth, mColumnCount - 1);
+ }
+
+ int unsigned index = column + (row * mColumnCount);
+
+ if (index < mEmotes.size())
+ return index;
+
+ return -1;
+}
+
+void EmotePopup::recalculateSize()
+{
+ const unsigned emoteCount = static_cast<unsigned>(mEmotes.size());
+
+ mRowCount = emoteCount / MAX_COLUMNS;
+ if (emoteCount % MAX_COLUMNS > 0)
+ ++mRowCount;
+
+ if (mRowCount)
+ mColumnCount = emoteCount / mRowCount;
+ else
+ mColumnCount = 1;
+
+ if (emoteCount % mRowCount > 0)
+ ++mColumnCount;
+
+ setContentSize(mColumnCount * gridWidth, mRowCount * gridHeight);
+}
+
+void EmotePopup::distributeValueChangedEvent()
+{
+ gcn::SelectionEvent event(this);
+ Listeners::const_iterator i_end = mListeners.end();
+ Listeners::const_iterator i;
+
+ for (i = mListeners.begin(); i != i_end; ++i)
+ {
+ if (*i)
+ (*i)->valueChanged(event);
+ }
+}
diff --git a/src/gui/emotepopup.h b/src/gui/emotepopup.h
new file mode 100644
index 000000000..c1026d0a5
--- /dev/null
+++ b/src/gui/emotepopup.h
@@ -0,0 +1,121 @@
+/*
+ * Extended support for activating emotes
+ * Copyright (C) 2009 Aethyra Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EMOTEPOPUP_H
+#define EMOTEPOPUP_H
+
+#include "gui/widgets/popup.h"
+
+#include <guichan/mouselistener.hpp>
+
+#include <list>
+#include <vector>
+
+class AnimatedSprite;
+class Image;
+
+namespace gcn
+{
+ class SelectionListener;
+}
+
+/**
+ * An emote popup. Used to activate emotes and assign them to shortcuts.
+ *
+ * \ingroup GUI
+ */
+class EmotePopup : public Popup
+{
+ public:
+ /**
+ * Constructor. Initializes the graphic.
+ */
+ EmotePopup();
+
+ virtual ~EmotePopup();
+
+ /**
+ * Draws the emotes.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ void mousePressed(gcn::MouseEvent &event);
+ void mouseMoved(gcn::MouseEvent &event);
+
+ /**
+ * Returns the selected emote.
+ */
+ int getSelectedEmote() const;
+
+ /**
+ * Adds a listener to the list that's notified each time a change to
+ * the selection occurs.
+ */
+ void addSelectionListener(gcn::SelectionListener *listener)
+ { mListeners.push_back(listener); }
+
+ /**
+ * Removes a listener from the list that's notified each time a change
+ * to the selection occurs.
+ */
+ void removeSelectionListener(gcn::SelectionListener *listener)
+ { mListeners.remove(listener); }
+
+ private:
+ /**
+ * Sets the index of the currently selected emote.
+ */
+ void setSelectedEmoteIndex(int index);
+
+ /**
+ * Returns the index at the specified coordinates. Returns -1 when
+ * there is no valid index.
+ */
+ int getIndexAt(int x, int y) const;
+
+ /**
+ * Determine and set the size of the container.
+ */
+ void recalculateSize();
+
+ /**
+ * Sends out selection events to the list of selection listeners.
+ */
+ void distributeValueChangedEvent();
+
+ std::vector<const AnimatedSprite*> mEmotes;
+ Image *mSelectionImage;
+ int mSelectedEmoteIndex;
+ int mHoveredEmoteIndex;
+
+ int mRowCount;
+ int mColumnCount;
+
+ typedef std::list<gcn::SelectionListener*> Listeners;
+
+ Listeners mListeners;
+
+ static const int gridWidth;
+ static const int gridHeight;
+};
+
+#endif
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
new file mode 100644
index 000000000..dc5dc8c04
--- /dev/null
+++ b/src/gui/equipmentwindow.cpp
@@ -0,0 +1,260 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/button.h"
+
+#include "equipment.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+
+#include "gui/equipmentwindow.h"
+#include "gui/itempopup.h"
+#include "gui/theme.h"
+#include "gui/setup.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/playerbox.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+
+static const int BOX_WIDTH = 36;
+static const int BOX_HEIGHT = 36;
+
+// Positions of the boxes, 2nd dimension is X and Y respectively.
+static const int boxPosition[][2] =
+{
+ { 90, 40 }, // EQUIP_TORSO_SLOT
+ { 8, 78 }, // EQUIP_GLOVES_SLOT
+ { 70, 0 }, // EQUIP_HEAD_SLOT
+ { 50, 253 }, // EQUIP_LEGS_SLOT
+ { 90, 253 }, // EQUIP_FEET_SLOT
+ { 8, 213 }, // EQUIP_RING1_SLOT
+ { 129, 213 }, // EQUIP_RING2_SLOT
+ { 50, 40 }, // EQUIP_NECK_SLOT
+ { 8, 168 }, // EQUIP_FIGHT1_SLOT
+ { 129, 168 }, // EQUIP_FIGHT2_SLOT
+ { 129, 78 }, // EQUIP_PROJECTILE_SLOT
+ { 8, 123 }, // EQUIP_EVOL_RING1_SLOT
+ { 129, 123 }, // EQUIP_EVOL_RING2_SLOT
+};
+
+EquipmentWindow::EquipmentWindow(Equipment *equipment):
+ Window(_("Equipment")),
+ mEquipment(equipment),
+ mSelected(-1)
+{
+ mItemPopup = new ItemPopup;
+ if (setupWindow)
+ setupWindow->registerWindowForReset(this);
+
+ // Control that shows the Player
+ PlayerBox *playerBox = new PlayerBox;
+ playerBox->setDimension(gcn::Rectangle(50, 80, 74, 168));
+ playerBox->setPlayer(player_node);
+
+ setWindowName("Equipment");
+ setCloseButton(true);
+ setSaveVisible(true);
+ setDefaultSize(180, 345, ImageRect::CENTER);
+ loadWindowState();
+
+ mUnequip = new Button(_("Unequip"), "unequip", this);
+ const gcn::Rectangle &area = getChildrenArea();
+ mUnequip->setPosition(area.width - mUnequip->getWidth() - 5,
+ area.height - mUnequip->getHeight() - 5);
+ mUnequip->setEnabled(false);
+
+ add(playerBox);
+ add(mUnequip);
+
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ mEquipBox[i].posX = boxPosition[i][0] + getPadding();
+ mEquipBox[i].posY = boxPosition[i][1] + getTitleBarHeight();
+ }
+}
+
+EquipmentWindow::~EquipmentWindow()
+{
+ delete mItemPopup;
+ mItemPopup = 0;
+}
+
+void EquipmentWindow::draw(gcn::Graphics *graphics)
+{
+ // Draw window graphics
+ Window::draw(graphics);
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ Window::drawChildren(graphics);
+
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ if (i == mSelected)
+ {
+ const gcn::Color color = Theme::getThemeColor(Theme::HIGHLIGHT);
+
+ // Set color to the highlight color
+ g->setColor(gcn::Color(color.r, color.g, color.b, getGuiAlpha()));
+ g->fillRectangle(gcn::Rectangle(mEquipBox[i].posX,
+ mEquipBox[i].posY, BOX_WIDTH, BOX_HEIGHT));
+ }
+
+ // Set color black
+ g->setColor(gcn::Color(0, 0, 0));
+ // Draw box border
+ g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
+ BOX_WIDTH, BOX_HEIGHT));
+
+ Item *item = mEquipment->getEquipment(i);
+ if (item)
+ {
+ // Draw Item.
+ Image *image = item->getImage();
+ if (image)
+ {
+ image->setAlpha(1.0f); // Ensure the image is drawn
+ // with maximum opacity
+ g->drawImage(image,
+ mEquipBox[i].posX + 2,
+ mEquipBox[i].posY + 2);
+ if (i == EQUIP_PROJECTILE_SLOT)
+ {
+ g->setColor(Theme::getThemeColor(Theme::TEXT));
+ graphics->drawText(toString(item->getQuantity()),
+ mEquipBox[i].posX + (BOX_WIDTH / 2),
+ mEquipBox[i].posY - getFont()->getHeight(),
+ gcn::Graphics::CENTER);
+ }
+ }
+ }
+ }
+}
+
+void EquipmentWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "unequip" && mSelected > -1)
+ {
+ Item *item = mEquipment->getEquipment(mSelected);
+ Net::getInventoryHandler()->unequipItem(item);
+ setSelected(-1);
+ }
+}
+
+Item *EquipmentWindow::getItem(int x, int y) const
+{
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
+ BOX_WIDTH, BOX_HEIGHT);
+
+ if (tRect.isPointInRect(x, y))
+ return mEquipment->getEquipment(i);
+ }
+ return NULL;
+}
+
+void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
+{
+ Window::mousePressed(mouseEvent);
+
+ const int x = mouseEvent.getX();
+ const int y = mouseEvent.getY();
+
+ if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
+ {
+ // Checks if any of the presses were in the equip boxes.
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ Item *item = mEquipment->getEquipment(i);
+ gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
+ BOX_WIDTH, BOX_HEIGHT);
+
+ if (tRect.isPointInRect(x, y) && item)
+ setSelected(i);
+ }
+ }
+ else if (mouseEvent.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ if (Item *item = getItem(x, y))
+ {
+ /* Convert relative to the window coordinates to absolute screen
+ * coordinates.
+ */
+ const int mx = x + getX();
+ const int my = y + getY();
+ if (viewport)
+ viewport->showPopup(this, mx, my, item, true);
+ }
+ }
+}
+
+// Show ItemTooltip
+void EquipmentWindow::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!mItemPopup)
+ return;
+
+ const int x = event.getX();
+ const int y = event.getY();
+
+ Item *item = getItem(x, y);
+
+ if (item)
+ {
+ int mouseX, mouseY;
+ SDL_GetMouseState(&mouseX, &mouseY);
+
+ mItemPopup->setItem(item);
+ mItemPopup->position(x + getX(), y + getY());
+ }
+ else
+ {
+ mItemPopup->setVisible(false);
+ }
+}
+
+// Hide ItemTooltip
+void EquipmentWindow::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ if (mItemPopup)
+ mItemPopup->setVisible(false);
+}
+
+void EquipmentWindow::setSelected(int index)
+{
+ mSelected = index;
+ if (mUnequip)
+ mUnequip->setEnabled(mSelected != -1);
+}
diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h
new file mode 100644
index 000000000..d80535ed6
--- /dev/null
+++ b/src/gui/equipmentwindow.h
@@ -0,0 +1,98 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EQUIPMENTWINDOW_H
+#define EQUIPMENTWINDOW_H
+
+#include "equipment.h"
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Inventory;
+class Item;
+class ItemPopup;
+
+/**
+ * Equipment dialog.
+ *
+ * \ingroup Interface
+ */
+class EquipmentWindow : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ EquipmentWindow(Equipment *equipment);
+
+ /**
+ * Destructor.
+ */
+ ~EquipmentWindow();
+
+ /**
+ * Draws the equipment window.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ void action(const gcn::ActionEvent &event);
+
+ void mousePressed(gcn::MouseEvent& mouseEvent);
+
+ private:
+ void mouseExited(gcn::MouseEvent &event);
+ void mouseMoved(gcn::MouseEvent &event);
+
+ Item *getItem(int x, int y) const;
+
+ void setSelected(int index);
+
+ Equipment *mEquipment;
+
+ /**
+ * Equipment box.
+ */
+ struct EquipBox
+ {
+ int posX;
+ int posY;
+ };
+
+ EquipBox mEquipBox[Equipment::EQUIP_VECTOREND]; /**<Equipment Boxes. */
+
+ ItemPopup *mItemPopup;
+ gcn::Button *mUnequip;
+
+ int mSelected; /**< Index of selected item. */
+};
+
+extern EquipmentWindow *equipmentWindow;
+
+#endif
diff --git a/src/gui/focushandler.cpp b/src/gui/focushandler.cpp
new file mode 100644
index 000000000..9a2a244cc
--- /dev/null
+++ b/src/gui/focushandler.cpp
@@ -0,0 +1,99 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "focushandler.h"
+
+#include "gui/widgets/window.h"
+
+void FocusHandler::requestModalFocus(gcn::Widget *widget)
+{
+ /* If there is another widget with modal focus, remove its modal focus
+ * and put it on the modal widget stack.
+ */
+ if (mModalFocusedWidget && mModalFocusedWidget != widget)
+ {
+ mModalStack.push_front(mModalFocusedWidget);
+ mModalFocusedWidget = NULL;
+ }
+
+ gcn::FocusHandler::requestModalFocus(widget);
+}
+
+void FocusHandler::releaseModalFocus(gcn::Widget *widget)
+{
+ mModalStack.remove(widget);
+
+ if (mModalFocusedWidget == widget)
+ {
+ gcn::FocusHandler::releaseModalFocus(widget);
+
+ /* Check if there were any previously modal widgets that'd still like
+ * to regain their modal focus.
+ */
+ if (!mModalStack.empty())
+ {
+ gcn::FocusHandler::requestModalFocus(mModalStack.front());
+ mModalStack.pop_front();
+ }
+ }
+}
+
+void FocusHandler::remove(gcn::Widget *widget)
+{
+ releaseModalFocus(widget);
+
+ gcn::FocusHandler::remove(widget);
+}
+
+void FocusHandler::tabNext()
+{
+ gcn::FocusHandler::tabNext();
+
+ checkForWindow();
+}
+
+void FocusHandler::tabPrevious()
+{
+ gcn::FocusHandler::tabPrevious();
+
+ checkForWindow();
+}
+
+void FocusHandler::checkForWindow()
+{
+ if (mFocusedWidget)
+ {
+ gcn::Widget *widget = mFocusedWidget->getParent();
+
+ while (widget)
+ {
+ Window *window = dynamic_cast<Window*>(widget);
+
+ if (window)
+ {
+ window->requestMoveToTop();
+ break;
+ }
+
+ widget = widget->getParent();
+ }
+ }
+}
diff --git a/src/gui/focushandler.h b/src/gui/focushandler.h
new file mode 100644
index 000000000..f933323ae
--- /dev/null
+++ b/src/gui/focushandler.h
@@ -0,0 +1,77 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef FOCUSHANDLER_H
+#define FOCUSHANDLER_H
+
+#include <guichan/focushandler.hpp>
+
+#include <list>
+
+/**
+ * The focus handler. This focus handler does exactly the same as the Guichan
+ * focus handler, but keeps a stack of modal widgets to be able to handle
+ * multiple modal focus requests.
+ */
+class FocusHandler : public gcn::FocusHandler
+{
+ public:
+ /**
+ * Sets modal focus to a widget. When there is already a modal widget
+ * then that widget loses modal focus and will regain it after this
+ * widget releases his modal focus.
+ */
+ void requestModalFocus(gcn::Widget *widget);
+
+ /**
+ * Releases modal focus of a widget. When this widget had modal focus
+ * and there are other widgets that had also requested modal focus,
+ * then modal focus will be transfered to the last of those.
+ */
+ void releaseModalFocus(gcn::Widget *widget);
+
+ /**
+ * Removes a widget from the focus handler. Also makes sure no dangling
+ * pointers remain in modal focus stack.
+ */
+ void remove(gcn::Widget *widget);
+
+ /**
+ * Overloaded to allow windows to move to the top when one of their
+ * widgets is tabbed to when tabbing through focusable elements.
+ */
+ void tabNext();
+ void tabPrevious();
+
+ private:
+ /**
+ * Checks to see if the widget tabbed to is in a window, and if it is,
+ * it requests the window be moved to the top.
+ */
+ void checkForWindow();
+
+ /**
+ * Stack of widgets that have requested modal forcus.
+ */
+ std::list<gcn::Widget*> mModalStack;
+};
+
+#endif
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
new file mode 100644
index 000000000..57a94b3d1
--- /dev/null
+++ b/src/gui/gui.cpp
@@ -0,0 +1,310 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/gui.h"
+
+#include "gui/focushandler.h"
+#include "gui/palette.h"
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+#include "gui/truetypefont.h"
+
+#include "gui/widgets/window.h"
+#include "gui/widgets/windowcontainer.h"
+
+#include "configlistener.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/imageloader.h"
+#include "resources/resourcemanager.h"
+
+#include <guichan/exception.hpp>
+#include <guichan/image.hpp>
+
+// Guichan stuff
+Gui *gui = 0;
+SDLInput *guiInput = 0;
+
+// Bolded font
+gcn::Font *boldFont = 0;
+
+class GuiConfigListener : public ConfigListener
+{
+ public:
+ GuiConfigListener(Gui *g):
+ mGui(g)
+ {}
+
+ void optionChanged(const std::string &name)
+ {
+ if (name == "customcursor" && mGui)
+ {
+ bool bCustomCursor = config.getBoolValue("customcursor");
+ mGui->setUseCustomCursor(bCustomCursor);
+ }
+ }
+ private:
+ Gui *mGui;
+};
+
+Gui::Gui(Graphics *graphics):
+ mCustomCursor(false),
+ mMouseCursors(NULL),
+ mMouseCursorAlpha(1.0f),
+ mMouseInactivityTimer(0),
+ mCursorType(CURSOR_POINTER)
+{
+ logger->log1("Initializing GUI...");
+ // Set graphics
+ setGraphics(graphics);
+
+ // Set image loader
+ static ImageLoader imageLoader;
+ gcn::Image::setImageLoader(&imageLoader);
+
+ // Set input
+ guiInput = new SDLInput;
+ setInput(guiInput);
+
+ // Set focus handler
+ delete mFocusHandler;
+ mFocusHandler = new FocusHandler;
+
+ // Initialize top GUI widget
+ WindowContainer *guiTop = new WindowContainer;
+ guiTop->setFocusable(true);
+ guiTop->setDimension(gcn::Rectangle(0, 0,
+ graphics->getWidth(), graphics->getHeight()));
+ guiTop->setOpaque(false);
+ Window::setWindowContainer(guiTop);
+ setTop(guiTop);
+
+ // Set global font
+ const int fontSize = config.getIntValue("fontSize");
+ std::string fontFile = config.getValue("font", "");
+// may be here need get paths from paths.getValue?
+// std::string path = resman->getPath(fontFile);
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("font");
+
+ try
+ {
+ mGuiFont = new TrueTypeFont(fontFile, fontSize);
+ }
+ catch (gcn::Exception e)
+ {
+ logger->error(std::string("Unable to load '") + fontFile +
+ std::string("': ") + e.getMessage());
+ }
+
+ // Set particle font
+ fontFile = config.getValue("particleFont", "");
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("particleFont");
+
+ try
+ {
+ mInfoParticleFont = new TrueTypeFont(
+ fontFile, fontSize, TTF_STYLE_BOLD);
+ }
+ catch (gcn::Exception e)
+ {
+ logger->error(std::string("Unable to load '") + fontFile +
+ std::string("': ") + e.getMessage());
+ }
+
+ // Set bold font
+ fontFile = config.getValue("boldFont", "");
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("boldFont");
+
+ try
+ {
+ boldFont = new TrueTypeFont(fontFile, fontSize);
+ }
+ catch (gcn::Exception e)
+ {
+ logger->error(std::string("Unable to load '") + fontFile +
+ std::string("': ") + e.getMessage());
+ }
+
+ // Set help font
+ fontFile = config.getValue("helpFont", "");
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("helpFont");
+
+ try
+ {
+ mHelpFont = new TrueTypeFont(fontFile, fontSize);
+ }
+ catch (gcn::Exception e)
+ {
+ logger->error(std::string("Unable to load '") + fontFile +
+ std::string("': ") + e.getMessage());
+ }
+
+ gcn::Widget::setGlobalFont(mGuiFont);
+
+ // Initialize mouse cursor and listen for changes to the option
+ setUseCustomCursor(config.getBoolValue("customcursor"));
+ mConfigListener = new GuiConfigListener(this);
+ config.addListener("customcursor", mConfigListener);
+}
+
+Gui::~Gui()
+{
+ config.removeListener("customcursor", mConfigListener);
+ delete mConfigListener;
+ mConfigListener = 0;
+
+ if (mMouseCursors)
+ {
+ mMouseCursors->decRef();
+ mMouseCursors = 0;
+ }
+
+ delete mGuiFont;
+ mGuiFont = 0;
+ delete boldFont;
+ boldFont = 0;
+ delete mHelpFont;
+ mHelpFont = 0;
+ delete mInfoParticleFont;
+ mInfoParticleFont = 0;
+ delete getTop();
+
+ delete guiInput;
+ guiInput = 0;
+
+ Theme::deleteInstance();
+}
+
+void Gui::logic()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ resman->clearScheduled();
+
+ // Fade out mouse cursor after extended inactivity
+ if (mMouseInactivityTimer < 100 * 15)
+ {
+ ++mMouseInactivityTimer;
+ mMouseCursorAlpha = std::min(1.0f, mMouseCursorAlpha + 0.05f);
+ }
+ else
+ {
+ mMouseCursorAlpha = std::max(0.0f, mMouseCursorAlpha - 0.005f);
+ }
+
+ Palette::advanceGradients();
+
+ gcn::Gui::logic();
+}
+
+void Gui::draw()
+{
+ mGraphics->pushClipArea(getTop()->getDimension());
+ getTop()->draw(mGraphics);
+
+ int mouseX, mouseY;
+ Uint8 button = SDL_GetMouseState(&mouseX, &mouseY);
+
+ if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1))
+ && mMouseCursors && mCustomCursor && mMouseCursorAlpha > 0.0f)
+ {
+ Image *mouseCursor = mMouseCursors->get(mCursorType);
+ if (mouseCursor)
+ {
+ mouseCursor->setAlpha(mMouseCursorAlpha);
+
+ static_cast<Graphics*>(mGraphics)->drawImage(
+ mouseCursor,
+ mouseX - 15,
+ mouseY - 17);
+ }
+ }
+
+ mGraphics->popClipArea();
+}
+
+void Gui::setUseCustomCursor(bool customCursor)
+{
+ if (customCursor != mCustomCursor)
+ {
+ mCustomCursor = customCursor;
+
+ if (mCustomCursor)
+ {
+ // Hide the SDL mouse cursor
+ SDL_ShowCursor(SDL_DISABLE);
+
+ // Load the mouse cursor
+ mMouseCursors = Theme::getImageSetFromTheme("mouse.png", 40, 40);
+
+ if (!mMouseCursors)
+ logger->log("Error: Unable to load mouse cursors.");
+ }
+ else
+ {
+ // Show the SDL mouse cursor
+ SDL_ShowCursor(SDL_ENABLE);
+
+ // Unload the mouse cursor
+ if (mMouseCursors)
+ {
+ mMouseCursors->decRef();
+ mMouseCursors = NULL;
+ }
+ }
+ }
+}
+
+void Gui::handleMouseMoved(const gcn::MouseInput &mouseInput)
+{
+ gcn::Gui::handleMouseMoved(mouseInput);
+ mMouseInactivityTimer = 0;
+}
+
+void Gui::updateFonts()
+{
+ const int fontSize = config.getIntValue("fontSize");
+ std::string fontFile = config.getValue("font", "");
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("font");
+
+ static_cast<TrueTypeFont*>(mGuiFont)->loadFont(fontFile, fontSize);
+
+ fontFile = config.getValue("particleFont", "");
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("particleFont");
+
+ static_cast<TrueTypeFont*>(mInfoParticleFont)->loadFont(
+ fontFile, fontSize, TTF_STYLE_BOLD);
+
+ fontFile = config.getValue("boldFont", "");
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("boldFont");
+
+ static_cast<TrueTypeFont*>(boldFont)->loadFont(fontFile, fontSize);
+}
diff --git a/src/gui/gui.h b/src/gui/gui.h
new file mode 100644
index 000000000..b4ddfc299
--- /dev/null
+++ b/src/gui/gui.h
@@ -0,0 +1,148 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_H
+#define GUI_H
+
+#include "guichanfwd.h"
+
+#include <guichan/gui.hpp>
+
+class Graphics;
+class GuiConfigListener;
+class ImageSet;
+class SDLInput;
+
+/**
+ * \defgroup GUI Core GUI related classes (widgets)
+ */
+
+/**
+ * \defgroup Interface User interface related classes (windows, dialogs)
+ */
+
+/**
+ * Main GUI class.
+ *
+ * \ingroup GUI
+ */
+class Gui : public gcn::Gui
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Gui(Graphics *screen);
+
+ /**
+ * Destructor.
+ */
+ ~Gui();
+
+ /**
+ * Performs logic of the GUI. Overridden to track mouse pointer
+ * activity.
+ */
+ void logic();
+
+ /**
+ * Draws the whole Gui by calling draw functions down in the
+ * Gui hierarchy. It also draws the mouse pointer.
+ */
+ void draw();
+
+ gcn::FocusHandler *getFocusHandler() const
+ { return mFocusHandler; }
+
+ /**
+ * Return game font.
+ */
+ gcn::Font *getFont() const
+ { return mGuiFont; }
+
+ /**
+ * Return help font.
+ */
+ gcn::Font *getHelpFont() const
+ { return mHelpFont; }
+
+ /**
+ * Return the Font used for "Info Particles", i.e. ones showing, what
+ * you picked up, etc.
+ */
+ gcn::Font *getInfoParticleFont() const
+ { return mInfoParticleFont; }
+
+ /**
+ * Sets whether a custom cursor should be rendered.
+ */
+ void setUseCustomCursor(bool customCursor);
+
+ /**
+ * Sets which cursor should be used.
+ */
+ void setCursorType(int index)
+ { mCursorType = index; }
+
+ void updateFonts();
+
+ /**
+ * Cursors are in graphic order from left to right.
+ * CURSOR_POINTER should be left untouched.
+ * CURSOR_TOTAL should always be last.
+ */
+ enum
+ {
+ CURSOR_POINTER = 0,
+ CURSOR_RESIZE_ACROSS,
+ CURSOR_RESIZE_DOWN,
+ CURSOR_RESIZE_DOWN_LEFT,
+ CURSOR_RESIZE_DOWN_RIGHT,
+ CURSOR_FIGHT,
+ CURSOR_PICKUP,
+ CURSOR_TALK,
+ CURSOR_TOTAL
+ };
+
+ protected:
+ void handleMouseMoved(const gcn::MouseInput &mouseInput);
+
+ private:
+ GuiConfigListener *mConfigListener;
+ gcn::Font *mGuiFont; /**< The global GUI font */
+ gcn::Font *mInfoParticleFont; /**< Font for Info Particles*/
+ gcn::Font *mHelpFont; /**< Font for Help Window*/
+ bool mCustomCursor; /**< Show custom cursor */
+ ImageSet *mMouseCursors; /**< Mouse cursor images */
+ float mMouseCursorAlpha;
+ int mMouseInactivityTimer;
+ int mCursorType;
+};
+
+extern Gui *gui; /**< The GUI system */
+extern SDLInput *guiInput; /**< GUI input */
+
+/**
+ * Bolded text font
+ */
+extern gcn::Font *boldFont;
+
+#endif // GUI_H
diff --git a/src/gui/help.cpp b/src/gui/help.cpp
new file mode 100644
index 000000000..aa114b99f
--- /dev/null
+++ b/src/gui/help.cpp
@@ -0,0 +1,106 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/help.h"
+
+#include "gui/gui.h"
+#include "gui/setup.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/scrollarea.h"
+
+#include "resources/resourcemanager.h"
+#include "configuration.h"
+
+#include "utils/gettext.h"
+
+HelpWindow::HelpWindow():
+ Window(_("Help"))
+{
+ setMinWidth(300);
+ setMinHeight(250);
+ setContentSize(455, 350);
+ setWindowName("Help");
+ setResizable(true);
+ setupWindow->registerWindowForReset(this);
+
+ setDefaultSize(500, 400, ImageRect::CENTER);
+
+ mBrowserBox = new BrowserBox;
+ mBrowserBox->setOpaque(false);
+ mScrollArea = new ScrollArea(mBrowserBox);
+ Button *okButton = new Button(_("Close"), "close", this);
+
+ mScrollArea->setDimension(gcn::Rectangle(5, 5, 445,
+ 335 - okButton->getHeight()));
+ okButton->setPosition(450 - okButton->getWidth(),
+ 345 - okButton->getHeight());
+
+ mBrowserBox->setLinkHandler(this);
+ mBrowserBox->setFont(gui->getHelpFont());
+
+ place(0, 0, mScrollArea, 5, 3).setPadding(3);
+ place(4, 3, okButton);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+
+ loadWindowState();
+}
+
+void HelpWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "close")
+ setVisible(false);
+}
+
+void HelpWindow::handleLink(const std::string &link,
+ gcn::MouseEvent *event _UNUSED_)
+{
+ std::string helpFile = link;
+ loadHelp(helpFile);
+}
+
+void HelpWindow::loadHelp(const std::string &helpFile)
+{
+ mBrowserBox->clearRows();
+
+ loadFile("header");
+ loadFile(helpFile);
+
+ mScrollArea->setVerticalScrollAmount(0);
+ setVisible(true);
+}
+
+void HelpWindow::loadFile(const std::string &file)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ std::string helpPath = branding.getStringValue("helpPath");
+ if (helpPath.empty())
+ helpPath = paths.getStringValue("help");
+ std::vector<std::string> lines =
+ resman->loadTextFile(helpPath + file + ".txt");
+
+ for (unsigned int i = 0; i < lines.size(); ++i)
+ mBrowserBox->addRow(lines[i]);
+}
diff --git a/src/gui/help.h b/src/gui/help.h
new file mode 100644
index 000000000..fe5cb9fe7
--- /dev/null
+++ b/src/gui/help.h
@@ -0,0 +1,76 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef HELP_H
+#define HELP_H
+
+#include "gui/widgets/linkhandler.h"
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class BrowserBox;
+class LinkHandler;
+
+/**
+ * The help dialog.
+ */
+class HelpWindow : public Window, public LinkHandler,
+ public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ HelpWindow();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Handles link action.
+ */
+ void handleLink(const std::string &link,
+ gcn::MouseEvent *event _UNUSED_);
+
+ /**
+ * Loads help in the dialog.
+ */
+ void loadHelp(const std::string &helpFile);
+
+ private:
+ void loadFile(const std::string &file);
+
+ BrowserBox *mBrowserBox;
+ gcn::ScrollArea *mScrollArea;
+};
+
+extern HelpWindow *helpWindow;
+
+#endif
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
new file mode 100644
index 000000000..abb702005
--- /dev/null
+++ b/src/gui/inventorywindow.cpp
@@ -0,0 +1,503 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/inventorywindow.h"
+
+#include "inventory.h"
+#include "item.h"
+#include "units.h"
+#include "keyboardconfig.h"
+#include "playerinfo.h"
+
+#include "gui/itemamount.h"
+#include "gui/setup.h"
+#include "gui/sdlinput.h"
+#include "gui/shopwindow.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/itemcontainer.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/progressbar.h"
+#include "gui/widgets/scrollarea.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "resources/iteminfo.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+#include <guichan/mouseinput.hpp>
+
+#include <string>
+
+InventoryWindow::WindowList InventoryWindow::instances;
+
+InventoryWindow::InventoryWindow(Inventory *inventory):
+ Window(inventory ? (inventory->isMainInventory()
+ ? _("Inventory") : _("Storage")) : _("Inventory")),
+ mInventory(inventory),
+ mDropButton(0),
+ mSplit(false)
+{
+ listen(CHANNEL_ATTRIBUTES);
+
+ setWindowName(isMainInventory() ? "Inventory" : "Storage");
+
+ if (setupWindow)
+ setupWindow->registerWindowForReset(this);
+
+ setResizable(true);
+ setCloseButton(true);
+ setSaveVisible(true);
+
+ setDefaultSize(387, 307, ImageRect::CENTER);
+ setMinWidth(316);
+ setMinHeight(179);
+ addKeyListener(this);
+
+ mItems = new ItemContainer(mInventory);
+ mItems->addSelectionListener(this);
+
+ gcn::ScrollArea *invenScroll = new ScrollArea(mItems);
+ invenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mSlotsLabel = new Label(_("Slots:"));
+ mSlotsBar = new ProgressBar(0.0f, 100, 20, Theme::PROG_INVY_SLOTS);
+
+ if (isMainInventory())
+ {
+ std::string equip = _("Equip");
+ std::string use = _("Use");
+ std::string unequip = _("Unequip");
+
+ std::string longestUseString = getFont()->getWidth(equip) >
+ getFont()->getWidth(use) ? equip : use;
+
+ if (getFont()->getWidth(longestUseString) <
+ getFont()->getWidth(unequip))
+ {
+ longestUseString = unequip;
+ }
+
+ mUseButton = new Button(longestUseString, "use", this);
+ mUseButton2 = new Button(longestUseString, "equip", this);
+ mDropButton = new Button(_("Drop..."), "drop", this);
+ mSplitButton = new Button(_("Split"), "split", this);
+ mOutfitButton = new Button(_("Outfits"), "outfit", this);
+ mShopButton = new Button(_("Shop"), "shop", this);
+
+ mWeightLabel = new Label(_("Weight:"));
+ mWeightBar = new ProgressBar(0.0f, 100, 20, Theme::PROG_WEIGHT);
+
+ place(0, 0, mWeightLabel).setPadding(3);
+ place(1, 0, mWeightBar, 3);
+ place(4, 0, mSlotsLabel).setPadding(3);
+ place(5, 0, mSlotsBar, 2);
+ place(0, 1, invenScroll, 7).setPadding(3);
+ place(0, 2, mUseButton);
+ place(1, 2, mUseButton2);
+ place(2, 2, mDropButton);
+ place(4, 2, mSplitButton);
+ place(5, 2, mShopButton);
+ place(6, 2, mOutfitButton);
+
+ updateWeight();
+ }
+ else
+ {
+ mStoreButton = new Button(_("Store"), "store", this);
+ mRetrieveButton = new Button(_("Retrieve"), "retrieve", this);
+ mCloseButton = new Button(_("Close"), "close", this);
+
+ place(0, 0, mSlotsLabel).setPadding(3);
+ place(1, 0, mSlotsBar, 3);
+ place(0, 1, invenScroll, 4, 4);
+ place(0, 5, mStoreButton);
+ place(1, 5, mRetrieveButton);
+ place(3, 5, mCloseButton);
+ }
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(1, Layout::AUTO_SET);
+
+ mInventory->addInventoyListener(this);
+
+ instances.push_back(this);
+
+ if (inventory->isMainInventory())
+ {
+ updateDropButton();
+ }
+ else
+ {
+ if (!instances.empty())
+ instances.front()->updateDropButton();
+ }
+
+ loadWindowState();
+ slotsChanged(mInventory);
+
+ if (!isMainInventory())
+ setVisible(true);
+}
+
+InventoryWindow::~InventoryWindow()
+{
+ instances.remove(this);
+ mInventory->removeInventoyListener(this);
+ if (!instances.empty())
+ instances.front()->updateDropButton();
+}
+
+void InventoryWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "outfit")
+ {
+ extern Window *outfitWindow;
+ if (outfitWindow)
+ {
+ outfitWindow->setVisible(!outfitWindow->isVisible());
+ if (outfitWindow->isVisible())
+ outfitWindow->requestMoveToTop();
+ }
+ }
+
+ if (event.getId() == "shop")
+ {
+ if (shopWindow)
+ {
+ shopWindow->setVisible(!shopWindow->isVisible());
+ if (shopWindow->isVisible())
+ shopWindow->requestMoveToTop();
+ }
+ }
+ else if (event.getId() == "close")
+ {
+ close();
+ }
+ else if (event.getId() == "store")
+ {
+ if (!inventoryWindow || !inventoryWindow->isVisible())
+ return;
+
+ Item *item = inventoryWindow->getSelectedItem();
+
+ if (!item)
+ return;
+
+ ItemAmountWindow::showWindow(ItemAmountWindow::StoreAdd, this, item);
+ }
+
+ Item *item = mItems->getSelectedItem();
+
+ if (!item)
+ return;
+
+ if (event.getId() == "use")
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ else
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ else
+ Net::getInventoryHandler()->useItem(item);
+ }
+ if (event.getId() == "equip")
+ {
+ if (!item->isEquipment())
+ {
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ else
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ else
+ Net::getInventoryHandler()->useItem(item);
+ }
+ else if (event.getId() == "drop")
+ {
+ if (isStorageActive())
+ {
+ Item *item = mItems->getSelectedItem();
+
+ if (!item)
+ return;
+
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ item->getInvIndex(), item->getQuantity(),
+ Inventory::STORAGE);
+ }
+ else
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemDrop,
+ this, item);
+ }
+ }
+ else if (event.getId() == "split")
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit, this, item,
+ (item->getQuantity() - 1));
+ }
+ else if (event.getId() == "retrieve")
+ {
+ Item *item = mItems->getSelectedItem();
+
+ if (!item)
+ return;
+
+ ItemAmountWindow::showWindow(ItemAmountWindow::StoreRemove, this,
+ item);
+ }
+}
+
+Item *InventoryWindow::getSelectedItem() const
+{
+ return mItems->getSelectedItem();
+}
+
+void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
+{
+ Window::mouseClicked(event);
+
+ if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ Item *item = mItems->getSelectedItem();
+
+ if (!item)
+ return;
+
+ /* Convert relative to the window coordinates to absolute screen
+ * coordinates.
+ */
+ const int mx = event.getX() + getX();
+ const int my = event.getY() + getY();
+
+ if (viewport)
+ viewport->showPopup(this, mx, my, item, isMainInventory());
+ }
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (isStorageActive() && keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ {
+ Item *item = mItems->getSelectedItem();
+
+ if (!item || !mInventory)
+ return;
+
+ if (mInventory->isMainInventory())
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ item->getInvIndex(), item->getQuantity(),
+ Inventory::STORAGE);
+ }
+ else
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ item->getInvIndex(), item->getQuantity(),
+ Inventory::INVENTORY);
+ }
+ }
+ }
+}
+
+void InventoryWindow::keyPressed(gcn::KeyEvent &event)
+{
+ switch (event.getKey().getValue())
+ {
+ case Key::LEFT_SHIFT:
+ case Key::RIGHT_SHIFT:
+ mSplit = true;
+ break;
+ default:
+ break;
+ }
+}
+
+void InventoryWindow::keyReleased(gcn::KeyEvent &event)
+{
+ switch (event.getKey().getValue())
+ {
+ case Key::LEFT_SHIFT:
+ case Key::RIGHT_SHIFT:
+ mSplit = false;
+ break;
+ default:
+ break;
+ }
+}
+
+void InventoryWindow::valueChanged(const gcn::SelectionEvent &event _UNUSED_)
+{
+ if (!mInventory || !mInventory->isMainInventory())
+ return;
+
+ Item *item = mItems->getSelectedItem();
+
+ if (mSplit && item && Net::getInventoryHandler()->
+ canSplit(mItems->getSelectedItem()))
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit, this, item,
+ (item->getQuantity() - 1));
+ }
+
+ if (!item || item->getQuantity() == 0)
+ {
+ if (mUseButton)
+ mUseButton->setEnabled(true);
+ if (mUseButton2)
+ mUseButton2->setEnabled(true);
+ if (mDropButton)
+ mDropButton->setEnabled(true);
+ return;
+ }
+
+ if (mUseButton)
+ mUseButton->setEnabled(true);
+ if (mUseButton2)
+ mUseButton2->setEnabled(true);
+ if (mDropButton)
+ mDropButton->setEnabled(true);
+
+ if (mUseButton && item && item->isEquipment())
+ {
+ if (item->isEquipped())
+ mUseButton->setCaption(_("Unequip"));
+ else
+ mUseButton->setCaption(_("Equip"));
+ mUseButton2->setCaption(_("Use"));
+ }
+ else if (mUseButton2)
+ {
+ mUseButton->setCaption(_("Use"));
+ if (item->isEquipped())
+ mUseButton2->setCaption(_("Unequip"));
+ else
+ mUseButton2->setCaption(_("Equip"));
+ }
+
+ updateDropButton();
+
+ if (mSplitButton)
+ {
+ if (Net::getInventoryHandler()->canSplit(item))
+ mSplitButton->setEnabled(true);
+ else
+ mSplitButton->setEnabled(false);
+ }
+}
+
+
+void InventoryWindow::setSplitAllowed(bool allowed)
+{
+ mSplitButton->setVisible(allowed);
+}
+
+void InventoryWindow::close()
+{
+ if (this == inventoryWindow)
+ {
+ setVisible(false);
+ }
+ else
+ {
+ Net::getInventoryHandler()->closeStorage(Inventory::STORAGE);
+ scheduleDelete();
+ }
+}
+
+void InventoryWindow::event(Channels channel _UNUSED_,
+ const Mana::Event &event)
+{
+ if (event.getName() == EVENT_UPDATEATTRIBUTE)
+ {
+ int id = event.getInt("id");
+ if (id == TOTAL_WEIGHT || id == MAX_WEIGHT)
+ updateWeight();
+ }
+}
+
+void InventoryWindow::updateWeight()
+{
+ if (!isMainInventory())
+ return;
+
+ int total = PlayerInfo::getAttribute(TOTAL_WEIGHT);
+ int max = PlayerInfo::getAttribute(MAX_WEIGHT);
+
+ if (max <= 0)
+ return;
+
+ // Adjust progress bar
+ mWeightBar->setProgress(static_cast<float>(total)
+ / static_cast<float>(max));
+ mWeightBar->setText(strprintf("%s/%s", Units::formatWeight(total).c_str(),
+ Units::formatWeight(max).c_str()));
+}
+
+void InventoryWindow::slotsChanged(Inventory* inventory)
+{
+ if (inventory == mInventory)
+ {
+ const int usedSlots = mInventory->getNumberOfSlotsUsed();
+ const int maxSlots = mInventory->getSize();
+
+ if (maxSlots)
+ {
+ mSlotsBar->setProgress(static_cast<float>(usedSlots)
+ / static_cast<float>(maxSlots));
+ }
+
+ mSlotsBar->setText(strprintf("%d/%d", usedSlots, maxSlots));
+ }
+}
+
+void InventoryWindow::updateDropButton()
+{
+ if (!mDropButton)
+ return;
+
+ if (isStorageActive())
+ {
+ mDropButton->setCaption(_("Store"));
+ }
+ else
+ {
+ Item *item = 0;
+ if (mItems)
+ item = mItems->getSelectedItem();
+
+ if (item && item->getQuantity() > 1)
+ mDropButton->setCaption(_("Drop..."));
+ else
+ mDropButton->setCaption(_("Drop"));
+ }
+}
diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h
new file mode 100644
index 000000000..87f57eb9d
--- /dev/null
+++ b/src/gui/inventorywindow.h
@@ -0,0 +1,155 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef INVENTORYWINDOW_H
+#define INVENTORYWINDOW_H
+
+#include "inventory.h"
+#include "listener.h"
+
+#include "gui/widgets/window.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Item;
+class ItemContainer;
+class ProgressBar;
+class TextBox;
+
+/**
+ * Inventory dialog.
+ *
+ * \ingroup Interface
+ */
+class InventoryWindow : public Window,
+ public gcn::ActionListener,
+ public gcn::KeyListener,
+ public gcn::SelectionListener,
+ public InventoryListener,
+ public Mana::Listener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ InventoryWindow(Inventory *inventory);
+
+ /**
+ * Destructor.
+ */
+ ~InventoryWindow();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Returns the selected item.
+ */
+ Item* getSelectedItem() const;
+
+ /**
+ * Handles the mouse clicks.
+ */
+ void mouseClicked(gcn::MouseEvent &event);
+
+ /**
+ * Handles the key presses.
+ */
+ void keyPressed(gcn::KeyEvent &event);
+
+ /**
+ * Handles the key releases.
+ */
+ void keyReleased(gcn::KeyEvent &event);
+
+ /**
+ * Updates labels to currently selected item.
+ */
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ /**
+ * Sets whether the split button should be shown.
+ */
+ void setSplitAllowed(bool allowed);
+
+ /**
+ * Closes the Storage Window, as well as telling the server that the
+ * window has been closed.
+ */
+ void close();
+
+ void slotsChanged(Inventory* inventory);
+
+ bool isMainInventory()
+ { return mInventory->isMainInventory(); }
+
+ /**
+ * Returns true if any instances exist.
+ */
+ static bool isStorageActive()
+ { return instances.size() > 1; }
+
+ void updateDropButton();
+
+ void event(Channels channel, const Mana::Event &event);
+
+ private:
+ /**
+ * Updates the weight bar.
+ */
+ void updateWeight();
+
+
+ typedef std::list<InventoryWindow*> WindowList;
+ static WindowList instances;
+
+ Inventory *mInventory;
+ ItemContainer *mItems;
+
+ std::string mWeight, mSlots;
+
+ gcn::Button *mUseButton, *mUseButton2, *mDropButton,
+ *mSplitButton, *mOutfitButton, *mShopButton,
+ *mStoreButton, *mRetrieveButton, *mCloseButton;
+
+ gcn::Label *mWeightLabel, *mSlotsLabel;
+
+ ProgressBar *mWeightBar, *mSlotsBar;
+
+ bool mSplit;
+};
+
+extern InventoryWindow *inventoryWindow;
+
+#endif
diff --git a/src/gui/itemamount.cpp b/src/gui/itemamount.cpp
new file mode 100644
index 000000000..25356823f
--- /dev/null
+++ b/src/gui/itemamount.cpp
@@ -0,0 +1,432 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/itemamount.h"
+
+#include "item.h"
+#include "keyboardconfig.h"
+
+#include "gui/trade.h"
+#include "net/inventoryhandler.h"
+#include "gui/itempopup.h"
+#include "net/net.h"
+#include "gui/shopwindow.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/dropdown.h"
+#include "gui/widgets/icon.h"
+#include "gui/widgets/inttextfield.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/slider.h"
+
+#include "resources/itemdb.h"
+
+#include "utils/gettext.h"
+
+#include <math.h>
+
+class ItemsModal : public gcn::ListModel
+{
+public:
+ ItemsModal()
+ {
+ std::map<int, ItemInfo*> info = ItemDB::getItemInfos();
+ std::list<std::string> tempStrings;
+
+ for (std::map<int, ItemInfo*>::const_iterator
+ i = info.begin(), i_end = info.end();
+ i != i_end; ++i)
+ {
+ if (i->first < 0)
+ continue;
+
+ ItemInfo info = (*i->second);
+ std::string name = info.getName();
+ if (name != "unnamed" && !info.getName().empty()
+ && info.getName() != "unnamed")
+ {
+ tempStrings.push_back(name);
+ }
+ }
+ tempStrings.sort();
+ for (std::list<std::string>::const_iterator i = tempStrings.begin(),
+ i_end = tempStrings.end(); i != i_end; ++i)
+ {
+ mStrings.push_back(*i);
+ }
+ }
+
+ virtual ~ItemsModal()
+ { }
+
+ virtual int getNumberOfElements()
+ {
+ return static_cast<int>(mStrings.size());
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i < 0 || i >= getNumberOfElements())
+ return _("???");
+
+ return mStrings.at(i);
+ }
+private:
+ std::vector<std::string> mStrings;
+};
+
+void ItemAmountWindow::finish(Item *item, int amount, int price, Usage usage)
+{
+ switch (usage)
+ {
+ case TradeAdd:
+ if (tradeWindow)
+ tradeWindow->tradeItem(item, amount);
+ break;
+ case ItemDrop:
+ Net::getInventoryHandler()->dropItem(item, amount);
+ break;
+ case ItemSplit:
+ Net::getInventoryHandler()->splitItem(item, amount);
+ break;
+ case StoreAdd:
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ item->getInvIndex(), amount,
+ Inventory::STORAGE);
+ break;
+ case StoreRemove:
+ Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ item->getInvIndex(), amount,
+ Inventory::INVENTORY);
+ break;
+ case ShopBuyAdd:
+ if (shopWindow)
+ shopWindow->addBuyItem(item, amount, price);
+ break;
+ case ShopSellAdd:
+ if (shopWindow)
+ shopWindow->addSellItem(item, amount, price);
+ break;
+ default:
+ break;
+ }
+}
+
+ItemAmountWindow::ItemAmountWindow(Usage usage, Window *parent, Item *item,
+ int maxRange):
+ Window("", true, parent),
+ mItemPriceTextField(0),
+ mGPLabel(0),
+ mItem(item),
+ mMax(maxRange),
+ mUsage(usage),
+ mItemPriceSlide(0),
+ mItemsModal(0),
+ mPrice(0)
+{
+ if (!mItem)
+ {
+ setVisible(false);
+ return;
+ }
+ if (usage == ShopBuyAdd)
+ mMax = 10000;
+ else if (!mMax)
+ mMax = mItem->getQuantity();
+
+ // Save keyboard state
+ mEnabledKeyboard = keyboard.isEnabled();
+ keyboard.setEnabled(false);
+
+ // Integer field
+ mItemAmountTextField = new IntTextField(1);
+ mItemAmountTextField->setRange(1, mMax);
+ mItemAmountTextField->setWidth(35);
+ mItemAmountTextField->addKeyListener(this);
+
+ // Slider
+ mItemAmountSlide = new Slider(1.0, mMax);
+ mItemAmountSlide->setHeight(10);
+ mItemAmountSlide->setActionEventId("slide");
+ mItemAmountSlide->addActionListener(this);
+
+ if (mUsage == ShopBuyAdd || mUsage == ShopSellAdd)
+ {
+ // Integer field
+ mItemPriceTextField = new IntTextField(1);
+ mItemPriceTextField->setRange(1, 10000000);
+ mItemPriceTextField->setWidth(35);
+ mItemPriceTextField->addKeyListener(this);
+
+ // Slider
+ mItemPriceSlide = new Slider(1.0, 10000000);
+ mItemPriceSlide->setHeight(10);
+ mItemPriceSlide->setActionEventId("slidePrice");
+ mItemPriceSlide->addActionListener(this);
+
+ mGPLabel = new Label(" GP");
+ }
+
+ if (mUsage == ShopBuyAdd)
+ {
+ mItemsModal = new ItemsModal;
+ mItemDropDown = new DropDown(mItemsModal);
+ mItemDropDown->setActionEventId("itemType");
+ mItemDropDown->addActionListener(this);
+ }
+
+ //Item icon
+ Image *image = item->getImage();
+ mItemIcon = new Icon(image);
+
+ // Buttons
+ Button *minusAmountButton = new Button(_("-"), "dec", this);
+ Button *plusAmountButton = new Button(_("+"), "inc", this);
+ Button *okButton = new Button(_("OK"), "ok", this);
+ Button *cancelButton = new Button(_("Cancel"), "cancel", this);
+ Button *addAllButton = new Button(_("All"), "all", this);
+
+ minusAmountButton->adjustSize();
+ minusAmountButton->setWidth(plusAmountButton->getWidth());
+
+ // Set positions
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+ int n = 0;
+ if (mUsage == ShopBuyAdd)
+ {
+ place(0, n, mItemDropDown, 8);
+ n++;
+ }
+ place(1, n, minusAmountButton);
+ place(2, n, mItemAmountTextField, 3);
+ place(5, n, plusAmountButton);
+ place(6, n, addAllButton);
+
+ place(0, n, mItemIcon, 1, 3);
+ place(1, n + 1, mItemAmountSlide, 7);
+
+ if (mUsage == ShopBuyAdd || mUsage == ShopSellAdd)
+ {
+ Button *minusPriceButton = new Button(_("-"), "decPrice", this);
+ Button *plusPriceButton = new Button(_("+"), "incPrice", this);
+ minusPriceButton->adjustSize();
+ minusPriceButton->setWidth(plusPriceButton->getWidth());
+
+ place(1, n + 2, minusPriceButton);
+ place(2, n + 2, mItemPriceTextField, 3);
+ place(5, n + 2, plusPriceButton);
+ place(6, n + 2, mGPLabel);
+
+ place(1, n + 3, mItemPriceSlide, 7);
+ place(4, n + 5, cancelButton);
+ place(5, n + 5, okButton);
+ }
+ else
+ {
+ place(4, n + 2, cancelButton);
+ place(5, n + 2, okButton);
+ }
+
+ reflowLayout(225, 0);
+
+ resetAmount();
+
+ switch (usage)
+ {
+ case TradeAdd:
+ setCaption(_("Select amount of items to trade."));
+ break;
+ case ItemDrop:
+ setCaption(_("Select amount of items to drop."));
+ break;
+ case StoreAdd:
+ setCaption(_("Select amount of items to store."));
+ break;
+ case StoreRemove:
+ setCaption(_("Select amount of items to retrieve."));
+ break;
+ case ItemSplit:
+ setCaption(_("Select amount of items to split."));
+ break;
+ case ShopBuyAdd:
+ setCaption(_("Add to buy shop."));
+ break;
+ case ShopSellAdd:
+ setCaption(_("Add to sell shop."));
+ break;
+ default:
+ setCaption(_("Unknown."));
+ break;
+ }
+
+ setLocationRelativeTo(getParentWindow());
+ setVisible(true);
+
+ mItemPopup = new ItemPopup;
+ mItemIcon->addMouseListener(this);
+}
+
+ItemAmountWindow::~ItemAmountWindow()
+{
+ delete mItemPopup;
+ mItemPopup = 0;
+}
+
+// Show ItemTooltip
+void ItemAmountWindow::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!viewport || !mItemPopup)
+ return;
+
+ if (event.getSource() == mItemIcon)
+ {
+ mItemPopup->setItem(mItem);
+ mItemPopup->position(viewport->getMouseX(), viewport->getMouseY());
+ }
+}
+
+// Hide ItemTooltip
+void ItemAmountWindow::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ if (mItemPopup)
+ mItemPopup->setVisible(false);
+}
+
+void ItemAmountWindow::resetAmount()
+{
+ mItemAmountTextField->setValue(1);
+}
+
+void ItemAmountWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ close();
+ return;
+ }
+ else if (event.getId() == "ok")
+ {
+ if (mItemPriceTextField)
+ {
+ finish(mItem, mItemAmountTextField->getValue(),
+ mItemPriceTextField->getValue(), mUsage);
+ }
+ else
+ {
+ finish(mItem, mItemAmountTextField->getValue(),
+ 0, mUsage);
+ }
+ close();
+ return;
+ }
+ else if (event.getId() == "itemType")
+ {
+ if (!mItemDropDown || !mItemsModal)
+ return;
+
+ std::string str = mItemsModal->getElementAt(
+ mItemDropDown->getSelected());
+ int id = ItemDB::get(str).getId();
+
+ mItem = new Item(id, 10000);
+
+ if (mUsage == ShopBuyAdd)
+ mMax = 10000;
+ else if (!mMax)
+ mMax = mItem->getQuantity();
+
+ Image *image = mItem->getImage();
+ mItemIcon->setImage(image);
+ }
+
+ int amount = mItemAmountTextField->getValue();
+
+ if (event.getId() == "inc" && amount < mMax)
+ amount++;
+ else if (event.getId() == "dec" && amount > 1)
+ amount--;
+ else if (event.getId() == "all")
+ amount = mMax;
+ else if (event.getId() == "slide")
+ amount = static_cast<int>(mItemAmountSlide->getValue());
+ mItemAmountTextField->setValue(amount);
+ mItemAmountSlide->setValue(amount);
+
+ if (mItemPriceTextField && mItemPriceSlide)
+ {
+ int price = 0;
+
+ if (mPrice > 7)
+ mPrice = 7;
+ else if (mPrice < 0)
+ mPrice = 0;
+
+ if (event.getId() == "incPrice")
+ {
+ mPrice++;
+ price = static_cast<int>(pow(10, mPrice));
+ }
+ else if (event.getId() == "decPrice")
+ {
+ mPrice--;
+ price = static_cast<int>(pow(10, mPrice));
+ }
+ else if (event.getId() == "slidePrice")
+ {
+ price = static_cast<int>(mItemPriceSlide->getValue());
+ if (price)
+ mPrice = static_cast<int>(log(price));
+ else
+ mPrice = 0;
+ }
+ mItemPriceTextField->setValue(price);
+ mItemPriceSlide->setValue(price);
+ }
+}
+
+void ItemAmountWindow::close()
+{
+ keyboard.setEnabled(mEnabledKeyboard);
+ scheduleDelete();
+}
+
+void ItemAmountWindow::keyReleased(gcn::KeyEvent &keyEvent _UNUSED_)
+{
+ mItemAmountSlide->setValue(mItemAmountTextField->getValue());
+}
+
+void ItemAmountWindow::showWindow(Usage usage, Window *parent, Item *item,
+ int maxRange)
+{
+ if (!item)
+ return;
+
+ if (!maxRange)
+ maxRange = item->getQuantity();
+
+ if (usage != ShopBuyAdd && usage != ShopSellAdd && maxRange <= 1)
+ finish(item, maxRange, 0, usage);
+ else
+ new ItemAmountWindow(usage, parent, item, maxRange);
+}
diff --git a/src/gui/itemamount.h b/src/gui/itemamount.h
new file mode 100644
index 000000000..f28581294
--- /dev/null
+++ b/src/gui/itemamount.h
@@ -0,0 +1,124 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEM_AMOUNT_WINDOW_H
+#define ITEM_AMOUNT_WINDOW_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/keylistener.hpp>
+#include <guichan/actionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Icon;
+class IntTextField;
+class Item;
+class ItemsModal;
+class ItemPopup;
+class Label;
+
+/**
+ * Window used for selecting the amount of items to drop, trade or split.
+ *
+ * \ingroup Interface
+ */
+class ItemAmountWindow : public Window,
+ public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ enum Usage
+ {
+ TradeAdd = 0,
+ ItemDrop,
+ StoreAdd,
+ StoreRemove,
+ ItemSplit,
+ ShopBuyAdd,
+ ShopSellAdd
+ };
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Sets default amount value.
+ */
+ void resetAmount();
+
+ // MouseListener
+ void mouseMoved(gcn::MouseEvent &event);
+ void mouseExited(gcn::MouseEvent &event);
+
+ /**
+ * Schedules the Item Amount window for deletion.
+ */
+ void close();
+
+ void keyReleased(gcn::KeyEvent &keyEvent);
+
+ /**
+ * Creates the dialog, or bypass it if there aren't enough items.
+ */
+ static void showWindow(Usage usage, Window *parent, Item *item,
+ int maxRange = 0);
+
+ ~ItemAmountWindow();
+
+ private:
+ static void finish(Item *item, int amount, int price, Usage usage);
+
+ ItemAmountWindow(Usage usage, Window *parent, Item *item,
+ int maxRange = 0);
+
+ IntTextField *mItemAmountTextField; /**< Item amount caption. */
+ IntTextField *mItemPriceTextField; /**< Item price caption. */
+ Label *mGPLabel;
+ Item *mItem;
+ Icon *mItemIcon;
+
+ int mMax;
+ Usage mUsage;
+ ItemPopup *mItemPopup;
+
+ /**
+ * Item Amount buttons.
+ */
+ gcn::Slider *mItemAmountSlide;
+
+ gcn::Slider *mItemPriceSlide;
+
+ gcn::DropDown *mItemDropDown;
+
+ ItemsModal *mItemsModal;
+
+ bool mEnabledKeyboard;
+ int mPrice;
+};
+
+#endif // ITEM_AMOUNT_WINDOW_H
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
new file mode 100644
index 000000000..15a0be6bc
--- /dev/null
+++ b/src/gui/itempopup.cpp
@@ -0,0 +1,238 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/itempopup.h"
+
+#include "graphics.h"
+#include "item.h"
+#include "units.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/icon.h"
+#include "gui/widgets/textbox.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include <guichan/font.hpp>
+
+#include <guichan/widgets/label.hpp>
+#include <guichan/widgets/container.hpp>
+
+ItemPopup::ItemPopup():
+ Popup("ItemPopup"),
+ mIcon(0)
+{
+ // Item Name
+ mItemName = new gcn::Label;
+ mItemName->setFont(boldFont);
+ mItemName->setPosition(getPadding(), getPadding());
+
+ const int fontHeight = getFont()->getHeight();
+
+ // Item Description
+ mItemDesc = new TextBox;
+ mItemDesc->setEditable(false);
+ mItemDesc->setPosition(getPadding(), fontHeight);
+
+ // Item Effect
+ mItemEffect = new TextBox;
+ mItemEffect->setEditable(false);
+ mItemEffect->setPosition(getPadding(), 2 * fontHeight + 2 * getPadding());
+
+ // Item Weight
+ mItemWeight = new TextBox;
+ mItemWeight->setEditable(false);
+ mItemWeight->setPosition(getPadding(), 3 * fontHeight + 4 * getPadding());
+
+ mIcon = new Icon(0);
+
+ add(mItemName);
+ add(mItemDesc);
+ add(mItemEffect);
+ add(mItemWeight);
+ add(mIcon);
+
+ addMouseListener(this);
+}
+
+ItemPopup::~ItemPopup()
+{
+ if (mIcon)
+ {
+ Image *image = mIcon->getImage();
+ if (image)
+ image->decRef();
+ }
+}
+
+void ItemPopup::setItem(const Item *item, bool showImage)
+{
+ if (!item)
+ return;
+
+ const ItemInfo &ii = item->getInfo();
+ setItem(ii, showImage);
+ if (item->getRefine() > 0)
+ {
+ mItemName->setCaption(strprintf("%s (+%d), %d", ii.getName().c_str(),
+ item->getRefine(), ii.getId()));
+ mItemName->adjustSize();
+ int minWidth = mItemName->getWidth() + 8;
+ if (getWidth() < minWidth)
+ setWidth(minWidth);
+ }
+}
+
+void ItemPopup::setItem(const ItemInfo &item, bool showImage)
+{
+ if (!mIcon || item.getName() == mItemName->getCaption())
+ return;
+
+ int space = 0;
+
+ Image *oldImage = mIcon->getImage();
+ if (oldImage)
+ oldImage->decRef();
+
+ if (showImage)
+ {
+ ResourceManager *resman = ResourceManager::getInstance();
+ Image *image = resman->getImage(
+ paths.getStringValue("itemIcons")
+ + item.getDisplay().image);
+
+ mIcon->setImage(image);
+ if (image)
+ {
+ int x = getPadding();
+ int y = getPadding();
+ mIcon->setPosition(x, y);
+ space = mIcon->getWidth();
+ }
+ }
+ else
+ {
+ mIcon->setImage(0);
+ }
+
+ mItemType = item.getType();
+
+ mItemName->setCaption(item.getName() + _(", ") + toString(item.getId()));
+ mItemName->adjustSize();
+ mItemName->setForegroundColor(getColor(mItemType));
+ mItemName->setPosition(getPadding() + space, getPadding());
+
+ mItemDesc->setTextWrapped(item.getDescription(), 196);
+ mItemEffect->setTextWrapped(item.getEffect(), 196);
+ mItemWeight->setTextWrapped(strprintf(_("Weight: %s"),
+ Units::formatWeight(item.getWeight()).c_str()),
+ 196);
+
+ int minWidth = mItemName->getWidth() + space;
+
+ if (mItemName->getWidth() + space > minWidth)
+ minWidth = mItemName->getWidth() + space;
+ if (mItemDesc->getMinWidth() > minWidth)
+ minWidth = mItemDesc->getMinWidth();
+ if (mItemEffect->getMinWidth() > minWidth)
+ minWidth = mItemEffect->getMinWidth();
+ if (mItemWeight->getMinWidth() > minWidth)
+ minWidth = mItemWeight->getMinWidth();
+
+ minWidth += 8;
+ setWidth(minWidth);
+
+ const int numRowsDesc = mItemDesc->getNumberOfRows();
+ const int numRowsEffect = mItemEffect->getNumberOfRows();
+ const int numRowsWeight = mItemWeight->getNumberOfRows();
+ const int height = getFont()->getHeight();
+
+ if (item.getEffect().empty())
+ {
+ setContentSize(minWidth, (numRowsDesc + numRowsWeight + getPadding()) *
+ height);
+
+ mItemWeight->setPosition(getPadding(), (numRowsDesc + getPadding()) *
+ height);
+ }
+ else
+ {
+ setContentSize(minWidth, (numRowsDesc + numRowsEffect + numRowsWeight +
+ getPadding()) * height);
+
+ mItemWeight->setPosition(getPadding(), (numRowsDesc + numRowsEffect +
+ getPadding()) * height);
+ }
+
+ mItemDesc->setPosition(getPadding(), 2 * height);
+ mItemEffect->setPosition(getPadding(),
+ (numRowsDesc + getPadding()) * height);
+}
+
+gcn::Color ItemPopup::getColor(ItemType type)
+{
+ switch (type)
+ {
+ case ITEM_UNUSABLE:
+ return Theme::getThemeColor(Theme::GENERIC);
+ case ITEM_USABLE:
+ return Theme::getThemeColor(Theme::USABLE);
+ case ITEM_EQUIPMENT_ONE_HAND_WEAPON:
+ return Theme::getThemeColor(Theme::ONEHAND);
+ case ITEM_EQUIPMENT_TWO_HANDS_WEAPON:
+ return Theme::getThemeColor(Theme::TWOHAND);
+ case ITEM_EQUIPMENT_TORSO:
+ return Theme::getThemeColor(Theme::TORSO);
+ case ITEM_EQUIPMENT_ARMS:
+ return Theme::getThemeColor(Theme::ARMS);
+ case ITEM_EQUIPMENT_HEAD:
+ return Theme::getThemeColor(Theme::HEAD);
+ case ITEM_EQUIPMENT_LEGS:
+ return Theme::getThemeColor(Theme::LEGS);
+ case ITEM_EQUIPMENT_SHIELD:
+ return Theme::getThemeColor(Theme::SHIELD);
+ case ITEM_EQUIPMENT_RING:
+ return Theme::getThemeColor(Theme::RING);
+ case ITEM_EQUIPMENT_NECKLACE:
+ return Theme::getThemeColor(Theme::NECKLACE);
+ case ITEM_EQUIPMENT_FEET:
+ return Theme::getThemeColor(Theme::FEET);
+ case ITEM_EQUIPMENT_AMMO:
+ return Theme::getThemeColor(Theme::AMMO);
+ default:
+ return Theme::getThemeColor(Theme::UNKNOWN_ITEM);
+ }
+}
+
+void ItemPopup::mouseMoved(gcn::MouseEvent &event)
+{
+ Popup::mouseMoved(event);
+
+ // When the mouse moved on top of the popup, hide it
+ setVisible(false);
+} \ No newline at end of file
diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h
new file mode 100644
index 000000000..0baf8fb79
--- /dev/null
+++ b/src/gui/itempopup.h
@@ -0,0 +1,71 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEMPOPUP_H
+#define ITEMPOPUP_H
+
+#include "gui/widgets/popup.h"
+
+#include "resources/iteminfo.h"
+
+#include <guichan/mouselistener.hpp>
+
+class Icon;
+class TextBox;
+
+/**
+ * A popup that displays information about an item.
+ */
+class ItemPopup : public Popup
+{
+ public:
+ /**
+ * Constructor. Initializes the item popup.
+ */
+ ItemPopup();
+
+ /**
+ * Destructor. Cleans up the item popup on deletion.
+ */
+ ~ItemPopup();
+
+ /**
+ * Sets the info to be displayed given a particular item.
+ */
+ void setItem(const ItemInfo &item, bool showImage = false);
+
+ void setItem(const Item *item, bool showImage = false);
+
+ void mouseMoved(gcn::MouseEvent &mouseEvent);
+
+ private:
+ gcn::Label *mItemName;
+ TextBox *mItemDesc;
+ TextBox *mItemEffect;
+ TextBox *mItemWeight;
+ ItemType mItemType;
+ Icon *mIcon;
+
+ static gcn::Color getColor(ItemType type);
+};
+
+#endif // ITEMPOPUP_H
diff --git a/src/gui/killstats.cpp b/src/gui/killstats.cpp
new file mode 100644
index 000000000..8ce38c719
--- /dev/null
+++ b/src/gui/killstats.cpp
@@ -0,0 +1,424 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "killstats.h"
+
+#include <math.h>
+#include <guichan/widgets/label.hpp>
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/chattab.h"
+#include "gui/chat.h"
+
+#include "actorspritemanager.h"
+#include "event.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+KillStats::KillStats():
+ Window(_("Kill stats")), mKillCounter(0), mExpCounter(0),
+ mKillTCounter(0), mExpTCounter(0), mKillTimer(0),
+ m1minExpTime(0), m1minExpNum(0), m1minSpeed(0),
+ m5minExpTime(0), m5minExpNum(0), m5minSpeed(0),
+ m15minExpTime(0), m15minExpNum(0), m15minSpeed(0),
+ mJackoSpawnTime(0), mValidateJackoTime(0), mJackoId(0),
+ mIsJackoAlive(false), mIsJackoMustSpawn(true),
+ mIsJackoSpawnTimeUnknown(true)
+{
+ setWindowName("Kill stats");
+ setCloseButton(true);
+ setResizable(true);
+ setDefaultSize(250, 250, 350, 300);
+
+ listen(CHANNEL_ATTRIBUTES);
+ int xp(PlayerInfo::getAttribute(EXP));
+ int xpNextLevel(PlayerInfo::getAttribute(EXP_NEEDED));
+
+ mResetButton = new Button(_("Reset stats"), "reset", this);
+ mTimerButton = new Button(_("Reset timer"), "timer", this);
+ if (!xpNextLevel)
+ xpNextLevel = 1;
+
+ mLine1 = new Label(_("Level: ") + toString(player_node->getLevel())
+ + " at " + toString(static_cast<float>(xp)
+ / static_cast<float>(xpNextLevel) * 100.0f) + "%");
+
+ mLine2 = new Label(_("Exp: ") + toString(xp) + "/" +
+ toString(xpNextLevel) + _(" Left: ") +
+ toString(xpNextLevel-xp));
+ mLine3 = new Label("1% = " + toString(xpNextLevel / 100) +
+ _(" exp, Avg Mob for 1%: ?"));
+ mLine4 = new Label(_("Kills: ?, Total Exp: ?"));
+ mLine5 = new Label(_("Avg Exp: ?, No. of Avg mob to next level: ?"));
+ mLine6 = new Label(_("Kills/Min: ?, Exp/Min: ?"));
+
+ mExpSpeed1Label = new Label(_("Exp speed per 1 min: ?"));
+ mExpTime1Label = new Label(_("Time for next level per 1 min: ?"));
+ mExpSpeed5Label = new Label(_("Exp speed per 5 min: ?"));
+ mExpTime5Label = new Label(_("Time for next level per 5 min: ?"));
+ mExpSpeed15Label = new Label(_("Exp speed per 15 min: ?"));
+ mExpTime15Label = new Label(_("Time for Next level per 15 min: ?"));
+
+ mLastKillExpLabel = new Label(_("Last kill exp: ?"));
+ mTimeBeforeJackoLabel = new Label(_("Time before jacko spawn: ?"));
+
+ place(0, 0, mLine1, 6).setPadding(0);
+ place(0, 1, mLine2, 6).setPadding(0);
+ place(0, 2, mLine3, 6).setPadding(0);
+ place(0, 3, mLine4, 6).setPadding(0);
+ place(0, 4, mLine5, 6).setPadding(0);
+ place(0, 5, mLine6, 6).setPadding(0);
+
+ place(0, 6, mLastKillExpLabel, 6).setPadding(0);
+ place(0, 7, mTimeBeforeJackoLabel, 6).setPadding(0);
+ place(0, 8, mExpSpeed1Label, 6).setPadding(0);
+ place(0, 9, mExpTime1Label, 6).setPadding(0);
+ place(0, 10, mExpSpeed5Label, 6).setPadding(0);
+ place(0, 11, mExpTime5Label, 6).setPadding(0);
+ place(0, 12, mExpSpeed15Label, 6).setPadding(0);
+ place(0, 13, mExpTime15Label, 6).setPadding(0);
+
+ place(5, 12, mTimerButton).setPadding(0);
+ place(5, 13, mResetButton).setPadding(0);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+
+ loadWindowState();
+
+}
+
+KillStats::~KillStats()
+{
+}
+
+void KillStats::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "reset")
+ {
+ mKillCounter = 0;
+ mExpCounter = 0;
+ mLine3->setCaption("1% = " + toString(
+ PlayerInfo::getAttribute(EXP_NEEDED) / 100) +
+ " exp, Avg Mob for 1%: ?");
+ mLine4->setCaption(_("Kills: ?, Total Exp: ?"));
+ mLine5->setCaption(_("Avg Exp: ?, No. of Avg mob to next level: ?"));
+
+ m1minExpTime = 0;
+ m1minExpNum = 0;
+ m1minSpeed = 0;
+ m5minExpTime = 0;
+ m5minExpNum = 0;
+ m5minSpeed = 0;
+ m15minExpTime = 0;
+ m15minExpNum = 0;
+ m15minSpeed = 0;
+ }
+ else if (event.getId() == "timer")
+ {
+ mKillTimer = 0;
+ mKillTCounter = 0;
+ mExpTCounter = 0;
+ mLine6->setCaption(_("Kills/Min: ?, Exp/Min: ?"));
+
+ m1minExpTime = 0;
+ m1minExpNum = 0;
+ m1minSpeed = 0;
+ m5minExpTime = 0;
+ m5minExpNum = 0;
+ m5minSpeed = 0;
+ m15minExpTime = 0;
+ m15minExpNum = 0;
+ m15minSpeed = 0;
+ }
+}
+
+void KillStats::gainXp(int xp)
+{
+ if (xp == PlayerInfo::getAttribute(EXP_NEEDED))
+ xp = 0;
+ else if (!xp)
+ return;
+
+ mKillCounter++;
+ mKillTCounter++;
+
+ mExpCounter = mExpCounter + xp;
+ mExpTCounter = mExpTCounter + xp;
+ if (!mKillCounter)
+ mKillCounter = 1;
+
+ float AvgExp = static_cast<float>(mExpCounter / mKillCounter);
+ int xpNextLevel(PlayerInfo::getAttribute(EXP_NEEDED));
+
+ if (mKillTimer == 0)
+ mKillTimer = cur_time;
+
+ if (!xpNextLevel)
+ xpNextLevel = 1;
+
+ double timeDiff = difftime(cur_time, mKillTimer) / 60;
+
+ if (timeDiff <= 0.001)
+ timeDiff = 1;
+
+ mLine1->setCaption("Level: " + toString(player_node->getLevel()) + " at " +
+ toString(static_cast<float>(PlayerInfo::getAttribute(EXP))
+ / static_cast<float>(xpNextLevel) * 100.0f) + "%");
+
+ mLine2->setCaption("Exp: " + toString(PlayerInfo::getAttribute(EXP)) + "/"
+ + toString(xpNextLevel) + " Left: "
+ + toString(xpNextLevel - PlayerInfo::getAttribute(EXP)));
+ if (AvgExp >= 0.001 && AvgExp <= 0.001)
+ {
+ mLine3->setCaption("1% = " + toString(xpNextLevel / 100)
+ + " exp, Avg Mob for 1%: ?");
+
+ mLine5->setCaption("Avg Exp: " + toString(AvgExp) +
+ ", No. of Avg mob to next level: ?");
+ }
+ else
+ {
+ mLine3->setCaption("1% = " + toString(xpNextLevel / 100)
+ + " exp, Avg Mob for 1%: " +
+ toString((static_cast<float>(xpNextLevel) / 100) / AvgExp));
+
+ mLine5->setCaption("Avg Exp: " + toString(AvgExp) +
+ ", No. of Avg mob to next level: " +
+ toString(static_cast<float>(xpNextLevel -
+ PlayerInfo::getAttribute(EXP)) / AvgExp));
+ }
+ mLine4->setCaption("Kills: " + toString(mKillCounter) +
+ ", Total Exp: " + toString(mExpCounter));
+
+ mLine6->setCaption("Kills/Min: " + toString(mKillTCounter / timeDiff) +
+ ", Exp/Min: " + toString(mExpTCounter / timeDiff));
+
+ mLastKillExpLabel->setCaption("Last Kill Exp: " + toString(xp));
+
+ recalcStats();
+ update();
+}
+
+void KillStats::recalcStats()
+{
+ int curTime = cur_time;
+
+ // Need Update Exp Counter
+ if (curTime - m1minExpTime > 60)
+ {
+ int newExp = PlayerInfo::getAttribute(EXP);
+ if (m1minExpTime != 0)
+ m1minSpeed = newExp - m1minExpNum;
+ else
+ m1minSpeed = 0;
+ m1minExpTime = curTime;
+ m1minExpNum = newExp;
+ }
+
+ if (curTime - m5minExpTime > 60*5)
+ {
+ int newExp = PlayerInfo::getAttribute(EXP);
+ if (m5minExpTime != 0)
+ m5minSpeed = newExp - m5minExpNum;
+ else
+ m5minSpeed = 0;
+ m5minExpTime = curTime;
+ m5minExpNum = newExp;
+ }
+
+ if (curTime - m15minExpTime > 60*15)
+ {
+ int newExp = PlayerInfo::getAttribute(EXP);
+ if (m15minExpTime != 0)
+ m15minSpeed = newExp - m15minExpNum;
+ else
+ m15minSpeed = 0;
+ m15minExpTime = curTime;
+ m15minExpNum = newExp;
+ }
+ validateJacko();
+}
+
+void KillStats::update()
+{
+ mExpSpeed1Label->setCaption(
+ strprintf(_("Exp Speed per 1 min: %d"), m1minSpeed));
+ mExpSpeed1Label->adjustSize();
+
+ if (m1minSpeed != 0)
+ {
+ mExpTime1Label->setCaption(strprintf(_(" Time For Next Level: %f"),
+ static_cast<float>((PlayerInfo::getAttribute(EXP_NEEDED)
+ - PlayerInfo::getAttribute(EXP)) / m1minSpeed)));
+ }
+ else
+ {
+ mExpTime1Label->setCaption(_(" Time For Next Level: ?"));
+ }
+ mExpTime1Label->adjustSize();
+
+ mExpSpeed5Label->setCaption(
+ strprintf(_("Exp Speed per 5 min: %d"), m5minSpeed / 5));
+ mExpSpeed5Label->adjustSize();
+
+ if (m5minSpeed != 0)
+ {
+ mExpTime5Label->setCaption(strprintf(_(" Time For Next Level: %f"),
+ static_cast<float>((PlayerInfo::getAttribute(EXP_NEEDED)
+ - PlayerInfo::getAttribute(EXP)) / m5minSpeed * 5)));
+ }
+ else
+ {
+ mExpTime5Label->setCaption(_(" Time For Next Level: ?"));
+ }
+ mExpTime5Label->adjustSize();
+
+ mExpSpeed15Label->setCaption(
+ strprintf(_("Exp Speed per 15 min: %d"), m15minSpeed / 15));
+ mExpSpeed15Label->adjustSize();
+
+ if (m15minSpeed != 0)
+ {
+ mExpTime15Label->setCaption(strprintf(_(" Time For Next Level: %f"),
+ static_cast<float>((PlayerInfo::getAttribute(EXP_NEEDED)
+ - PlayerInfo::getAttribute(EXP)) / m15minSpeed * 15)));
+ }
+ else
+ {
+ mExpTime15Label->setCaption(_(" Time For Next Level: ?"));
+ }
+
+ validateJacko();
+ updateJackoLabel();
+}
+void KillStats::draw(gcn::Graphics *g)
+{
+ update();
+
+ Window::draw(g);
+}
+
+void KillStats::updateJackoLabel()
+{
+ if (mIsJackoAlive)
+ {
+ mTimeBeforeJackoLabel->setCaption(
+ _("Time before jacko spawn: jacko alive"));
+ }
+ else if (mIsJackoSpawnTimeUnknown && mJackoSpawnTime != 0)
+ {
+ mTimeBeforeJackoLabel->setCaption(_("Time before jacko spawn: ")
+ + toString(mJackoSpawnTime - cur_time) + _("?"));
+ }
+ else if (mIsJackoMustSpawn)
+ {
+ mTimeBeforeJackoLabel->setCaption(
+ _("Time before jacko spawn: jacko spawning"));
+ }
+ else
+ {
+ mTimeBeforeJackoLabel->setCaption(_("Time before jacko spawn: ")
+ + toString(mJackoSpawnTime - cur_time));
+ }
+}
+
+void KillStats::jackoDead(int id)
+{
+ if (id == mJackoId && mIsJackoAlive)
+ {
+ mIsJackoAlive = false;
+ mJackoSpawnTime = cur_time + 60*4;
+ mIsJackoSpawnTimeUnknown = false;
+ updateJackoLabel();
+ }
+}
+
+void KillStats::addLog(std::string str)
+{
+ if (debugChatTab)
+ debugChatTab->chatLog(str, BY_SERVER);
+}
+
+void KillStats::jackoAlive(int id)
+{
+ if (!mIsJackoAlive)
+ {
+ mJackoId = id;
+ mIsJackoAlive = true;
+ mIsJackoMustSpawn = false;
+ mJackoSpawnTime = 0;
+ mIsJackoSpawnTimeUnknown = false;
+ updateJackoLabel();
+ }
+}
+
+void KillStats::validateJacko()
+{
+ if (!actorSpriteManager || !player_node)
+ return;
+
+ Map *currentMap = Game::instance()->getCurrentMap();
+ if (currentMap)
+ {
+ if (currentMap->getProperty("_filename") == "018-1"
+ || currentMap->getProperty("_filename") == "maps/018-1.tmx")
+ {
+ if (player_node->getTileX() >= 167
+ && player_node->getTileX() <= 175
+ && player_node->getTileY() >= 21
+ && player_node->getTileY() <= 46)
+ {
+ Being *dstBeing = actorSpriteManager->findBeingByName(
+ "Jack O", Being::MONSTER);
+ if (mIsJackoAlive && !dstBeing)
+ {
+ mIsJackoAlive = false;
+ mJackoSpawnTime = cur_time + 60*4;
+ mIsJackoSpawnTimeUnknown = true;
+ }
+ }
+ }
+
+ if (!mIsJackoAlive && cur_time > mJackoSpawnTime + 15)
+ mIsJackoMustSpawn = true;
+ }
+}
+
+void KillStats::event(Channels channel _UNUSED_,
+ const Mana::Event &event)
+{
+ if (event.getName() == EVENT_UPDATEATTRIBUTE)
+ {
+ int id = event.getInt("id");
+ if (id == EXP || id == EXP_NEEDED)
+ {
+ gainXp(event.getInt("newValue") - event.getInt("oldValue"));
+// update();
+ }
+ }
+}
diff --git a/src/gui/killstats.h b/src/gui/killstats.h
new file mode 100644
index 000000000..df53aa319
--- /dev/null
+++ b/src/gui/killstats.h
@@ -0,0 +1,132 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef KILLSTATS_H
+#define KILLSTATS_H
+
+#include <guichan/actionlistener.hpp>
+
+#include "listener.h"
+
+#include "gui/widgets/window.h"
+
+class Label;
+class Button;
+
+class KillStats : public Window, gcn::ActionListener, public Mana::Listener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ KillStats();
+
+ /**
+ * Destructor.
+ */
+ ~KillStats();
+
+ /**
+ * Stuff.
+ */
+ void action(const gcn::ActionEvent &event);
+ void gainXp(int Xp);
+
+ /**
+ * Recalc stats if needed
+ */
+ void recalcStats();
+
+ /**
+ * Draw this window
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Updates this dialog
+ */
+ void update();
+
+ /**
+ * Updates jacko info
+ */
+ void updateJackoLabel();
+
+ void jackoDead(int id);
+
+ void jackoAlive(int id);
+
+ void addLog(std::string str);
+
+ void event(Channels channel _UNUSED_,
+ const Mana::Event &event);
+
+ private:
+ void validateJacko();
+
+ int mKillCounter; /**< Session Kill counter. */
+ int mExpCounter; /**< Session Exp counter. */
+ int mKillTCounter; /**< Timer Kill counter. */
+ int mExpTCounter; /**< Timer Exp counter. */
+ time_t mKillTimer; /**< Timer for kill stats. */
+ Button *mResetButton;
+ Button *mTimerButton;
+ Label *mLine1;
+ Label *mLine2;
+ Label *mLine3;
+ Label *mLine4;
+ Label *mLine5;
+ Label *mLine6;
+
+ gcn::Label *mExpSpeed1Label;
+ gcn::Label *mExpTime1Label;
+ gcn::Label *mExpSpeed5Label;
+ gcn::Label *mExpTime5Label;
+ gcn::Label *mExpSpeed15Label;
+ gcn::Label *mExpTime15Label;
+
+ gcn::Label *mLastKillExpLabel;
+ gcn::Label *mTimeBeforeJackoLabel;
+
+ int m1minExpTime;
+ int m1minExpNum;
+ int m1minSpeed;
+
+ int m5minExpTime;
+ int m5minExpNum;
+ int m5minSpeed;
+
+ int m15minExpTime;
+ int m15minExpNum;
+ int m15minSpeed;
+
+ int mJackoSpawnTime;
+ int mValidateJackoTime;
+ int mJackoId;
+ bool mIsJackoAlive;
+ bool mIsJackoMustSpawn;
+ bool mIsJackoSpawnTimeUnknown;
+};
+
+extern KillStats *killStats;
+
+#endif
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
new file mode 100644
index 000000000..997895c95
--- /dev/null
+++ b/src/gui/login.cpp
@@ -0,0 +1,231 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/login.h"
+
+#include "client.h"
+#include "configuration.h"
+
+#include "gui/okdialog.h"
+#include "gui/sdlinput.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/dropdown.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/passwordfield.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+static const int MAX_SERVER_LIST_SIZE = 15;
+static const int LOGIN_DIALOG_WIDTH = 300;
+static const int LOGIN_DIALOG_HEIGHT = 140;
+static const int FIELD_WIDTH = LOGIN_DIALOG_WIDTH - 70;
+
+std::string LoginDialog::savedPassword = "";
+std::string LoginDialog::savedPasswordKey = "";
+
+
+const char *UPDATE_TYPE_TEXT[3] =
+{
+ _("Normal"),
+ _("Auto Close"),
+ _("Skip"),
+};
+
+class UpdateTypeModel : public gcn::ListModel
+{
+public:
+ virtual ~UpdateTypeModel()
+ { }
+
+ virtual int getNumberOfElements()
+ {
+ return 3;
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return UPDATE_TYPE_TEXT[i];
+ }
+};
+
+LoginDialog::LoginDialog(LoginData *loginData, std::string serverName,
+ std::string *updateHost):
+ Window(_("Login")),
+ mLoginData(loginData),
+ mUpdateHost(updateHost)
+{
+ gcn::Label *serverLabel1 = new Label(_("Server:"));
+ gcn::Label *serverLabel2 = new Label(serverName);
+ serverLabel2->adjustSize();
+ gcn::Label *userLabel = new Label(_("Name:"));
+ gcn::Label *passLabel = new Label(_("Password:"));
+ mCustomUpdateHost = new CheckBox(_("Custom update host"),
+ loginData->updateType & LoginData::Upd_Custom, this, "customhost");
+
+ mUpdateHostText = new TextField(serverConfig.getValue(
+ "customUpdateHost", ""));
+
+ mUpdateHostText->adjustSize();
+
+ mUserField = new TextField(mLoginData->username);
+ mPassField = new PasswordField(mLoginData->password);
+
+ if (mPassField->getText().empty() && LoginDialog::savedPassword != "")
+ mPassField->setText(LoginDialog::savedPassword);
+
+ mKeepCheck = new CheckBox(_("Remember username"), mLoginData->remember);
+ mUpdateTypeLabel = new Label(_("Update:"));
+ mUpdateTypeDropDown = new DropDown(new UpdateTypeModel());
+ mUpdateTypeDropDown->setActionEventId("updatetype");
+ mUpdateTypeDropDown->setSelected((loginData->updateType
+ | LoginData::Upd_Custom) ^ LoginData::Upd_Custom);
+
+ if (!mCustomUpdateHost->isSelected())
+ mUpdateHostText->setVisible(false);
+
+ mRegisterButton = new Button(_("Register"), "register", this);
+ mServerButton = new Button(_("Change Server"), "server", this);
+ mLoginButton = new Button(_("Login"), "login", this);
+
+ mUserField->setActionEventId("login");
+ mPassField->setActionEventId("login");
+
+ mUserField->addKeyListener(this);
+ mPassField->addKeyListener(this);
+ mUserField->addActionListener(this);
+ mPassField->addActionListener(this);
+
+ place(0, 0, serverLabel1);
+ place(1, 0, serverLabel2, 8).setPadding(1);
+
+ place(0, 1, userLabel);
+ place(0, 2, passLabel);
+ place(1, 1, mUserField, 8).setPadding(1);
+ place(1, 2, mPassField, 8).setPadding(1);
+ place(0, 6, mUpdateTypeLabel, 1);
+ place(1, 6, mUpdateTypeDropDown, 8);
+ place(0, 7, mCustomUpdateHost, 9);
+ place(0, 8, mUpdateHostText, 9);
+ place(0, 9, mKeepCheck, 9);
+ place(0, 10, mRegisterButton).setHAlign(LayoutCell::LEFT);
+ place(2, 10, mServerButton);
+ place(3, 10, mLoginButton);
+
+ reflowLayout();
+
+ addKeyListener(this);
+
+ center();
+ setVisible(true);
+
+ if (mUserField->getText().empty())
+ mUserField->requestFocus();
+ else
+ mPassField->requestFocus();
+
+ mLoginButton->setEnabled(canSubmit());
+ mRegisterButton->setEnabled(Net::getLoginHandler()
+ ->isRegistrationEnabled());
+}
+
+LoginDialog::~LoginDialog()
+{
+}
+
+void LoginDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "login" && canSubmit())
+ {
+ mLoginData->username = mUserField->getText();
+ mLoginData->password = mPassField->getText();
+ mLoginData->remember = mKeepCheck->isSelected();
+ int updateType = mUpdateTypeDropDown->getSelected();
+
+ if (mCustomUpdateHost->isSelected())
+ {
+ updateType |= LoginData::Upd_Custom;
+ serverConfig.setValue("customUpdateHost",
+ mUpdateHostText->getText());
+
+ mLoginData->updateHost = mUpdateHostText->getText();
+ *mUpdateHost = mUpdateHostText->getText();
+ }
+ mLoginData->updateType = updateType;
+ serverConfig.setValue("updateType", updateType);
+
+ mLoginData->registerLogin = false;
+
+ mRegisterButton->setEnabled(false);
+ mServerButton->setEnabled(false);
+ mLoginButton->setEnabled(false);
+
+ if (mLoginData->remember)
+ LoginDialog::savedPassword = mPassField->getText();
+
+ Client::setState(STATE_LOGIN_ATTEMPT);
+ }
+ else if (event.getId() == "server")
+ {
+ Client::setState(STATE_SWITCH_SERVER);
+ }
+ else if (event.getId() == "register")
+ {
+ mLoginData->username = mUserField->getText();
+ mLoginData->password = mPassField->getText();
+
+ Client::setState(STATE_REGISTER_PREP);
+ }
+ else if (event.getId() == "customhost")
+ {
+ mUpdateHostText->setVisible(mCustomUpdateHost->isSelected());
+ }
+}
+
+void LoginDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ESCAPE)
+ action(gcn::ActionEvent(NULL, mServerButton->getActionEventId()));
+ else if (key.getValue() == Key::ENTER)
+ action(gcn::ActionEvent(NULL, mLoginButton->getActionEventId()));
+ else
+ mLoginButton->setEnabled(canSubmit());
+}
+
+bool LoginDialog::canSubmit() const
+{
+ return !mUserField->getText().empty() &&
+ !mPassField->getText().empty() &&
+ Client::getState() == STATE_LOGIN;
+}
diff --git a/src/gui/login.h b/src/gui/login.h
new file mode 100644
index 000000000..f20637032
--- /dev/null
+++ b/src/gui/login.h
@@ -0,0 +1,90 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LOGIN_H
+#define LOGIN_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/listmodel.hpp>
+
+#include <string>
+#include <vector>
+
+class LoginData;
+
+/**
+ * The login dialog.
+ *
+ * \ingroup Interface
+ */
+class LoginDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ LoginDialog(LoginData *loginData, std::string serverName,
+ std::string *updateHost);
+
+ ~LoginDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Called when a key is pressed in one of the text fields.
+ */
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ static std::string savedPasswordKey;
+ static std::string savedPassword;
+
+ private:
+ /**
+ * Returns whether submit can be enabled. This is true in the login
+ * state, when all necessary fields have some text.
+ */
+ bool canSubmit() const;
+
+ gcn::TextField *mUserField;
+ gcn::TextField *mPassField;
+ gcn::CheckBox *mKeepCheck;
+ gcn::Label *mUpdateTypeLabel;
+ gcn::DropDown *mUpdateTypeDropDown;
+ gcn::Button *mServerButton;
+ gcn::Button *mLoginButton;
+ gcn::Button *mRegisterButton;
+ gcn::CheckBox *mCustomUpdateHost;
+ gcn::TextField *mUpdateHostText;
+
+ LoginData *mLoginData;
+ std::string *mUpdateHost;
+};
+
+#endif
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
new file mode 100644
index 000000000..6edefcfdd
--- /dev/null
+++ b/src/gui/minimap.cpp
@@ -0,0 +1,292 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/minimap.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "localplayer.h"
+#include "log.h"
+#include "map.h"
+
+#include "gui/userpalette.h"
+#include "gui/setup.h"
+#include "gui/viewport.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+
+#include <guichan/font.hpp>
+
+bool Minimap::mShow = true;
+
+Minimap::Minimap():
+ Window(_("Map")),
+ mMapImage(0),
+ mWidthProportion(0.5),
+ mHeightProportion(0.5)
+{
+ setWindowName("Minimap");
+ mShow = config.getValueBool(getWindowName() + "Show", true);
+ setDefaultSize(5, 25, 100, 100);
+ // set this to false as the minimap window size is changed
+ //depending on the map size
+ setResizable(false);
+ setupWindow->registerWindowForReset(this);
+
+ setDefaultVisible(true);
+ setSaveVisible(true);
+
+ setStickyButton(true);
+ setSticky(false);
+
+ loadWindowState();
+ setVisible(mShow, isSticky());
+}
+
+Minimap::~Minimap()
+{
+ config.setValue(getWindowName() + "Show", mShow);
+
+ if (mMapImage)
+ mMapImage->decRef();
+}
+
+void Minimap::setMap(Map *map)
+{
+ std::string caption = "";
+ std::string minimapName;
+
+ if (map)
+ caption = map->getName();
+
+ if (caption.empty())
+ caption = _("Map");
+
+ setCaption(caption);
+
+ // Adapt the image
+ if (mMapImage)
+ {
+ mMapImage->decRef();
+ mMapImage = 0;
+ }
+
+ if (map)
+ {
+ std::string tempname =
+ "graphics/minimaps/" + map->getFilename() + ".png";
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ minimapName = map->getProperty("minimap");
+
+ if (minimapName.empty() && resman->exists(tempname))
+ minimapName = tempname;
+
+ mMapImage = resman->getImage(minimapName);
+ }
+
+ if (mMapImage && map)
+ {
+ const int offsetX = 2 * getPadding();
+ const int offsetY = getTitleBarHeight() + getPadding();
+ const int titleWidth = getFont()->getWidth(getCaption()) + 15;
+ const int mapWidth = mMapImage->getWidth() < 100 ?
+ mMapImage->getWidth() + offsetX : 100;
+ const int mapHeight = mMapImage->getHeight() < 100 ?
+ mMapImage->getHeight() + offsetY : 100;
+
+ setMinWidth(mapWidth > titleWidth ? mapWidth : titleWidth);
+ setMinHeight(mapHeight);
+
+ mWidthProportion = static_cast<float>(
+ mMapImage->getWidth()) / static_cast<float>(map->getWidth());
+ mHeightProportion = static_cast<float>(
+ mMapImage->getHeight()) / static_cast<float>(map->getHeight());
+
+ setMaxWidth(mMapImage->getWidth() > titleWidth ?
+ mMapImage->getWidth() + offsetX : titleWidth);
+ setMaxHeight(mMapImage->getHeight() + offsetY);
+
+ setDefaultSize(getX(), getY(), getWidth(), getHeight());
+ resetToDefaultSize();
+
+ if (mShow)
+ setVisible(true);
+ }
+ else
+ {
+ if (!isSticky())
+ setVisible(false);
+ }
+}
+
+void Minimap::toggle()
+{
+ setVisible(!isVisible(), isSticky());
+ mShow = isVisible();
+}
+
+void Minimap::draw(gcn::Graphics *graphics)
+{
+ Window::draw(graphics);
+
+ if (!userPalette || !player_node || !viewport)
+ return;
+
+ Graphics *graph = static_cast<Graphics*>(graphics);
+
+ const gcn::Rectangle a = getChildrenArea();
+
+ graphics->pushClipArea(a);
+
+ int mapOriginX = 0;
+ int mapOriginY = 0;
+
+ if (mMapImage)
+ {
+ if (mMapImage->getWidth() > a.width ||
+ mMapImage->getHeight() > a.height)
+ {
+ const Vector &p = player_node->getPosition();
+ mapOriginX = ((a.width) / 2) - static_cast<int>((p.x
+ + viewport->getCameraRelativeX()) * mWidthProportion) / 32;
+ mapOriginY = ((a.height) / 2) - static_cast<int>((p.y
+ + viewport->getCameraRelativeX()) * mHeightProportion) / 32;
+
+ const int minOriginX = a.width - mMapImage->getWidth();
+ const int minOriginY = a.height - mMapImage->getHeight();
+
+ if (mapOriginX < minOriginX)
+ mapOriginX = minOriginX;
+ if (mapOriginY < minOriginY)
+ mapOriginY = minOriginY;
+ if (mapOriginX > 0)
+ mapOriginX = 0;
+ if (mapOriginY > 0)
+ mapOriginY = 0;
+ }
+
+ graph->drawImage(mMapImage, mapOriginX, mapOriginY);
+ }
+
+ if (!actorSpriteManager)
+ return;
+
+ const ActorSprites &actors = actorSpriteManager->getAll();
+
+ for (ActorSpritesConstIterator it = actors.begin(), it_end = actors.end();
+ it != it_end; it++)
+ {
+ if (!(*it) || (*it)->getType() == ActorSprite::FLOOR_ITEM)
+ continue;
+
+ const Being *being = static_cast<Being*>(*it);
+ if (!being)
+ continue;
+
+ int dotSize = 2;
+
+ int type = UserPalette::PC;
+
+ if (being == player_node)
+ {
+ type = UserPalette::SELF;
+ dotSize = 3;
+ }
+ else if (being->isGM())
+ {
+ type = UserPalette::GM;
+ }
+ else if (being->isInParty())
+ {
+ type = UserPalette::PARTY;
+ }
+ else if (being)
+ {
+ switch (being->getType())
+ {
+ case ActorSprite::MONSTER:
+ type = UserPalette::MONSTER;
+ break;
+
+ case ActorSprite::NPC:
+ type = UserPalette::NPC;
+ break;
+
+ default:
+ continue;
+ }
+ }
+
+ if (userPalette)
+ graphics->setColor(userPalette->getColor(type));
+
+ const int offsetHeight = static_cast<int>(static_cast<float>(
+ dotSize - 1) * mHeightProportion);
+ const int offsetWidth = static_cast<int>(static_cast<float>(
+ dotSize - 1) * mWidthProportion);
+ const Vector &pos = being->getPosition();
+
+ graphics->fillRectangle(gcn::Rectangle(
+ static_cast<int>(pos.x * mWidthProportion) / 32
+ + mapOriginX - offsetWidth,
+ static_cast<int>(pos.y * mHeightProportion) / 32
+ + mapOriginY - offsetHeight,
+ dotSize, dotSize));
+ }
+
+ const Vector &pos = player_node->getPosition();
+// logger->log("width:" + toString(graph->getWidth()));
+
+ int x = static_cast<int>((pos.x - (graph->getWidth() / 2)
+ + viewport->getCameraRelativeX())
+ * mWidthProportion) / 32 + mapOriginX;
+ int y = static_cast<int>((pos.y - (graph->getHeight() / 2)
+ + viewport->getCameraRelativeY())
+ * mHeightProportion) / 32 + mapOriginY;
+
+ const int w = graph->getWidth() * mWidthProportion / 32;
+ const int h = graph->getHeight() * mHeightProportion / 32;
+
+ if (w <= a.width)
+ {
+ if (x < 0 && w)
+ x = 0;
+ if (x + w > a.width)
+ x = a.width - w;
+ }
+ if (h <= a.height)
+ {
+ if (y < 0 && h)
+ y = 0;
+ if (y + h > a.height)
+ y = a.height - h;
+ }
+
+ graphics->setColor(userPalette->getColor(UserPalette::PC));
+ graphics->drawRectangle(gcn::Rectangle(x, y, w, h));
+ graphics->popClipArea();
+}
diff --git a/src/gui/minimap.h b/src/gui/minimap.h
new file mode 100644
index 000000000..a376a15c1
--- /dev/null
+++ b/src/gui/minimap.h
@@ -0,0 +1,69 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MINIMAP_H
+#define MINIMAP_H
+
+#include "gui/widgets/window.h"
+
+class Image;
+class Map;
+
+/**
+ * Minimap window. Shows a minimap image and the name of the current map.
+ *
+ * The name of the map is defined by the map property "name". The minimap image
+ * is defined by the map property "minimap". The path to the image should be
+ * given relative to the root of the client data.
+ *
+ * \ingroup Interface
+ */
+class Minimap : public Window
+{
+ public:
+ Minimap();
+ ~Minimap();
+
+ /**
+ * Sets the map image that should be displayed.
+ */
+ void setMap(Map *map);
+
+ /**
+ * Toggles the displaying of the minimap.
+ */
+ void toggle();
+
+ /**
+ * Draws the minimap.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ private:
+ Image *mMapImage;
+ float mWidthProportion;
+ float mHeightProportion;
+ static bool mShow;
+};
+
+extern Minimap *minimap;
+
+#endif
diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp
new file mode 100644
index 000000000..406ad7ddd
--- /dev/null
+++ b/src/gui/ministatus.cpp
@@ -0,0 +1,228 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/ministatus.h"
+
+#include "animatedsprite.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "playerinfo.h"
+
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/statuswindow.h"
+#include "gui/statuspopup.h"
+#include "gui/textpopup.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/progressbar.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+#include "net/gamehandler.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern volatile int tick_time;
+
+MiniStatusWindow::MiniStatusWindow():
+ Popup("MiniStatus")
+{
+ listen(CHANNEL_ATTRIBUTES);
+
+ mHpBar = new ProgressBar(0, 100, 20, Theme::PROG_HP);
+ StatusWindow::updateHPBar(mHpBar);
+
+ if (Net::getGameHandler()->canUseMagicBar())
+ {
+ mMpBar = new ProgressBar(0, 100, 20,
+ Net::getPlayerHandler()->canUseMagic()
+ ? Theme::PROG_MP : Theme::PROG_NO_MP);
+
+ StatusWindow::updateMPBar(mMpBar);
+ }
+ else
+ {
+ mMpBar = 0;
+ }
+
+ mXpBar = new ProgressBar(0, 100, 20, Theme::PROG_EXP);
+ StatusWindow::updateXPBar(mXpBar);
+
+ mStatusBar = new ProgressBar(100, 150, 20, Theme::PROG_EXP);
+
+ mHpBar->setPosition(0, 3);
+ if (mMpBar)
+ mMpBar->setPosition(mHpBar->getWidth() + 3, 3);
+ mXpBar->setPosition(mMpBar ? mMpBar->getX() + mMpBar->getWidth() + 3 :
+ mHpBar->getX() + mHpBar->getWidth() + 3, 3);
+ mStatusBar->setPosition(mXpBar->getX() + mXpBar->getWidth() + 3, 3);
+
+ add(mHpBar);
+ if (mMpBar)
+ add(mMpBar);
+ add(mXpBar);
+ add(mStatusBar);
+
+ setContentSize(mStatusBar->getX() + mStatusBar->getWidth(),
+ mXpBar->getY() + mXpBar->getHeight());
+
+ setVisible(config.getValueBool(getPopupName() + "Visible", true));
+
+ mStatusPopup = new StatusPopup();
+ mTextPopup = new TextPopup();
+
+ addMouseListener(this);
+ updateStatus();
+}
+
+MiniStatusWindow::~MiniStatusWindow()
+{
+ delete mTextPopup;
+ mTextPopup = 0;
+ delete mStatusPopup;
+ mStatusPopup = 0;
+}
+
+void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite)
+{
+ if (index >= static_cast<int>(mIcons.size()))
+ mIcons.resize(index + 1, 0);
+
+ delete mIcons[index];
+
+ mIcons[index] = sprite;
+}
+
+void MiniStatusWindow::eraseIcon(int index)
+{
+ mIcons.erase(mIcons.begin() + index);
+}
+
+void MiniStatusWindow::drawIcons(Graphics *graphics)
+{
+ // Draw icons
+ int icon_x = mStatusBar->getX() + mStatusBar->getWidth() + 4;
+ for (unsigned int i = 0; i < mIcons.size(); i++)
+ {
+ if (mIcons[i])
+ {
+ mIcons[i]->draw(graphics, icon_x, 3);
+ icon_x += 2 + mIcons[i]->getWidth();
+ }
+ }
+}
+
+void MiniStatusWindow::event(Channels channel _UNUSED_,
+ const Mana::Event &event)
+{
+ if (event.getName() == EVENT_UPDATEATTRIBUTE)
+ {
+ int id = event.getInt("id");
+ if (id == HP || id == MAX_HP)
+ StatusWindow::updateHPBar(mHpBar);
+ else if (id == MP || id == MAX_MP)
+ StatusWindow::updateMPBar(mMpBar);
+ else if (id == EXP || id == EXP_NEEDED)
+ StatusWindow::updateXPBar(mXpBar);
+ }
+ else if (event.getName() == EVENT_UPDATESTAT)
+ {
+ StatusWindow::updateMPBar(mMpBar);
+ }
+}
+
+void MiniStatusWindow::updateStatus()
+{
+ StatusWindow::updateStatusBar(mStatusBar);
+ if (mStatusPopup && mStatusPopup->isVisible())
+ mStatusPopup->update();
+}
+
+void MiniStatusWindow::logic()
+{
+ Popup::logic();
+
+ for (unsigned int i = 0; i < mIcons.size(); i++)
+ {
+ if (mIcons[i])
+ mIcons[i]->update(tick_time * 10);
+ }
+}
+
+void MiniStatusWindow::draw(gcn::Graphics *graphics)
+{
+ drawChildren(graphics);
+}
+
+void MiniStatusWindow::mouseMoved(gcn::MouseEvent &event)
+{
+ Popup::mouseMoved(event);
+
+ const int x = event.getX();
+ const int y = event.getY();
+
+ if (event.getSource() == mStatusBar)
+ {
+ mStatusPopup->view(x + getX(), y + getY());
+ mTextPopup->hide();
+ }
+ else if (event.getSource() == mXpBar)
+ {
+ mTextPopup->show(x + getX(), y + getY(),
+ strprintf("%u/%u", PlayerInfo::getAttribute(EXP),
+ PlayerInfo::getAttribute(EXP_NEEDED)),
+ strprintf("%s: %u", _("Need"),
+ PlayerInfo::getAttribute(EXP_NEEDED)
+ - PlayerInfo::getAttribute(EXP)));
+ mStatusPopup->hide();
+ }
+ else if (event.getSource() == mHpBar)
+ {
+ mTextPopup->show(x + getX(), y + getY(),
+ strprintf("%u/%u", PlayerInfo::getAttribute(HP),
+ PlayerInfo::getAttribute(MAX_HP)));
+ mStatusPopup->hide();
+ }
+ else if (event.getSource() == mMpBar)
+ {
+ mTextPopup->show(x + getX(), y + getY(),
+ strprintf("%u/%u", PlayerInfo::getAttribute(MP),
+ PlayerInfo::getAttribute(MAX_MP)));
+ mStatusPopup->hide();
+ }
+ else
+ {
+ mTextPopup->hide();
+ mStatusPopup->hide();
+ }
+}
+
+void MiniStatusWindow::mouseExited(gcn::MouseEvent &event)
+{
+ Popup::mouseExited(event);
+
+ mTextPopup->hide();
+ mStatusPopup->hide();
+}
diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h
new file mode 100644
index 000000000..080beece3
--- /dev/null
+++ b/src/gui/ministatus.h
@@ -0,0 +1,94 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MINISTATUS_H
+#define MINISTATUS_H
+
+#include "listener.h"
+
+#include "gui/widgets/popup.h"
+#include "gui/widgets/window.h"
+
+#include <vector>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class AnimatedSprite;
+class Graphics;
+class ProgressBar;
+class StatusPopup;
+class TextPopup;
+
+/**
+ * The player mini-status dialog.
+ *
+ * \ingroup Interface
+ */
+class MiniStatusWindow : public Popup, public Mana::Listener
+{
+ public:
+ MiniStatusWindow();
+
+ ~MiniStatusWindow();
+
+ /**
+ * Sets one of the icons.
+ */
+ void setIcon(int index, AnimatedSprite *sprite);
+
+ void eraseIcon(int index);
+
+ void drawIcons(Graphics *graphics);
+
+ void event(Channels channel, const Mana::Event &event);
+
+ void updateStatus();
+
+ void logic(); // Updates icons
+
+ void draw(gcn::Graphics *graphics);
+
+ void mouseMoved(gcn::MouseEvent &mouseEvent);
+ void mouseExited(gcn::MouseEvent &event);
+
+ private:
+ bool isInBar(ProgressBar *bar, int x, int y) const;
+
+ /*
+ * Mini Status Bars
+ */
+ ProgressBar *mHpBar;
+ ProgressBar *mMpBar;
+ ProgressBar *mXpBar;
+ ProgressBar *mStatusBar;
+ TextPopup *mTextPopup;
+ StatusPopup *mStatusPopup;
+
+ std::vector<AnimatedSprite *> mIcons;
+};
+
+extern MiniStatusWindow *miniStatusWindow;
+
+#endif
diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp
new file mode 100644
index 000000000..6414da6ed
--- /dev/null
+++ b/src/gui/npcdialog.cpp
@@ -0,0 +1,483 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/npcdialog.h"
+
+#include "configuration.h"
+#include "client.h"
+
+#include "gui/setup.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/inttextfield.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/textbox.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/net.h"
+#include "net/npchandler.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+
+#define CAPTION_WAITING _("Waiting for server")
+#define CAPTION_NEXT _("Next")
+#define CAPTION_CLOSE _("Close")
+#define CAPTION_SUBMIT _("Submit")
+
+NpcDialog::DialogList NpcDialog::instances;
+
+NpcDialog::NpcDialog(int npcId)
+ : Window(_("NPC")),
+ mNpcId(npcId),
+ mLogInteraction(config.getBoolValue("logNpcInGui")),
+ mDefaultInt(0),
+ mInputState(NPC_INPUT_NONE),
+ mActionState(NPC_ACTION_WAIT),
+ mLastNextTime(0)
+{
+ // Basic Window Setup
+ setWindowName("NpcText");
+ setResizable(true);
+ //setupWindow->registerWindowForReset(this);
+ setFocusable(true);
+
+ setMinWidth(200);
+ setMinHeight(150);
+
+ setDefaultSize(260, 200, ImageRect::CENTER);
+
+ // Setup output text box
+ mTextBox = new TextBox;
+ mTextBox->setEditable(false);
+ mTextBox->setOpaque(false);
+
+ mScrollArea = new ScrollArea(mTextBox);
+ mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mScrollArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
+
+ // Setup listbox
+ mItemList = new ListBox(this);
+ mItemList->setWrappingEnabled(true);
+ setContentSize(260, 175);
+
+ mListScrollArea = new ScrollArea(mItemList);
+ mListScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mItemList->setVisible(true);
+
+ // Setup string input box
+ mTextField = new TextField("");
+ mTextField->setVisible(true);
+
+ // Setup int input box
+ mIntField = new IntTextField;
+ mIntField->setVisible(true);
+
+ mClearButton = new Button(_("Clear"), "clear", this);
+
+ // Setup button
+ mButton = new Button("", "ok", this);
+
+ //Setup more and less buttons (int input)
+ mPlusButton = new Button(_("+"), "inc", this);
+ mMinusButton = new Button(_("-"), "dec", this);
+
+ int width = std::max(mButton->getFont()->getWidth(CAPTION_WAITING),
+ mButton->getFont()->getWidth(CAPTION_NEXT));
+ width = std::max(width, mButton->getFont()->getWidth(CAPTION_CLOSE));
+ width = std::max(width, mButton->getFont()->getWidth(CAPTION_SUBMIT));
+
+ mButton->setWidth(8 + width);
+
+ mResetButton = new Button(_("Reset"), "reset", this);
+
+ // Place widgets
+ buildLayout();
+
+ center();
+ loadWindowState();
+
+ instances.push_back(this);
+ setVisible(true);
+ requestFocus();
+
+ config.addListener("logNpcInGui", this);
+}
+
+NpcDialog::~NpcDialog()
+{
+ config.removeListener("logNpcInGui", this);
+
+ // These might not actually be in the layout, so lets be safe
+ delete mScrollArea;
+ mScrollArea = 0;
+ delete mItemList;
+ mItemList = 0;
+ delete mTextField;
+ mTextField = 0;
+ delete mIntField;
+ mIntField = 0;
+ delete mResetButton;
+ mResetButton = 0;
+ delete mPlusButton;
+ mPlusButton = 0;
+ delete mMinusButton;
+ mMinusButton = 0;
+
+ instances.remove(this);
+
+}
+
+void NpcDialog::setText(const std::string &text)
+{
+ mText = text;
+
+ mTextBox->setTextWrapped(mText, mScrollArea->getWidth() - 15);
+}
+
+void NpcDialog::addText(const std::string &text, bool save)
+{
+ if (save || mLogInteraction)
+ {
+ if (mText.size() > 5000)
+ mText = "";
+
+ mNewText += text + "\n";
+ setText(mText + text + "\n");
+ }
+ mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
+ mActionState = NPC_ACTION_WAIT;
+ buildLayout();
+}
+
+void NpcDialog::showNextButton()
+{
+ mActionState = NPC_ACTION_NEXT;
+ buildLayout();
+}
+
+void NpcDialog::showCloseButton()
+{
+ mActionState = NPC_ACTION_CLOSE;
+ buildLayout();
+}
+
+void NpcDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ if (mActionState == NPC_ACTION_NEXT)
+ {
+ if (!Client::limitPackets(PACKET_NPC_NEXT))
+ return;
+
+ nextDialog();
+ // TRANSLATORS: Please leave the \n sequences intact.
+ addText(_("\n> Next\n"), false);
+ }
+ else if (mActionState == NPC_ACTION_CLOSE)
+ {
+ closeDialog();
+ }
+ else if (mActionState == NPC_ACTION_INPUT)
+ {
+ std::string printText = ""; // Text that will get printed
+ // in the textbox
+
+ if (mInputState == NPC_INPUT_LIST)
+ {
+ unsigned char choice = 0;
+ int selectedIndex = mItemList->getSelected();
+
+ if (selectedIndex >= static_cast<int>(mItems.size())
+ || selectedIndex < 0
+ || !Client::limitPackets(PACKET_NPC_INPUT))
+ {
+ return;
+ }
+ choice = static_cast<unsigned char>(selectedIndex + 1);
+ printText = mItems[selectedIndex];
+
+ Net::getNpcHandler()->listInput(mNpcId, choice);
+ }
+ else if (mInputState == NPC_INPUT_STRING)
+ {
+ if (!Client::limitPackets(PACKET_NPC_INPUT))
+ return;
+ printText = mTextField->getText();
+ Net::getNpcHandler()->stringInput(mNpcId, printText);
+ }
+ else if (mInputState == NPC_INPUT_INTEGER)
+ {
+ if (!Client::limitPackets(PACKET_NPC_INPUT))
+ return;
+ printText = strprintf("%d", mIntField->getValue());
+ Net::getNpcHandler()->integerInput(
+ mNpcId, mIntField->getValue());
+ }
+ // addText will auto remove the input layout
+ addText(strprintf("\n> \"%s\"\n", printText.c_str()), false);
+
+ mNewText.clear();
+ }
+
+ if (!mLogInteraction)
+ setText("");
+ }
+ else if (event.getId() == "reset")
+ {
+ if (mInputState == NPC_INPUT_STRING)
+ mTextField->setText(mDefaultString);
+ else if (mInputState == NPC_INPUT_INTEGER)
+ mIntField->setValue(mDefaultInt);
+ }
+ else if (event.getId() == "inc")
+ {
+ mIntField->setValue(mIntField->getValue() + 1);
+ }
+ else if (event.getId() == "dec")
+ {
+ mIntField->setValue(mIntField->getValue() - 1);
+ }
+ else if (event.getId() == "clear")
+ {
+ setText(mNewText);
+ }
+}
+
+void NpcDialog::nextDialog()
+{
+ Net::getNpcHandler()->nextDialog(mNpcId);
+}
+
+void NpcDialog::closeDialog()
+{
+ Net::getNpcHandler()->closeDialog(mNpcId);
+}
+
+int NpcDialog::getNumberOfElements()
+{
+ return static_cast<int>(mItems.size());
+}
+
+std::string NpcDialog::getElementAt(int i)
+{
+ return mItems[i];
+}
+
+void NpcDialog::choiceRequest()
+{
+ mItems.clear();
+ mActionState = NPC_ACTION_INPUT;
+ mInputState = NPC_INPUT_LIST;
+ buildLayout();
+}
+
+void NpcDialog::addChoice(const std::string &choice)
+{
+ mItems.push_back(choice);
+}
+
+void NpcDialog::parseListItems(const std::string &itemString)
+{
+ std::istringstream iss(itemString);
+
+ std::string tmp;
+ while (getline(iss, tmp, ':'))
+ mItems.push_back(tmp);
+}
+
+void NpcDialog::textRequest(const std::string &defaultText)
+{
+ mActionState = NPC_ACTION_INPUT;
+ mInputState = NPC_INPUT_STRING;
+ mDefaultString = defaultText;
+ mTextField->setText(defaultText);
+ buildLayout();
+}
+
+bool NpcDialog::isTextInputFocused() const
+{
+ return mTextField->isFocused();
+}
+
+bool NpcDialog::isInputFocused() const
+{
+ return mTextField->isFocused() || mIntField->isFocused();
+}
+
+bool NpcDialog::isAnyInputFocused()
+{
+ DialogList::iterator it = instances.begin();
+ DialogList::iterator it_end = instances.end();
+
+ for (; it != it_end; it++)
+ {
+ if ((*it)->isInputFocused())
+ return true;
+ }
+
+ return false;
+}
+
+void NpcDialog::integerRequest(int defaultValue, int min, int max)
+{
+ mActionState = NPC_ACTION_INPUT;
+ mInputState = NPC_INPUT_INTEGER;
+ mDefaultInt = defaultValue;
+ mIntField->setRange(min, max);
+ mIntField->setValue(defaultValue);
+ buildLayout();
+}
+
+void NpcDialog::move(int amount)
+{
+ if (mActionState != NPC_ACTION_INPUT)
+ return;
+
+ switch (mInputState)
+ {
+ case NPC_INPUT_INTEGER:
+ mIntField->setValue(mIntField->getValue() + amount);
+ break;
+ case NPC_INPUT_LIST:
+ mItemList->setSelected(mItemList->getSelected() - amount);
+ break;
+ case NPC_INPUT_NONE:
+ case NPC_INPUT_STRING:
+ default:
+ break;
+ }
+}
+
+void NpcDialog::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+
+ setText(mText);
+}
+
+void NpcDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (!visible)
+ scheduleDelete();
+}
+
+void NpcDialog::optionChanged(const std::string &name)
+{
+ if (name == "logNpcInGui")
+ mLogInteraction = config.getBoolValue("logNpcInGui");
+}
+
+NpcDialog *NpcDialog::getActive()
+{
+ if (instances.size() == 1)
+ return instances.front();
+
+ DialogList::iterator it = instances.begin();
+ DialogList::iterator it_end = instances.end();
+
+ for (; it != it_end; it++)
+ {
+ if ((*it)->isFocused())
+ return (*it);
+ }
+
+ return 0;
+}
+
+void NpcDialog::closeAll()
+{
+ DialogList::iterator it = instances.begin();
+ DialogList::iterator it_end = instances.end();
+
+ for (; it != it_end; it++)
+ (*it)->close();
+}
+
+void NpcDialog::buildLayout()
+{
+ clearLayout();
+
+ if (mActionState != NPC_ACTION_INPUT)
+ {
+ if (mActionState == NPC_ACTION_WAIT)
+ mButton->setCaption(CAPTION_WAITING);
+ else if (mActionState == NPC_ACTION_NEXT)
+ mButton->setCaption(CAPTION_NEXT);
+ else if (mActionState == NPC_ACTION_CLOSE)
+ mButton->setCaption(CAPTION_CLOSE);
+ place(0, 0, mScrollArea, 5, 3);
+ place(3, 3, mClearButton);
+ place(4, 3, mButton);
+ }
+ else if (mInputState != NPC_INPUT_NONE)
+ {
+ if (!mLogInteraction)
+ setText(mNewText);
+
+ mButton->setCaption(CAPTION_SUBMIT);
+ if (mInputState == NPC_INPUT_LIST)
+ {
+ place(0, 0, mScrollArea, 6, 3);
+ place(0, 3, mListScrollArea, 6, 3);
+ place(2, 6, mClearButton, 2);
+ place(4, 6, mButton, 2);
+
+ mItemList->setSelected(-1);
+ }
+ else if (mInputState == NPC_INPUT_STRING)
+ {
+ place(0, 0, mScrollArea, 6, 3);
+ place(0, 3, mTextField, 6);
+ place(0, 4, mResetButton, 2);
+ place(2, 4, mClearButton, 2);
+ place(4, 4, mButton, 2);
+ }
+ else if (mInputState == NPC_INPUT_INTEGER)
+ {
+ place(0, 0, mScrollArea, 6, 3);
+ place(0, 3, mMinusButton, 1);
+ place(1, 3, mIntField, 4);
+ place(5, 3, mPlusButton, 1);
+ place(0, 4, mResetButton, 2);
+ place(2, 4, mClearButton, 2);
+ place(4, 4, mButton, 2);
+ }
+ }
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+
+ mButton->setEnabled(mActionState != NPC_ACTION_WAIT);
+
+ redraw();
+
+ mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
+} \ No newline at end of file
diff --git a/src/gui/npcdialog.h b/src/gui/npcdialog.h
new file mode 100644
index 000000000..eee4b32e2
--- /dev/null
+++ b/src/gui/npcdialog.h
@@ -0,0 +1,232 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NPCDIALOG_H
+#define NPCDIALOG_H
+
+#include "configlistener.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/listmodel.hpp>
+
+#include <list>
+#include <string>
+#include <vector>
+
+class TextBox;
+class ListBox;
+class TextField;
+class IntTextField;
+class Button;
+
+/**
+ * The npc dialog.
+ *
+ * \ingroup Interface
+ */
+class NpcDialog : public Window, public gcn::ActionListener,
+ public gcn::ListModel, public ConfigListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ NpcDialog(int npcId);
+
+ ~NpcDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Sets the text shows in the dialog.
+ *
+ * @param string The new text.
+ */
+ void setText(const std::string &string);
+
+ /**
+ * Adds the text to the text shows in the dialog. Also adds a newline
+ * to the end.
+ *
+ * @param string The text to add.
+ */
+ void addText(const std::string &string, bool save = true);
+
+ /**
+ * When called, the widget will show a "Next" button.
+ */
+ void showNextButton();
+
+ /**
+ * When called, the widget will show a "Close" button and will close
+ * the dialog when clicked.
+ */
+ void showCloseButton();
+
+ /**
+ * Notifies the server that client has performed a next action.
+ */
+ void nextDialog();
+
+ /**
+ * Notifies the server that the client has performed a close action.
+ */
+ void closeDialog();
+
+ /**
+ * Returns the number of items in the choices list.
+ */
+ int getNumberOfElements();
+
+ /**
+ * Returns the name of item number i of the choices list.
+ */
+ std::string getElementAt(int i);
+
+ /**
+ * Makes this dialog request a choice selection from the user.
+ */
+ void choiceRequest();
+
+ /**
+ * Adds a choice to the list box.
+ */
+ void addChoice(const std::string &);
+
+ /**
+ * Fills the options list for an NPC dialog.
+ *
+ * @param itemString A string with the options separated with colons.
+ */
+ void parseListItems(const std::string &itemString);
+
+ /**
+ * Requests a text string from the user.
+ */
+ void textRequest(const std::string &defaultText = "");
+
+ bool isInputFocused() const;
+
+ bool isTextInputFocused() const;
+
+ static bool isAnyInputFocused();
+
+ /**
+ * Requests a interger from the user.
+ */
+ void integerRequest(int defaultValue = 0, int min = 0,
+ int max = 2147483647);
+
+ void move(int amount);
+
+ /**
+ * Called when resizing the window.
+ *
+ * @param event The calling event
+ */
+ void widgetResized(const gcn::Event &event);
+
+ void setVisible(bool visible);
+
+ void optionChanged(const std::string &name);
+
+ /**
+ * Returns true if any instances exist.
+ */
+ static bool isActive() { return !instances.empty(); }
+
+ /**
+ * Returns the first active instance. Useful for pushing user
+ * interaction.
+ */
+ static NpcDialog *getActive();
+
+ /**
+ * Closes all instances.
+ */
+ static void closeAll();
+
+ private:
+ typedef std::list<NpcDialog*> DialogList;
+ static DialogList instances;
+
+ void buildLayout();
+
+ int mNpcId;
+ bool mLogInteraction;
+
+ int mDefaultInt;
+ std::string mDefaultString;
+
+ // Used for the main input area
+ gcn::ScrollArea *mScrollArea;
+ TextBox *mTextBox;
+ std::string mText;
+ std::string mNewText;
+
+ // Used for choice input
+ ListBox *mItemList;
+ gcn::ScrollArea *mListScrollArea;
+ std::vector<std::string> mItems;
+
+ // Used for string and integer input
+ TextField *mTextField;
+ IntTextField *mIntField;
+ Button *mPlusButton;
+ Button *mMinusButton;
+
+ Button *mClearButton;
+
+ // Used for the button
+ Button *mButton;
+
+ // Will reset the text and integer input to the provided default
+ Button *mResetButton;
+
+ enum NpcInputState
+ {
+ NPC_INPUT_NONE = 0,
+ NPC_INPUT_LIST,
+ NPC_INPUT_STRING,
+ NPC_INPUT_INTEGER
+ };
+
+ enum NpcActionState
+ {
+ NPC_ACTION_WAIT = 0,
+ NPC_ACTION_NEXT,
+ NPC_ACTION_INPUT,
+ NPC_ACTION_CLOSE
+ };
+
+ NpcInputState mInputState;
+ NpcActionState mActionState;
+ int mLastNextTime;
+};
+
+#endif // NPCDIALOG_H
diff --git a/src/gui/npcpostdialog.cpp b/src/gui/npcpostdialog.cpp
new file mode 100644
index 000000000..00bf55028
--- /dev/null
+++ b/src/gui/npcpostdialog.cpp
@@ -0,0 +1,128 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/npcpostdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/textbox.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/scrollarea.h"
+
+#include "net/net.h"
+#include "net/npchandler.h"
+
+#include "utils/gettext.h"
+
+NpcPostDialog::DialogList NpcPostDialog::instances;
+
+NpcPostDialog::NpcPostDialog(int npcId):
+ Window(_("NPC")),
+ mNpcId(npcId)
+{
+ setContentSize(400, 180);
+
+ // create text field for receiver
+ gcn::Label *senderText = new Label(_("To:"));
+ senderText->setPosition(5, 5);
+ mSender = new TextField;
+ mSender->setPosition(senderText->getWidth() + 5, 5);
+ mSender->setWidth(65);
+
+ // create button for sending
+ Button *sendButton = new Button(_("Send"), "send", this);
+ sendButton->setPosition(400 - sendButton->getWidth(),
+ 170 - sendButton->getHeight());
+ Button *cancelButton = new Button(_("Cancel"), "cancel", this);
+ cancelButton->setPosition(sendButton->getX()
+ - (cancelButton->getWidth() + 2), sendButton->getY());
+
+ // create textfield for letter
+ mText = new TextBox;
+ mText->setHeight(400 - (mSender->getHeight() + sendButton->getHeight()));
+ mText->setEditable(true);
+
+ // create scroll box for letter text
+ ScrollArea *scrollArea = new ScrollArea(mText);
+ scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ scrollArea->setDimension(gcn::Rectangle(
+ 5, mSender->getHeight() + 5,
+ 380, 140 - (mSender->getHeight() + sendButton->getHeight())));
+
+ add(senderText);
+ add(mSender);
+ add(scrollArea);
+ add(sendButton);
+ add(cancelButton);
+
+ setLocationRelativeTo(getParent());
+
+ instances.push_back(this);
+ setVisible(true);
+}
+
+NpcPostDialog::~NpcPostDialog()
+{
+ instances.remove(this);
+}
+
+void NpcPostDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "send")
+ {
+ if (mSender->getText().empty() || mText->getText().empty())
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(_("Failed to send as sender or letter "
+ "invalid."));
+ }
+ }
+ else
+ {
+ Net::getNpcHandler()->sendLetter(mNpcId, mSender->getText(),
+ mText->getText());
+ }
+ setVisible(false);
+ }
+ else if (event.getId() == "cancel")
+ {
+ setVisible(false);
+ }
+}
+
+void NpcPostDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (!visible)
+ scheduleDelete();
+}
+
+void NpcPostDialog::closeAll()
+{
+ DialogList::iterator it = instances.begin();
+ DialogList::iterator it_end = instances.end();
+
+ for (; it != it_end; it++)
+ (*it)->close();
+} \ No newline at end of file
diff --git a/src/gui/npcpostdialog.h b/src/gui/npcpostdialog.h
new file mode 100644
index 000000000..6cc64d1e2
--- /dev/null
+++ b/src/gui/npcpostdialog.h
@@ -0,0 +1,70 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_NPCPOSTDIALOG_H
+#define GUI_NPCPOSTDIALOG_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class TextBox;
+class TextField;
+
+class NpcPostDialog : public Window, public gcn::ActionListener
+{
+public:
+ /**
+ * Constructor
+ */
+ NpcPostDialog(int npcId);
+
+ ~NpcPostDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ void setVisible(bool visible);
+
+ /**
+ * Returns true if any instances exist.
+ */
+ static bool isActive()
+ { return !instances.empty(); }
+
+ /**
+ * Closes all instances.
+ */
+ static void closeAll();
+
+private:
+ typedef std::list<NpcPostDialog*> DialogList;
+ static DialogList instances;
+
+ int mNpcId;
+
+ TextBox *mText;
+ TextField *mSender;
+};
+
+#endif
diff --git a/src/gui/okdialog.cpp b/src/gui/okdialog.cpp
new file mode 100644
index 000000000..9812a171f
--- /dev/null
+++ b/src/gui/okdialog.cpp
@@ -0,0 +1,81 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/okdialog.h"
+
+#include "gui/gui.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/textbox.h"
+
+#include "utils/gettext.h"
+
+#include <guichan/font.hpp>
+
+OkDialog::OkDialog(const std::string &title, const std::string &msg,
+ bool modal, bool showCenter, Window *parent):
+ Window(title, modal, parent)
+{
+ mTextBox = new TextBox;
+ mTextBox->setEditable(false);
+ mTextBox->setOpaque(false);
+ mTextBox->setTextWrapped(msg, 260);
+
+ gcn::Button *okButton = new Button(_("OK"), "ok", this);
+
+ const int numRows = mTextBox->getNumberOfRows();
+ const int fontHeight = getFont()->getHeight();
+ const int height = numRows * fontHeight;
+ int width = getFont()->getWidth(title);
+
+ if (width < mTextBox->getMinWidth())
+ width = mTextBox->getMinWidth();
+ if (width < okButton->getWidth())
+ width = okButton->getWidth();
+
+ setContentSize(mTextBox->getMinWidth() + fontHeight, height +
+ fontHeight + okButton->getHeight());
+ mTextBox->setPosition(getPadding(), getPadding());
+
+ // 8 is the padding that GUIChan adds to button widgets
+ // (top and bottom combined)
+ okButton->setPosition((width - okButton->getWidth()) / 2, height + 8);
+
+ add(mTextBox);
+ add(okButton);
+
+ if (showCenter)
+ center();
+ else
+ centerHorisontally();
+ setVisible(true);
+ okButton->requestFocus();
+}
+
+void OkDialog::action(const gcn::ActionEvent &event)
+{
+ setActionEventId(event.getId());
+ distributeActionEvent();
+
+ // Can we receive anything else anyway?
+ if (event.getId() == "ok")
+ scheduleDelete();
+}
diff --git a/src/gui/okdialog.h b/src/gui/okdialog.h
new file mode 100644
index 000000000..b7db20d79
--- /dev/null
+++ b/src/gui/okdialog.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef OK_DIALOG_H
+#define OK_DIALOG_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class TextBox;
+
+/**
+ * An 'Ok' button dialog.
+ *
+ * \ingroup GUI
+ */
+class OkDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ OkDialog(const std::string &title, const std::string &msg,
+ bool modal = true, bool showCenter = true,
+ Window *parent = NULL);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ TextBox *mTextBox;
+};
+
+#endif
diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp
new file mode 100644
index 000000000..770c77572
--- /dev/null
+++ b/src/gui/outfitwindow.cpp
@@ -0,0 +1,914 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/outfitwindow.h"
+
+#include "configuration.h"
+#include "equipment.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "log.h"
+#include "playerinfo.h"
+
+#include "gui/chat.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <vector>
+
+float OutfitWindow::mAlpha = 1.0;
+
+OutfitWindow::OutfitWindow():
+ Window(_("Outfits")),
+ mBoxWidth(33),
+ mBoxHeight(33),
+ mGridWidth(4),
+ mGridHeight(3),
+ mItemClicked(false),
+ mItemMoved(NULL),
+ mItemSelected(-1),
+ mCurrentOutfit(0),
+ mAwayOutfit(0)
+{
+ setWindowName("Outfits");
+ setResizable(true);
+ setCloseButton(true);
+ setDefaultSize(250, 400, 150, 230);
+ setMinWidth(145);
+ setMinHeight(220);
+
+ addMouseListener(this);
+
+ mPreviousButton = new Button(_("<"), "previous", this);
+ mNextButton = new Button(_(">"), "next", this);
+ mCurrentLabel = new Label(strprintf(_("Outfit: %d"), 1));
+ mCurrentLabel->setAlignment(gcn::Graphics::CENTER);
+ mKeyLabel = new Label(strprintf(_("Key: %s"),
+ keyName(mCurrentOutfit).c_str()));
+ mKeyLabel->setAlignment(gcn::Graphics::CENTER);
+ mUnequipCheck = new CheckBox(_("Unequip first"),
+ serverConfig.getValueBool("OutfitUnequip0", true));
+
+ mAwayOutfitCheck = new CheckBox(_("Away outfit"),
+ serverConfig.getValue("OutfitAwayIndex", OUTFITS_COUNT - 1));
+
+ mUnequipCheck->setActionEventId("unequip");
+ mUnequipCheck->addActionListener(this);
+
+ mAwayOutfitCheck->setActionEventId("away");
+ mAwayOutfitCheck->addActionListener(this);
+
+ place(0, 3, mKeyLabel, 4);
+ place(0, 4, mPreviousButton, 1);
+ place(1, 4, mCurrentLabel, 2);
+ place(3, 4, mNextButton, 1);
+ place(0, 5, mUnequipCheck, 4);
+ place(0, 6, mAwayOutfitCheck, 4);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+ layout.setColWidth(4, Layout::CENTER);
+
+ loadWindowState();
+
+ load();
+}
+
+OutfitWindow::~OutfitWindow()
+{
+ save();
+}
+
+void OutfitWindow::load(bool oldConfig)
+{
+ Configuration *cfg;
+ if (oldConfig)
+ cfg = &config;
+ else
+ cfg = &serverConfig;
+
+ memset(mItems, -1, sizeof(mItems));
+
+ for (int o = 0; o < OUTFITS_COUNT; o++)
+ {
+ std::string outfit = cfg->getValue("Outfit" + toString(o), "-1");
+ std::string buf;
+ std::stringstream ss(outfit);
+
+ std::vector<int> tokens;
+
+ while (ss >> buf)
+ tokens.push_back(atoi(buf.c_str()));
+
+ for (int i = 0; i < static_cast<int>(tokens.size())
+ && i < OUTFIT_ITEM_COUNT; i++)
+ {
+ mItems[o][i] = tokens[i];
+ }
+
+ mItemsUnequip[o] = cfg->getValueBool("OutfitUnequip" + toString(o),
+ true);
+ }
+ mAwayOutfit = cfg->getValue("OutfitAwayIndex", OUTFITS_COUNT - 1);
+ if (mAwayOutfit >= OUTFITS_COUNT)
+ mAwayOutfit = OUTFITS_COUNT - 1;
+
+ if (mAwayOutfitCheck)
+ mAwayOutfitCheck->setSelected(mAwayOutfit == mCurrentOutfit);
+}
+
+void OutfitWindow::save()
+{
+ std::string outfitStr;
+ for (int o = 0; o < OUTFITS_COUNT; o++)
+ {
+ for (int i = 0; i < OUTFIT_ITEM_COUNT; i++)
+ {
+ outfitStr += mItems[o][i] ? toString(mItems[o][i]) : toString(-1);
+ if (i < OUTFIT_ITEM_COUNT - 1)
+ outfitStr += " ";
+ }
+ serverConfig.setValue("Outfit" + toString(o), outfitStr);
+ serverConfig.setValue("OutfitUnequip" + toString(o), mItemsUnequip[o]);
+ outfitStr = "";
+ }
+ serverConfig.setValue("OutfitAwayIndex", mAwayOutfit);
+}
+
+void OutfitWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "next")
+ {
+ next();
+ }
+ else if (event.getId() == "previous")
+ {
+ previous();
+ }
+ else if (event.getId() == "unequip")
+ {
+ if (mCurrentOutfit < OUTFITS_COUNT)
+ mItemsUnequip[mCurrentOutfit] = mUnequipCheck->isSelected();
+ }
+ else if (event.getId() == "away")
+ {
+ mAwayOutfit = mCurrentOutfit;
+ if (!mAwayOutfitCheck->isSelected())
+ mAwayOutfitCheck->setSelected(true);
+ }
+}
+
+void OutfitWindow::wearOutfit(int outfit, bool unwearEmpty, bool select)
+{
+ bool isEmpty = true;
+
+ Item *item;
+ if (outfit < 0 || outfit > OUTFITS_COUNT)
+ return;
+
+ for (int i = 0; i < OUTFIT_ITEM_COUNT; i++)
+ {
+ item = PlayerInfo::getInventory()->findItem(mItems[outfit][i]);
+ if (item && !item->isEquipped() && item->getQuantity())
+ {
+ if (item->isEquipment())
+ {
+ Net::getInventoryHandler()->equipItem(item);
+ isEmpty = false;
+ }
+ }
+ }
+
+ if ((!isEmpty || unwearEmpty) && outfit < OUTFITS_COUNT
+ && mItemsUnequip[outfit])
+ {
+ unequipNotInOutfit(outfit);
+ }
+ if (select)
+ {
+ mCurrentOutfit = outfit;
+ showCurrentOutfit();
+ }
+}
+
+void OutfitWindow::copyOutfit(int outfit)
+{
+ copyOutfit(outfit, mCurrentOutfit);
+}
+
+void OutfitWindow::copyOutfit(int src, int dst)
+{
+ if (src < 0 || src > OUTFITS_COUNT
+ || dst < 0 || dst > OUTFITS_COUNT)
+ {
+ return;
+ }
+
+ for (int i = 0; i < OUTFIT_ITEM_COUNT; i++)
+ {
+ mItems[dst][i] = mItems[src][i];
+ }
+}
+
+void OutfitWindow::draw(gcn::Graphics *graphics)
+{
+ Window::draw(graphics);
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ for (int i = 0; i < OUTFIT_ITEM_COUNT; i++)
+ {
+ const int itemX = 10 + ((i % mGridWidth) * mBoxWidth);
+ const int itemY = 25 + ((i / mGridWidth) * mBoxHeight);
+
+ graphics->setColor(gcn::Color(0, 0, 0, 64));
+ graphics->drawRectangle(gcn::Rectangle(itemX, itemY, 32, 32));
+ graphics->setColor(gcn::Color(255, 255, 255, 32));
+ graphics->fillRectangle(gcn::Rectangle(itemX, itemY, 32, 32));
+
+ if (mItems[mCurrentOutfit][i] < 0)
+ continue;
+
+ bool foundItem = false;
+ Inventory *inv = PlayerInfo::getInventory();
+ if (inv)
+ {
+ Item *item = inv->findItem(mItems[mCurrentOutfit][i]);
+ if (item)
+ {
+ // Draw item icon.
+ Image* image = item->getImage();
+ if (image)
+ {
+ g->drawImage(image, itemX, itemY);
+ foundItem = true;
+ }
+ }
+ }
+ if (!foundItem)
+ {
+ Image *image = Item::getImage(mItems[mCurrentOutfit][i]);
+ if (image)
+ g->drawImage(image, itemX, itemY);
+ }
+ }
+ if (mItemMoved)
+ {
+ // Draw the item image being dragged by the cursor.
+ Image* image = mItemMoved->getImage();
+ if (image)
+ {
+ const int tPosX = mCursorPosX - (image->getWidth() / 2);
+ const int tPosY = mCursorPosY - (image->getHeight() / 2);
+
+ g->drawImage(image, tPosX, tPosY);
+ }
+ }
+}
+
+
+void OutfitWindow::mouseDragged(gcn::MouseEvent &event)
+{
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (!mItemMoved && mItemClicked)
+ {
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1)
+ {
+ Window::mouseDragged(event);
+ return;
+ }
+ const int itemId = mItems[mCurrentOutfit][index];
+ if (itemId < 0)
+ {
+ Window::mouseDragged(event);
+ return;
+ }
+ mMoved = false;
+ event.consume();
+ Inventory *inv = PlayerInfo::getInventory();
+ if (inv)
+ {
+ Item *item = inv->findItem(itemId);
+ if (item)
+ mItemMoved = item;
+ else
+ mItemMoved = 0;
+ mItems[mCurrentOutfit][index] = -1;
+ }
+ }
+ if (mItemMoved)
+ {
+ mCursorPosX = event.getX();
+ mCursorPosY = event.getY();
+ }
+ }
+ Window::mouseDragged(event);
+}
+
+void OutfitWindow::mousePressed(gcn::MouseEvent &event)
+{
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1)
+ {
+ if (event.getButton() == gcn::MouseEvent::RIGHT && viewport)
+ viewport->showOutfitsPopup();
+ Window::mousePressed(event);
+ return;
+ }
+ mMoved = false;
+ event.consume();
+
+ // Stores the selected item if there is one.
+ if (isItemSelected())
+ {
+ mItems[mCurrentOutfit][index] = mItemSelected;
+ mItemSelected = -1;
+ }
+ else if (mItems[mCurrentOutfit][index])
+ {
+ mItemClicked = true;
+ }
+ Window::mousePressed(event);
+}
+
+void OutfitWindow::mouseReleased(gcn::MouseEvent &event)
+{
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (isItemSelected())
+ mItemSelected = -1;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1)
+ {
+ mItemMoved = NULL;
+ Window::mouseReleased(event);
+ return;
+ }
+ mMoved = false;
+ event.consume();
+ if (mItemMoved)
+ {
+ mItems[mCurrentOutfit][index] = mItemMoved->getId();
+ mItemMoved = NULL;
+ }
+ if (mItemClicked)
+ mItemClicked = false;
+ }
+ Window::mouseReleased(event);
+}
+
+int OutfitWindow::getIndexFromGrid(int pointX, int pointY) const
+{
+ const gcn::Rectangle tRect = gcn::Rectangle(
+ 10, 25, mGridWidth * mBoxWidth, mGridHeight * mBoxHeight);
+ if (!tRect.isPointInRect(pointX, pointY))
+ return -1;
+ const int index = (((pointY - 25) / mBoxHeight) * mGridWidth) +
+ (pointX - 10) / mBoxWidth;
+ if (index >= OUTFIT_ITEM_COUNT || index < 0)
+ return -1;
+ return index;
+}
+
+void OutfitWindow::unequipNotInOutfit(int outfit)
+{
+ // here we think that outfit is correct index
+
+ Inventory *inventory = PlayerInfo::getInventory();
+ if (!inventory)
+ return;
+
+ for (unsigned i = 0; i < inventory->getSize(); i++)
+ {
+ if (inventory->getItem(i) && inventory->getItem(i)->isEquipped())
+ {
+ bool found = false;
+ for (unsigned f = 0; f < OUTFIT_ITEM_COUNT; f++)
+ {
+ if (inventory->getItem(i)->getId() == mItems[outfit][f])
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ Net::getInventoryHandler()->unequipItem(inventory->getItem(i));
+ }
+ }
+}
+
+int OutfitWindow::keyToNumber(SDLKey key)
+{
+ int outfitNum = -1;
+ switch (key)
+ {
+ case SDLK_1:
+ case SDLK_2:
+ case SDLK_3:
+ case SDLK_4:
+ case SDLK_5:
+ case SDLK_6:
+ case SDLK_7:
+ case SDLK_8:
+ case SDLK_9:
+ outfitNum = key - SDLK_1;
+ break;
+
+ case SDLK_0:
+ outfitNum = 9;
+ break;
+
+ case SDLK_MINUS:
+ outfitNum = 10;
+ break;
+
+ case SDLK_EQUALS:
+ outfitNum = 11;
+ break;
+
+ case SDLK_BACKSPACE:
+ outfitNum = 12;
+ break;
+
+ case SDLK_INSERT:
+ outfitNum = 13;
+ break;
+
+ case SDLK_HOME:
+ outfitNum = 14;
+ break;
+
+ case SDLK_q:
+ outfitNum = 15;
+ break;
+
+ case SDLK_w:
+ outfitNum = 16;
+ break;
+
+ case SDLK_e:
+ outfitNum = 17;
+ break;
+
+ case SDLK_r:
+ outfitNum = 18;
+ break;
+
+ case SDLK_t:
+ outfitNum = 19;
+ break;
+
+ case SDLK_y:
+ outfitNum = 20;
+ break;
+
+ case SDLK_u:
+ outfitNum = 21;
+ break;
+
+ case SDLK_i:
+ outfitNum = 22;
+ break;
+
+ case SDLK_o:
+ outfitNum = 23;
+ break;
+
+ case SDLK_p:
+ outfitNum = 24;
+ break;
+
+ case SDLK_LEFTBRACKET:
+ outfitNum = 25;
+ break;
+
+ case SDLK_RIGHTBRACKET:
+ outfitNum = 26;
+ break;
+
+ case SDLK_BACKSLASH:
+ outfitNum = 27;
+ break;
+
+ case SDLK_a:
+ outfitNum = 28;
+ break;
+
+ case SDLK_s:
+ outfitNum = 29;
+ break;
+
+ case SDLK_d:
+ outfitNum = 30;
+ break;
+
+ case SDLK_f:
+ outfitNum = 31;
+ break;
+
+ case SDLK_g:
+ outfitNum = 32;
+ break;
+
+ case SDLK_h:
+ outfitNum = 33;
+ break;
+
+ case SDLK_j:
+ outfitNum = 34;
+ break;
+
+ case SDLK_k:
+ outfitNum = 35;
+ break;
+
+ case SDLK_l:
+ outfitNum = 36;
+ break;
+
+ case SDLK_SEMICOLON:
+ outfitNum = 37;
+ break;
+
+ case SDLK_QUOTE:
+ outfitNum = 38;
+ break;
+
+ case SDLK_z:
+ outfitNum = 39;
+ break;
+
+
+ case SDLK_x:
+ outfitNum = 40;
+ break;
+
+ case SDLK_c:
+ outfitNum = 41;
+ break;
+
+ case SDLK_v:
+ outfitNum = 42;
+ break;
+
+ case SDLK_b:
+ outfitNum = 43;
+ break;
+
+ case SDLK_n:
+ outfitNum = 44;
+ break;
+
+ case SDLK_m:
+ outfitNum = 45;
+ break;
+
+ case SDLK_COMMA:
+ outfitNum = 46;
+ break;
+
+ case SDLK_PERIOD:
+ outfitNum = 47;
+ break;
+
+ case SDLK_SLASH:
+ outfitNum = 48;
+ break;
+
+ default:
+ break;
+ }
+
+ return outfitNum;
+}
+
+SDLKey OutfitWindow::numberToKey(int number)
+{
+ SDLKey key = SDLK_UNKNOWN;
+ switch (number)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ key = static_cast<SDLKey>(
+ static_cast<unsigned int>(SDLK_1) + number);
+ break;
+
+ case 9:
+ key = SDLK_0;
+ break;
+
+ case 10:
+ key = SDLK_MINUS;
+ break;
+
+ case 11:
+ key = SDLK_EQUALS;
+ break;
+
+ case 12:
+ key = SDLK_BACKSPACE;
+ break;
+
+ case 13:
+ key = SDLK_INSERT;
+ break;
+
+ case 14:
+ key = SDLK_HOME;
+ break;
+
+ case 15:
+ key = SDLK_q;
+ break;
+
+ case 16:
+ key = SDLK_w;
+ break;
+
+ case 17:
+ key = SDLK_e;
+ break;
+
+ case 18:
+ key = SDLK_r;
+ break;
+
+ case 19:
+ key = SDLK_t;
+ break;
+
+ case 20:
+ key = SDLK_y;
+ break;
+
+ case 21:
+ key = SDLK_u;
+ break;
+
+ case 22:
+ key = SDLK_i;
+ break;
+
+ case 23:
+ key = SDLK_o;
+ break;
+
+ case 24:
+ key = SDLK_p;
+ break;
+
+ case 25:
+ key = SDLK_LEFTBRACKET;
+ break;
+
+ case 26:
+ key = SDLK_RIGHTBRACKET;
+ break;
+
+ case 27:
+ key = SDLK_BACKSLASH;
+ break;
+
+ case 28:
+ key = SDLK_a;
+ break;
+
+ case 29:
+ key = SDLK_s;
+ break;
+
+ case 30:
+ key = SDLK_d;
+ break;
+
+ case 31:
+ key = SDLK_f;
+ break;
+
+ case 32:
+ key = SDLK_g;
+ break;
+
+ case 33:
+ key = SDLK_h;
+ break;
+
+ case 34:
+ key = SDLK_j;
+ break;
+
+ case 35:
+ key = SDLK_k;
+ break;
+
+ case 36:
+ key = SDLK_l;
+ break;
+
+ case 37:
+ key = SDLK_SEMICOLON;
+ break;
+
+ case 38:
+ key = SDLK_QUOTE;
+ break;
+
+ case 39:
+ key = SDLK_z;
+ break;
+
+
+ case 40:
+ key = SDLK_x;
+ break;
+
+ case 41:
+ key = SDLK_c;
+ break;
+
+ case 42:
+ key = SDLK_v;
+ break;
+
+ case 43:
+ key = SDLK_b;
+ break;
+
+ case 44:
+ key = SDLK_n;
+ break;
+
+ case 45:
+ key = SDLK_m;
+ break;
+
+ case 46:
+ key = SDLK_COMMA;
+ break;
+
+ case 47:
+ key = SDLK_PERIOD;
+ break;
+
+ case 48:
+ key = SDLK_SLASH;
+ break;
+
+ default:
+ break;
+ }
+
+ return key;
+}
+
+std::string OutfitWindow::keyName(int number)
+{
+ return SDL_GetKeyName(numberToKey(number));
+}
+
+void OutfitWindow::next()
+{
+ if (mCurrentOutfit < (OUTFITS_COUNT - 1))
+ mCurrentOutfit++;
+ else
+ mCurrentOutfit = 0;
+ showCurrentOutfit();
+}
+
+void OutfitWindow::previous()
+{
+ if (mCurrentOutfit > 0)
+ mCurrentOutfit--;
+ else
+ mCurrentOutfit = OUTFITS_COUNT - 1;
+ showCurrentOutfit();
+}
+
+void OutfitWindow::showCurrentOutfit()
+{
+ mCurrentLabel->setCaption(strprintf(_("Outfit: %d"), mCurrentOutfit + 1));
+ mUnequipCheck->setSelected(mItemsUnequip[mCurrentOutfit]);
+ mKeyLabel->setCaption(strprintf(_("Key: %s"),
+ keyName(mCurrentOutfit).c_str()));
+ mAwayOutfitCheck->setSelected(mAwayOutfit == mCurrentOutfit);
+}
+
+void OutfitWindow::wearNextOutfit(bool all)
+{
+ bool fromStart = false;
+ next();
+ if (!all && mCurrentOutfit < OUTFITS_COUNT)
+ {
+ while (!mItemsUnequip[mCurrentOutfit])
+ {
+ next();
+ if (mCurrentOutfit == 0)
+ {
+ if (!fromStart)
+ fromStart = true;
+ else
+ return;
+ }
+ }
+ }
+ wearOutfit(mCurrentOutfit);
+}
+
+void OutfitWindow::wearPreviousOutfit(bool all)
+{
+ bool fromStart = false;
+ previous();
+ if (!all && mCurrentOutfit < OUTFITS_COUNT)
+ {
+ while (!mItemsUnequip[mCurrentOutfit])
+ {
+ previous();
+ if (mCurrentOutfit == 0)
+ {
+ if (!fromStart)
+ fromStart = true;
+ else
+ return;
+ }
+ }
+ }
+ wearOutfit(mCurrentOutfit);
+}
+
+void OutfitWindow::copyFromEquiped()
+{
+ copyFromEquiped(mCurrentOutfit);
+}
+
+void OutfitWindow::copyFromEquiped(int dst)
+{
+ Inventory *inventory = PlayerInfo::getInventory();
+ if (!inventory)
+ return;
+
+ int outfitCell = 0;
+
+ for (unsigned i = 0; i < inventory->getSize(); i++)
+ {
+ if (inventory->getItem(i) && inventory->getItem(i)->isEquipped())
+ {
+ mItems[dst][outfitCell++] = inventory->getItem(i)->getId();
+ if (outfitCell > 8)
+ break;
+ }
+ }
+}
+
+void OutfitWindow::wearAwayOutfit()
+{
+ copyFromEquiped(OUTFITS_COUNT);
+ wearOutfit(mAwayOutfit, false);
+}
+
+void OutfitWindow::unwearAwayOutfit()
+{
+ wearOutfit(OUTFITS_COUNT);
+}
diff --git a/src/gui/outfitwindow.h b/src/gui/outfitwindow.h
new file mode 100644
index 000000000..684d1c6f1
--- /dev/null
+++ b/src/gui/outfitwindow.h
@@ -0,0 +1,135 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef OUTFITWINDOW_H
+#define OUTFITWINDOW_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/mouselistener.hpp>
+
+#define OUTFITS_COUNT 100
+#define OUTFIT_ITEM_COUNT 12
+
+class Button;
+class CheckBox;
+class Item;
+class Label;
+
+class OutfitWindow : public Window, gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ OutfitWindow();
+
+ /**
+ * Destructor.
+ */
+ ~OutfitWindow();
+
+ void action(const gcn::ActionEvent &event);
+
+ void draw(gcn::Graphics *graphics);
+
+ void mousePressed(gcn::MouseEvent &event);
+
+ void mouseDragged(gcn::MouseEvent &event);
+
+ void mouseReleased(gcn::MouseEvent &event);
+
+ void load(bool oldConfig = false);
+
+ void setItemSelected(int itemId)
+ { mItemSelected = itemId; }
+
+ bool isItemSelected()
+ { return mItemSelected > 0; }
+
+ void wearOutfit(int outfit, bool unwearEmpty = true,
+ bool select = false);
+
+ void copyOutfit(int outfit);
+
+ void copyOutfit(int src, int dst);
+
+ void copyFromEquiped();
+
+ void copyFromEquiped(int dst);
+
+ void unequipNotInOutfit(int outfit);
+
+ int keyToNumber(SDLKey key);
+
+ SDLKey numberToKey(int number);
+
+ void next();
+
+ void previous();
+
+ void wearNextOutfit(bool all = false);
+
+ void wearPreviousOutfit(bool all = false);
+
+ void wearAwayOutfit();
+
+ void unwearAwayOutfit();
+
+ void showCurrentOutfit();
+
+ std::string keyName(int number);
+
+ private:
+ Button *mPreviousButton;
+ Button *mNextButton;
+ Label *mCurrentLabel;
+ CheckBox *mUnequipCheck;
+ CheckBox *mAwayOutfitCheck;
+ Label *mKeyLabel;
+
+ int getIndexFromGrid(int pointX, int pointY) const;
+
+ int mBoxWidth;
+ int mBoxHeight;
+ int mCursorPosX, mCursorPosY;
+ int mGridWidth, mGridHeight;
+ bool mItemClicked;
+ Item *mItemMoved;
+
+ void save();
+
+ int mItems[OUTFITS_COUNT + 1][OUTFIT_ITEM_COUNT];
+ bool mItemsUnequip[OUTFITS_COUNT];
+ int mItemSelected;
+
+ int mCurrentOutfit;
+ int mAwayOutfit;
+
+ Image *mBackgroundImg;
+
+ static float mAlpha;
+};
+
+extern OutfitWindow *outfitWindow;
+
+#endif
diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp
new file mode 100644
index 000000000..72c490912
--- /dev/null
+++ b/src/gui/palette.cpp
@@ -0,0 +1,274 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "palette.h"
+
+#include "configuration.h"
+#include "client.h"
+
+#include "gui/gui.h"
+
+#include "utils/gettext.h"
+#include "utils/mathutils.h"
+#include "utils/stringutils.h"
+
+#include <math.h>
+
+const gcn::Color Palette::BLACK = gcn::Color(0, 0, 0);
+Palette::Palettes Palette::mInstances;
+
+const gcn::Color Palette::RAINBOW_COLORS[7] = {
+ gcn::Color(255, 0, 0),
+ gcn::Color(255, 153, 0),
+ gcn::Color(255, 255, 0),
+ gcn::Color(0, 153, 0),
+ gcn::Color(0, 204, 204),
+ gcn::Color(51, 0, 153),
+ gcn::Color(153, 0, 153)
+};
+/** Number of Elemets of RAINBOW_COLORS */
+const int Palette::RAINBOW_COLOR_COUNT = 7;
+
+Palette::Palette(int size) :
+ mRainbowTime(tick_time),
+ mColors(Colors(size))
+{
+ mInstances.insert(this);
+}
+
+Palette::~Palette()
+{
+ mInstances.erase(this);
+}
+
+const gcn::Color& Palette::getColor(char c, bool &valid)
+{
+ for (Colors::const_iterator col = mColors.begin(),
+ colEnd = mColors.end(); col != colEnd; ++col)
+ {
+ if (col->ch == c)
+ {
+ valid = true;
+ return col->color;
+ }
+ }
+ valid = false;
+ return BLACK;
+}
+
+void Palette::advanceGradients()
+{
+ Palettes::iterator it = mInstances.begin();
+ Palettes::iterator it_end = mInstances.end();
+
+ for (; it != it_end; it++)
+ (*it)->advanceGradient();
+}
+
+void Palette::advanceGradient()
+{
+ if (get_elapsed_time(mRainbowTime) > 5)
+ {
+ int pos, colIndex, colVal, delay, numOfColors;
+ // For slower systems, advance can be greater than one (advance > 1
+ // skips advance-1 steps). Should make gradient look the same
+ // independent of the framerate.
+ int advance = get_elapsed_time(mRainbowTime) / 5;
+ double startColVal, destColVal;
+
+ for (size_t i = 0; i < mGradVector.size(); i++)
+ {
+ if (!mGradVector[i])
+ continue;
+
+ delay = mGradVector[i]->delay;
+
+ if (mGradVector[i]->grad == PULSE)
+ delay = delay / 20;
+
+ numOfColors = (mGradVector[i]->grad == SPECTRUM ? 6 :
+ mGradVector[i]->grad == PULSE ? 127 :
+ RAINBOW_COLOR_COUNT);
+
+ mGradVector[i]->gradientIndex =
+ (mGradVector[i]->gradientIndex + advance) %
+ (delay * numOfColors);
+
+ pos = mGradVector[i]->gradientIndex % delay;
+ if (delay)
+ colIndex = mGradVector[i]->gradientIndex / delay;
+ else
+ colIndex = mGradVector[i]->gradientIndex;
+
+ if (mGradVector[i]->grad == PULSE)
+ {
+ colVal = static_cast<int>(255.0 *
+ sin(M_PI * colIndex / numOfColors));
+
+ const gcn::Color &col = mGradVector[i]->testColor;
+
+ mGradVector[i]->color.r =
+ ((colVal * col.r) / 255) % (col.r + 1);
+ mGradVector[i]->color.g =
+ ((colVal * col.g) / 255) % (col.g + 1);
+ mGradVector[i]->color.b =
+ ((colVal * col.b) / 255) % (col.b + 1);
+ }
+ if (mGradVector[i]->grad == SPECTRUM)
+ {
+ if (colIndex % 2)
+ { // falling curve
+ if (delay)
+ {
+ colVal = static_cast<int>(255.0 *
+ (cos(M_PI * pos / delay) + 1) / 2);
+ }
+ else
+ {
+ colVal = static_cast<int>(255.0 *
+ (cos(M_PI * pos) + 1) / 2);
+ }
+ }
+ else
+ { // ascending curve
+ if (delay)
+ {
+ colVal = static_cast<int>(255.0 * (cos(M_PI *
+ (delay - pos) / delay) + 1) / 2);
+ }
+ else
+ {
+ colVal = static_cast<int>(255.0 * (cos(M_PI *
+ (delay - pos)) + 1) / 2);
+ }
+ }
+
+ mGradVector[i]->color.r =
+ (colIndex == 0 || colIndex == 5) ? 255 :
+ (colIndex == 1 || colIndex == 4) ? colVal : 0;
+ mGradVector[i]->color.g =
+ (colIndex == 1 || colIndex == 2) ? 255 :
+ (colIndex == 0 || colIndex == 3) ? colVal : 0;
+ mGradVector[i]->color.b =
+ (colIndex == 3 || colIndex == 4) ? 255 :
+ (colIndex == 2 || colIndex == 5) ? colVal : 0;
+ }
+ else if (mGradVector[i]->grad == RAINBOW)
+ {
+ const gcn::Color &startCol = RAINBOW_COLORS[colIndex];
+ const gcn::Color &destCol =
+ RAINBOW_COLORS[(colIndex + 1) % numOfColors];
+
+ if (delay)
+ startColVal = (cos(M_PI * pos / delay) + 1) / 2;
+ else
+ startColVal = 0;
+
+ destColVal = 1 - startColVal;
+
+ mGradVector[i]->color.r = static_cast<int>(startColVal
+ * startCol.r + destColVal * destCol.r);
+
+ mGradVector[i]->color.g = static_cast<int>(startColVal
+ * startCol.g + destColVal * destCol.g);
+
+ mGradVector[i]->color.b = static_cast<int>(startColVal
+ * startCol.b + destColVal * destCol.b);
+ }
+ }
+
+ if (advance)
+ mRainbowTime = tick_time;
+ }
+}
+
+/*
+gcn::Color Palette::produceHPColor(int hp, int maxHp, int alpha)
+{
+ float r1 = 255;
+ float g1 = 255;
+ float b1 = 255;
+ float r2 = 255;
+ float g2 = 255;
+ float b2 = 255;
+
+ float weight = 1.0f;
+
+ int thresholdLevel = maxHp / 4;
+ int thresholdProgress = hp % thresholdLevel;
+
+ if (thresholdLevel)
+ weight = 1 - ((float)thresholdProgress) / ((float)thresholdLevel);
+ else
+ weight = 0;
+
+ if (hp < (thresholdLevel))
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_QUARTER);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+ else if (hp < (thresholdLevel*2))
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+ else if (hp < thresholdLevel*3)
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+ else
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_FULL);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+
+ // Safety checks
+ if (weight > 1.0f) weight = 1.0f;
+ if (weight < 0.0f) weight = 0.0f;
+
+ // Do the color blend
+ r1 = (int) weightedAverage(r1, r2,weight);
+ g1 = (int) weightedAverage(g1, g2, weight);
+ b1 = (int) weightedAverage(b1, b2, weight);
+
+ // More safety checks
+ if (r1 > 255) r1 = 255;
+ if (g1 > 255) g1 = 255;
+ if (b1 > 255) b1 = 255;
+
+ return gcn::Color(r1, g1, b1, alpha);
+}
+*/
+
diff --git a/src/gui/palette.h b/src/gui/palette.h
new file mode 100644
index 000000000..0c8af1d7f
--- /dev/null
+++ b/src/gui/palette.h
@@ -0,0 +1,191 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PALETTE_H
+#define PALETTE_H
+
+#include "log.h"
+#include "utils/stringutils.h"
+
+#include <guichan/color.hpp>
+
+#include <cstdlib>
+#include <string>
+#include <set>
+#include <vector>
+
+// Default Gradient Delay
+#define GRADIENT_DELAY 40
+
+/**
+ * Class controlling the game's color palette.
+ */
+class Palette
+{
+ public:
+ /** Black Color Constant */
+ static const gcn::Color BLACK;
+
+ /** Colors can be static or can alter over time. */
+ enum GradientType
+ {
+ STATIC = 0,
+ PULSE,
+ SPECTRUM,
+ RAINBOW
+ };
+
+ /**
+ * Returns the color associated with a character, if it exists. Returns
+ * Palette::BLACK if the character is not found.
+ *
+ * @param c character requested
+ * @param valid indicate whether character is known
+ *
+ * @return the requested color or Palette::BLACK
+ */
+ const gcn::Color &getColor(char c, bool &valid);
+
+ /**
+ * Gets the color associated with the type. Sets the alpha channel
+ * before returning.
+ *
+ * @param type the color type requested
+ * @param alpha alpha channel to use
+ *
+ * @return the requested color
+ */
+ inline const gcn::Color &getColor(int type, int alpha = 255)
+ {
+ gcn::Color* col = &mColors[type].color;
+ col->a = alpha;
+ return *col;
+ }
+
+ inline const gcn::Color &getColorWithAlpha(int type)
+ {
+ gcn::Color* col = &mColors[type].color;
+ col->a = mColors[type].delay;
+ return *col;
+ }
+
+ /**
+ * Gets the GradientType associated with the specified type.
+ *
+ * @param type the color type of the color
+ *
+ * @return the gradient type of the color with the given index
+ */
+ inline GradientType getGradientType(int type) const
+ {
+ return mColors[type].grad;
+ }
+
+ /**
+ * Get the character used by the specified color.
+ *
+ * @param type the color type of the color
+ *
+ * @return the color char of the color with the given index
+ */
+ inline char getColorChar(int type) const
+ {
+ return mColors[type].ch;
+ }
+
+ /**
+ * Gets the gradient delay for the specified type.
+ *
+ * @param type the color type of the color
+ *
+ * @return the gradient delay of the color with the given index
+ */
+ inline int getGradientDelay(int type) const
+ { return mColors[type].delay; }
+
+ /**
+ * Updates all colors, that are non-static.
+ */
+ static void advanceGradients();
+
+ gcn::Color static produceHPColor(int hp, int maxHp, int alpha = 255);
+
+ protected:
+ /** Colors used for the rainbow gradient */
+ static const gcn::Color RAINBOW_COLORS[];
+ static const int RAINBOW_COLOR_COUNT;
+
+ /** Time tick, that gradient-type colors were updated the last time. */
+ int mRainbowTime;
+
+ typedef std::set<Palette*> Palettes;
+ static Palettes mInstances;
+
+ /**
+ * Constructor
+ */
+ Palette(int size);
+
+ /**
+ * Destructor
+ */
+ ~Palette();
+
+ void advanceGradient();
+
+ struct ColorElem
+ {
+ int type;
+ gcn::Color color;
+ gcn::Color testColor;
+ gcn::Color committedColor;
+ std::string text;
+ char ch;
+ GradientType grad;
+ GradientType committedGrad;
+ int gradientIndex;
+ int delay;
+ int committedDelay;
+
+ void set(int type, gcn::Color& color, GradientType grad, int delay)
+ {
+ ColorElem::type = type;
+ ColorElem::color = color;
+ ColorElem::testColor = color;
+ ColorElem::grad = grad;
+ ColorElem::delay = delay;
+ ColorElem::gradientIndex = rand();
+ }
+
+ inline int getRGB() const
+ {
+ return (committedColor.r << 16) | (committedColor.g << 8) |
+ committedColor.b;
+ }
+ };
+ typedef std::vector<ColorElem> Colors;
+ /** Vector containing the colors. */
+ Colors mColors;
+ std::vector<ColorElem*> mGradVector;
+};
+
+#endif
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
new file mode 100644
index 000000000..662b184b9
--- /dev/null
+++ b/src/gui/popupmenu.cpp
@@ -0,0 +1,1286 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/popupmenu.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "dropshortcut.h"
+#include "guild.h"
+#include "flooritem.h"
+#include "graphics.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+#include "log.h"
+#include "map.h"
+#include "party.h"
+#include "playerinfo.h"
+#include "playerrelations.h"
+#include "spellmanager.h"
+
+#include "gui/buy.h"
+#include "gui/chat.h"
+#include "gui/inventorywindow.h"
+#include "gui/itemamount.h"
+#include "gui/outfitwindow.h"
+#include "gui/sell.h"
+#include "gui/socialwindow.h"
+#include "gui/textcommandeditor.h"
+#include "gui/textdialog.h"
+#include "gui/trade.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/whispertab.h"
+
+#include "net/adminhandler.h"
+#include "net/beinghandler.h"
+#include "net/buysellhandler.h"
+#include "net/guildhandler.h"
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+#include "net/partyhandler.h"
+#include "gui/shortcutwindow.h"
+#include "net/tradehandler.h"
+
+#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <cassert>
+
+std::string tradePartnerName("");
+
+PopupMenu::PopupMenu():
+ Popup("PopupMenu"),
+ mBeingId(0),
+ mFloorItem(0),
+ mItem(0),
+ mItemId(0),
+ mMapItem(0),
+ mTab(0),
+ mSpell(0),
+ mDialog(0),
+ mNick("")
+{
+ mBrowserBox = new BrowserBox;
+ mBrowserBox->setPosition(4, 4);
+ mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
+ mBrowserBox->setOpaque(false);
+ mBrowserBox->setLinkHandler(this);
+ add(mBrowserBox);
+}
+
+void PopupMenu::showPopup(int x, int y, Being *being)
+{
+ if (!being || !player_node)
+ return;
+
+ mBeingId = being->getId();
+ mNick = being->getName();
+ mBrowserBox->clearRows();
+
+ const std::string &name = mNick;
+
+ mBrowserBox->addRow(name);
+
+ switch (being->getType())
+ {
+ case ActorSprite::PLAYER:
+ {
+ // Players can be traded with.
+ mBrowserBox->addRow(_("@@trade|Trade@@"));
+ // TRANSLATORS: Attacking a player.
+ mBrowserBox->addRow(_("@@attack|Attack@@"));
+ // TRANSLATORS: Whispering a player.
+ mBrowserBox->addRow(_("@@whisper|Whisper@@"));
+
+ mBrowserBox->addRow("##3---");
+
+ mBrowserBox->addRow(_("@@heal|Heal@@"));
+ mBrowserBox->addRow("##3---");
+
+ switch (player_relations.getRelation(name))
+ {
+ case PlayerRelation::NEUTRAL:
+ mBrowserBox->addRow(_("@@friend|Befriend@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::ERASED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ break;
+
+ default:
+ break;
+ }
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@follow|Follow@@"));
+ mBrowserBox->addRow(_("@@imitation|Imitation@@"));
+
+ if (player_node->isInParty())
+ {
+ if (player_node->getParty())
+ {
+ if (player_node->getParty()->getName()
+ != being->getPartyName())
+ {
+ mBrowserBox->addRow(
+ _("@@party|Invite to party@@"));
+ }
+ else
+ {
+ mBrowserBox->addRow(
+ _("@@kick party|Kick from party@@"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+ }
+
+ Guild *guild1 = being->getGuild();
+ Guild *guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild1)
+ {
+ if (guild1->getId() == guild2->getId())
+ {
+ mBrowserBox->addRow(
+ _("@@guild-kick|Kick from guild@@"));
+ mBrowserBox->addRow(
+ _("@@guild-pos|Change pos in guild >@@"));
+ }
+ }
+ else
+ {
+ mBrowserBox->addRow(_("@@guild|Invite to guild@@"));
+ }
+ }
+
+ if (player_node->isGM())
+ {
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@admin-kick|Kick player@@"));
+ }
+ mBrowserBox->addRow(_("@@nuke|Nuke@@"));
+ mBrowserBox->addRow(_("@@move|Move@@"));
+ mBrowserBox->addRow(_("@@undress|Undress@@"));
+
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ }
+ }
+ break;
+
+ case ActorSprite::NPC:
+ // NPCs can be talked to (single option, candidate for removal
+ // unless more options would be added)
+ mBrowserBox->addRow(_("@@talk|Talk@@"));
+
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@move|Move@@"));
+ break;
+
+ case ActorSprite::MONSTER:
+ {
+ // Monsters can be attacked
+ mBrowserBox->addRow(_("@@attack|Attack@@"));
+
+ if (player_node->isGM())
+ mBrowserBox->addRow(_("@@admin-kick|Kick@@"));
+ }
+ break;
+
+ default:
+ /* Other beings aren't interesting... */
+ return;
+ }
+ mBrowserBox->addRow(_("@@name|Add name to chat@@"));
+
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(int x, int y, std::list<Being*> &beings)
+{
+ mBrowserBox->clearRows();
+ mBrowserBox->addRow("Players");
+ std::list<Being*>::iterator it, it_end;
+ for (it = beings.begin(), it_end = beings.end(); it != it_end; it++)
+ {
+ Being *being = *it;
+ if (!being->getName().empty())
+ {
+ mBrowserBox->addRow(strprintf(_("@@player_%u|%s >@@"),
+ being->getId(), being->getName().c_str()));
+ }
+ }
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+ showPopup(x, y);
+}
+
+void PopupMenu::showPlayerPopup(int x, int y, std::string nick)
+{
+ if (nick.empty() || !player_node)
+ return;
+
+ mNick = nick;
+ mBeingId = 0;
+ mBrowserBox->clearRows();
+
+ const std::string &name = mNick;
+
+ mBrowserBox->addRow(name);
+
+ mBrowserBox->addRow(_("@@whisper|Whisper@@"));
+ mBrowserBox->addRow("##3---");
+
+ switch (player_relations.getRelation(name))
+ {
+ case PlayerRelation::NEUTRAL:
+ mBrowserBox->addRow(_("@@friend|Befriend@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::ERASED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ break;
+
+ default:
+ break;
+ }
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@follow|Follow@@"));
+ mBrowserBox->addRow(_("@@imitation|Imitation@@"));
+
+ Guild *guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild2->getMember(mNick))
+ {
+ mBrowserBox->addRow(_("@@guild-kick|Kick from guild@@"));
+ mBrowserBox->addRow(_("@@guild-pos|Change pos in guild >@@"));
+ }
+ else
+ {
+ mBrowserBox->addRow(_("@@guild|Invite to guild@@"));
+ }
+ }
+
+ mBrowserBox->addRow("##3---");
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ }
+
+ mBrowserBox->addRow(_("@@name|Add name to chat@@"));
+
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+
+}
+
+void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
+{
+ if (!floorItem)
+ return;
+
+ mFloorItem = floorItem;
+ ItemInfo info = floorItem->getInfo();
+ mBrowserBox->clearRows();
+
+ // Floor item can be picked up (single option, candidate for removal)
+ std::string name = info.getName();
+ mBrowserBox->addRow(name);
+ mBrowserBox->addRow(_("@@pickup|Pick up@@"));
+ mBrowserBox->addRow(_("@@chat|Add to chat@@"));
+
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(int x, int y, MapItem *mapItem)
+{
+ if (!mapItem)
+ return;
+
+ mMapItem = mapItem;
+
+ mBrowserBox->clearRows();
+
+ mBrowserBox->addRow(_("Map Item"));
+ mBrowserBox->addRow(_("@@rename map|Rename@@"));
+ mBrowserBox->addRow(_("@@remove map|Remove@@"));
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showOutfitsPopup(int x, int y)
+{
+ mBrowserBox->clearRows();
+
+ mBrowserBox->addRow(_("Outfits"));
+ mBrowserBox->addRow(_("@@load old outfits|Load old outfits@@"));
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showSpellPopup(int x, int y, TextCommand *cmd)
+{
+ if (!cmd)
+ return;
+
+ mBrowserBox->clearRows();
+
+ mSpell = cmd;
+ mBrowserBox->addRow(_("Spells"));
+ mBrowserBox->addRow(_("@@load old spells|Load old spells@@"));
+ mBrowserBox->addRow(_("@@edit spell|Edit spell@@"));
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showChatPopup(int x, int y, ChatTab *tab)
+{
+ if (!tab || !actorSpriteManager || !player_node)
+ return;
+
+ mTab = tab;
+
+ mBrowserBox->clearRows();
+
+ if (tab->getType() == ChatTab::TAB_WHISPER)
+ mBrowserBox->addRow(_("@@chat close|Close@@"));
+
+ mBrowserBox->addRow(strprintf("@@chat clear|%s@@", _("Clear")));
+ mBrowserBox->addRow("##3---");
+
+ if (tab->getAllowHighlight())
+ {
+ mBrowserBox->addRow(strprintf("@@disable highlight|%s@@",
+ _("Disable highlight")));
+ mBrowserBox->addRow("##3---");
+ }
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@enable highlight|%s@@",
+ _("Enable highlight")));
+ mBrowserBox->addRow("##3---");
+ }
+
+ if (tab->getType() == ChatTab::TAB_PARTY)
+ {
+ mBrowserBox->addRow(_("@@leave party|Leave@@"));
+ mBrowserBox->addRow("##3---");
+ }
+
+ if (tab->getType() == ChatTab::TAB_WHISPER)
+ {
+ WhisperTab *wTab = static_cast<WhisperTab*>(tab);
+ std::string name = wTab->getNick();
+
+ Being* being = actorSpriteManager->findBeingByName(
+ name, Being::PLAYER);
+
+ if (being)
+ {
+ mBeingId = being->getId();
+ mNick = being->getName();
+
+ mBrowserBox->addRow(_("@@trade|Trade@@"));
+ mBrowserBox->addRow(_("@@attack|Attack@@"));
+
+ mBrowserBox->addRow("##3---");
+
+ mBrowserBox->addRow(_("@@heal|Heal@@"));
+ mBrowserBox->addRow("##3---");
+
+ switch (player_relations.getRelation(name))
+ {
+ case PlayerRelation::NEUTRAL:
+ mBrowserBox->addRow(_("@@friend|Befriend@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::ERASED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ break;
+
+ default:
+ break;
+ }
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@follow|Follow@@"));
+ mBrowserBox->addRow(_("@@imitation|Imitation@@"));
+ mBrowserBox->addRow(_("@@move|Move@@"));
+ mBrowserBox->addRow(_("@@undress|Undress@@"));
+
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ }
+
+ mBrowserBox->addRow("##3---");
+
+ if (player_node->isInParty())
+ {
+ if (player_node->getParty())
+ {
+ if (!player_node->getParty()->isMember(wTab->getNick()))
+ {
+ mBrowserBox->addRow(_("@@party|Invite to party@@"));
+ }
+ else
+ {
+ mBrowserBox->addRow(
+ _("@@kick party|Kick from party@@"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+ }
+ Guild *guild1 = being->getGuild();
+ Guild *guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild1)
+ {
+ if (guild1->getId() == guild2->getId())
+ {
+ mBrowserBox->addRow(
+ _("@@guild-kick|Kick from guild@@"));
+ mBrowserBox->addRow(
+ _("@@guild-pos|Change pos in guild >@@"));
+ }
+ }
+ else
+ {
+ mBrowserBox->addRow(_("@@guild|Invite to guild@@"));
+ }
+ }
+ }
+ }
+ mBrowserBox->addRow(strprintf(_("@@cancel|Cancel@@")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showChangePos(int x, int y)
+{
+ mBrowserBox->clearRows();
+ mBrowserBox->addRow(_("Change guild position"));
+
+ if (!player_node)
+ return;
+
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ {
+ PositionsMap map = guild->getPositions();
+ PositionsMap::iterator itr = map.begin();
+ PositionsMap::iterator itr_end = map.end();
+ for (; itr != itr_end; ++itr)
+ {
+ mBrowserBox->addRow(strprintf(_("@@guild-pos-%d|%s@@"),
+ itr->first, itr->second.c_str()));
+ }
+ mBrowserBox->addRow(strprintf(_("@@cancel|Cancel@@")));
+
+ showPopup(x, y);
+ }
+ else
+ {
+ mBeingId = 0;
+ mFloorItem = 0;
+ mItem = 0;
+ mMapItem = 0;
+ mNick = "";
+ setVisible(false);
+ }
+}
+
+void PopupMenu::handleLink(const std::string &link,
+ gcn::MouseEvent *event _UNUSED_)
+{
+ if (!actorSpriteManager)
+ return;
+
+ Being *being = actorSpriteManager->findBeing(mBeingId);
+
+ // Talk To action
+ if (link == "talk" && being && being->canTalk())
+ {
+ being->talkTo();
+ }
+ // Trade action
+ else if (link == "trade" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ Net::getTradeHandler()->request(being);
+ tradePartnerName = being->getName();
+ if (tradeWindow)
+ tradeWindow->clear();
+ }
+ else if (link == "buy" && being && mBeingId != 0)
+ {
+ if (being->getType() == Being::NPC)
+ Net::getNpcHandler()->buy(mBeingId);
+ else if (being->getType() == Being::PLAYER)
+ Net::getBuySellHandler()->requestSellList(being->getName());
+ }
+ else if (link == "buy" && !mNick.empty())
+ {
+ Net::getBuySellHandler()->requestSellList(mNick);
+ }
+ else if (link == "sell" && being && mBeingId != 0)
+ {
+ if (being->getType() == Being::NPC)
+ Net::getNpcHandler()->sell(mBeingId);
+ else if (being->getType() == Being::PLAYER)
+ Net::getBuySellHandler()->requestBuyList(being->getName());
+ }
+ else if (link == "sell" && !mNick.empty())
+ {
+ Net::getBuySellHandler()->requestBuyList(mNick);
+ }
+ // Attack action
+ else if (link == "attack" && being)
+ {
+ if (player_node)
+ player_node->attack(being, true);
+ }
+ else if (link == "heal" && being && being->getType() != Being::MONSTER)
+ {
+ actorSpriteManager->heal(player_node, being);
+ }
+ else if (link == "unignore" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::NEUTRAL);
+ }
+ else if (link == "unignore" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick,
+ PlayerRelation::NEUTRAL);
+ }
+ else if (link == "ignore" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::IGNORED);
+ }
+ else if (link == "ignore" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::IGNORED);
+ }
+ else if (link == "erase" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(), PlayerRelation::ERASED);
+ }
+ else if (link == "erase" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::ERASED);
+ }
+ else if (link == "disregard" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(),
+ PlayerRelation::DISREGARDED);
+ }
+ else if (link == "disregard" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::DISREGARDED);
+ }
+ else if (link == "friend" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(), PlayerRelation::FRIEND);
+ }
+ else if (link == "friend" && !mNick.empty())
+ {
+ player_relations.setRelation(mNick, PlayerRelation::FRIEND);
+ }
+ // Guild action
+ else if (link == "guild" && !mNick.empty())
+ {
+ if (player_node)
+ {
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ Net::getGuildHandler()->invite(guild->getId(), mNick);
+ }
+ }
+ else if (link == "nuke" && being)
+ {
+ actorSpriteManager->addBlock(being->getId());
+ actorSpriteManager->destroy(being);
+ }
+ // Follow Player action
+ else if (link == "follow" && !mNick.empty())
+ {
+ if (player_node)
+ player_node->setFollow(mNick);
+ }
+ else if (link == "imitation" && !mNick.empty())
+ {
+ if (player_node)
+ player_node->setImitate(mNick);
+ }
+ // Pick Up Floor Item action
+ else if ((link == "pickup") && mFloorItem)
+ {
+ if (player_node)
+ player_node->pickUp(mFloorItem);
+ }
+ // Look To action
+ else if (link == "look")
+ {
+ }
+ else if (link == "use" && mItem)
+ {
+ if (mItem->isEquipment())
+ {
+ if (mItem->isEquipped())
+ Net::getInventoryHandler()->unequipItem(mItem);
+ else
+ Net::getInventoryHandler()->equipItem(mItem);
+ }
+ else
+ {
+ Net::getInventoryHandler()->useItem(mItem);
+ }
+ }
+ else if (link == "use" && mItemId)
+ {
+ if (mItemId < SPELL_MIN_ID)
+ {
+ Inventory *inv = PlayerInfo::getInventory();
+ if (inv)
+ {
+ Item *item = inv->findItem(mItemId);
+ if (item)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ else
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ else
+ {
+ Net::getInventoryHandler()->useItem(item);
+ }
+ }
+ }
+ }
+ else if (spellManager)
+ {
+ spellManager->useItem(mItemId);
+ }
+ }
+ else if (link == "chat")
+ {
+ if (chatWindow)
+ {
+ if (mItem)
+ chatWindow->addItemText(mItem->getInfo().getName());
+ else if (mFloorItem)
+ chatWindow->addItemText(mFloorItem->getInfo().getName());
+ }
+ }
+ else if (link == "whisper" && !mNick.empty() && chatWindow)
+ {
+ if (chatWindow)
+ {
+ if (config.getBoolValue("whispertab"))
+ chatWindow->localChatInput("/q " + mNick);
+ else
+ chatWindow->addInputText("/w \"" + mNick + "\" ");
+ }
+ }
+ else if (link == "move" && being)
+ {
+ if (player_node)
+ player_node->navigateTo(being->getTileX(), being->getTileY());
+ }
+ else if (link == "split" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit,
+ inventoryWindow, mItem);
+ }
+ else if (link == "drop" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemDrop,
+ inventoryWindow, mItem);
+ }
+ else if (link == "store" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::StoreAdd,
+ inventoryWindow, mItem);
+ }
+ else if (link == "store 10" && mItem)
+ {
+ int cnt = 10;
+ if (cnt > mItem->getQuantity())
+ cnt = mItem->getQuantity();
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ mItem->getInvIndex(), cnt,
+ Inventory::STORAGE);
+ }
+ else if (link == "store half" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ mItem->getInvIndex(), mItem->getQuantity() / 2,
+ Inventory::STORAGE);
+ }
+ else if (link == "store all" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ mItem->getInvIndex(), mItem->getQuantity(),
+ Inventory::STORAGE);
+ }
+ else if (link == "retrieve" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::StoreRemove, mWindow,
+ mItem);
+ }
+ else if (link == "retrieve 10" && mItem)
+ {
+ int cnt = 10;
+ if (cnt > mItem->getQuantity())
+ cnt = mItem->getQuantity();
+ Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ mItem->getInvIndex(), cnt,
+ Inventory::INVENTORY);
+ }
+ else if (link == "retrieve half" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ mItem->getInvIndex(), mItem->getQuantity() / 2,
+ Inventory::INVENTORY);
+ }
+ else if (link == "retrieve all" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ mItem->getInvIndex(), mItem->getQuantity(),
+ Inventory::INVENTORY);
+ }
+ else if (link == "party" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ Net::getPartyHandler()->invite(being);
+ }
+ else if (link == "kick party" && being
+ && being->getType() == Being::PLAYER)
+ {
+ Net::getPartyHandler()->kick(being);
+ }
+ else if (link == "name" && !mNick.empty())
+ {
+ const std::string &name = mNick;
+ if (chatWindow)
+ chatWindow->addInputText(name);
+ }
+ else if (link == "admin-kick" && being &&
+ (being->getType() == ActorSprite::PLAYER ||
+ being->getType() == ActorSprite::MONSTER))
+ {
+ Net::getAdminHandler()->kick(being->getId());
+ }
+ else if (link == "chat close" && mTab)
+ {
+ mTab->handleCommand("close", "");
+ }
+ else if (link == "leave party" && mTab)
+ {
+ Net::getPartyHandler()->leave();
+ }
+ else if (link == "chat clear" && mTab)
+ {
+ if (chatWindow)
+ chatWindow->clearTab();
+ }
+ else if (link == "remove map" && mMapItem)
+ {
+ if (viewport)
+ {
+ Map *map = viewport->getCurrentMap();
+ if (map)
+ {
+ SpecialLayer *specialLayer = map->getSpecialLayer();
+ if (specialLayer)
+ {
+ const int x = mMapItem->getX();
+ const int y = mMapItem->getY();
+ specialLayer->setTile(x, y, MapItem::EMPTY);
+ if (socialWindow)
+ socialWindow->removePortal(x, y);
+ }
+ }
+ }
+ }
+ else if (link == "rename map" && mMapItem)
+ {
+ mRenameListener.setMapItem(mMapItem);
+ mDialog = new TextDialog(_("Rename map sign "),
+ _("Name: "));
+ mRenameListener.setDialog(mDialog);
+ mDialog->setText(mMapItem->getComment());
+ mDialog->setActionEventId("ok");
+ mDialog->addActionListener(&mRenameListener);
+ }
+ else if (link == "load old outfits")
+ {
+ if (outfitWindow)
+ outfitWindow->load(true);
+ }
+ else if (link == "load old spells")
+ {
+ if (spellManager)
+ {
+ spellManager->load(true);
+ spellManager->save();
+ }
+ }
+ else if (link == "load old item shortcuts")
+ {
+ if (itemShortcutWindow)
+ {
+ int num = itemShortcutWindow->getTabIndex();
+ if (num >= 0 && num < SHORTCUT_TABS && itemShortcut[num])
+ {
+ itemShortcut[num]->load(true);
+ itemShortcut[num]->save();
+ }
+ }
+ }
+ else if (link == "load old drop shortcuts")
+ {
+ if (dropShortcut)
+ {
+ dropShortcut->load(true);
+ dropShortcut->save();
+ }
+ }
+ else if (link == "edit spell" && mSpell)
+ {
+ new TextCommandEditor(mSpell);
+ }
+ else if (link == "undress" && being)
+ {
+ Net::getBeingHandler()->undress(being);
+ }
+ else if (link == "guild-kick" && !mNick.empty())
+ {
+ if (player_node)
+ {
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ Net::getGuildHandler()->kick(guild->getMember(mNick));
+ }
+ }
+ else if (link == "enable highlight" && mTab)
+ {
+ mTab->setAllowHighlight(true);
+ }
+ else if (link == "disable highlight" && mTab)
+ {
+ mTab->setAllowHighlight(false);
+ }
+ else if (link == "guild-pos" && !mNick.empty())
+ {
+ showChangePos(getX(), getY());
+ return;
+ }
+ else if (!link.find("guild-pos-"))
+ {
+ if (player_node)
+ {
+ int num = atoi(link.substr(10).c_str());
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ {
+ Net::getGuildHandler()->changeMemberPostion(
+ guild->getMember(mNick), num);
+ }
+ }
+ }
+ else if (!link.find("player_"))
+ {
+ mBeingId = atoi(link.substr(7).c_str());
+ Being *being = actorSpriteManager->findBeing(mBeingId);
+ if (being)
+ {
+ showPopup(getX(), getY(), being);
+ return;
+ }
+ }
+ // Unknown actions
+ else if (link != "cancel")
+ {
+ logger->log("PopupMenu: Warning, unknown action '%s'", link.c_str());
+ }
+
+ setVisible(false);
+
+ mBeingId = 0;
+ mFloorItem = 0;
+ mItem = 0;
+ mItemId = 0;
+ mMapItem = 0;
+ mNick = "";
+}
+
+void PopupMenu::showPopup(Window *parent, int x, int y, Item *item,
+ bool isInventory)
+{
+ if (!item)
+ return;
+
+ mItem = item;
+ mWindow = parent;
+ mBrowserBox->clearRows();
+
+ int cnt = item->getQuantity();
+
+ if (isInventory)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip")));
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip")));
+ }
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+
+ if (cnt > 1)
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop...")));
+ else
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
+
+ if (Net::getInventoryHandler()->canSplit(item))
+ mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
+
+ if (InventoryWindow::isStorageActive())
+ {
+ mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
+ if (cnt > 1)
+ {
+ if (cnt > 10)
+ {
+ mBrowserBox->addRow(strprintf("@@store 10|%s@@",
+ _("Store 10")));
+ }
+ mBrowserBox->addRow(strprintf("@@store half|%s@@",
+ _("Store half")));
+ mBrowserBox->addRow(strprintf("@@store all|%s@@",
+ _("Store all")));
+ }
+ }
+ }
+ // Assume in storage for now
+ // TODO: make this whole system more flexible, if needed
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@retrieve|%s@@", _("Retrieve")));
+ if (cnt > 1)
+ {
+ if (cnt > 10)
+ {
+ mBrowserBox->addRow(strprintf("@@retrieve 10|%s@@",
+ _("Retrieve 10")));
+ }
+ mBrowserBox->addRow(strprintf("@@retrieve half|%s@@",
+ _("Retrieve half")));
+ mBrowserBox->addRow(strprintf("@@retrieve all|%s@@",
+ _("Retrieve all")));
+ }
+ }
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showItemPopup(int x, int y, int itemId)
+{
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *item = inv->findItem(itemId);
+ if (item)
+ {
+ showItemPopup(x, y, item);
+ }
+ else
+ {
+ mItem = 0;
+ mItemId = itemId;
+ mBrowserBox->clearRows();
+
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@load old item shortcuts|%s@@",
+ _("Load old item shortcuts")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+ }
+}
+
+void PopupMenu::showItemPopup(int x, int y, Item *item)
+{
+ mItem = item;
+ if (item)
+ mItemId = item->getId();
+ else
+ mItemId = 0;
+ mBrowserBox->clearRows();
+
+ if (item)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip")));
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip")));
+ }
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+ }
+
+ if (item->getQuantity() > 1)
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop...")));
+ else
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
+
+ if (Net::getInventoryHandler()->canSplit(item))
+ mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
+
+ if (InventoryWindow::isStorageActive())
+ mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
+ mBrowserBox->addRow("##3---");
+ }
+ mBrowserBox->addRow(strprintf("@@load old item shortcuts|%s@@",
+ _("Load old item shortcuts")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showDropPopup(int x, int y, Item *item)
+{
+ mItem = item;
+ mBrowserBox->clearRows();
+
+ if (item)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip")));
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip")));
+ }
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+
+ if (item->getQuantity() > 1)
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop...")));
+ else
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
+
+ if (Net::getInventoryHandler()->canSplit(item))
+ mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
+
+ if (InventoryWindow::isStorageActive())
+ mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
+ mBrowserBox->addRow("##3---");
+ }
+ mBrowserBox->addRow(strprintf("@@load old drop shortcuts|%s@@",
+ _("Load old drop shortcuts")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(int x _UNUSED_, int y _UNUSED_, Button *button)
+{
+ if (!button)
+ return;
+
+}
+
+void PopupMenu::showPopup(int x, int y)
+{
+ setContentSize(mBrowserBox->getWidth() + 8, mBrowserBox->getHeight() + 8);
+ if (graphics->getWidth() < (x + getWidth() + 5))
+ x = graphics->getWidth() - getWidth();
+ if (graphics->getHeight() < (y + getHeight() + 5))
+ y = graphics->getHeight() - getHeight();
+ setPosition(x, y);
+ setVisible(true);
+ requestMoveToTop();
+}
+
+
+void RenameListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok" && mMapItem && viewport && mDialog)
+ {
+ Map *map = viewport->getMap();
+ if (!map)
+ return;
+
+ SpecialLayer *sl = map->getSpecialLayer();
+ MapItem *item = 0;
+ if (sl)
+ {
+ item = sl->getTile(mMapItem->getX(), mMapItem->getY());
+ if (!item)
+ {
+ sl->setTile(mMapItem->getX(), mMapItem->getY(),
+ mMapItem->getType());
+ item = sl->getTile(mMapItem->getX(), mMapItem->getY());
+ }
+ item->setComment(mDialog->getText());
+ }
+ item = map->findPortalXY(mMapItem->getX(), mMapItem->getY());
+ if (item)
+ item->setComment(mDialog->getText());
+
+ if (socialWindow)
+ socialWindow->updatePortalNames();
+ }
+ mDialog = 0;
+}
diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h
new file mode 100644
index 000000000..d6c66aa81
--- /dev/null
+++ b/src/gui/popupmenu.h
@@ -0,0 +1,149 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef POPUP_MENU_H
+#define POPUP_MENU_H
+
+#include "gui/widgets/linkhandler.h"
+#include "gui/widgets/popup.h"
+
+#include <guichan/actionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Being;
+class BrowserBox;
+class Button;
+class ChatTab;
+class FloorItem;
+class Item;
+class ItemShortcut;
+class MapItem;
+class TextCommand;
+class TextDialog;
+class Window;
+
+class RenameListener : public gcn::ActionListener
+{
+ public:
+ void action(const gcn::ActionEvent &event);
+
+ void setMapItem(MapItem* mapItem)
+ { mMapItem = mapItem; }
+
+ void setDialog(TextDialog *dialog)
+ { mDialog = dialog; }
+
+ private:
+ MapItem *mMapItem;
+ TextDialog *mDialog;
+};
+
+/**
+ * Window showing popup menu.
+ */
+class PopupMenu : public Popup, public LinkHandler
+{
+ public:
+ /**
+ * Constructor.
+ */
+ PopupMenu();
+
+ /**
+ * Shows the being related popup menu at the specified mouse coords.
+ */
+ void showPopup(int x, int y, Being *being);
+
+ /**
+ * Shows the beings related popup menu at the specified mouse coords.
+ */
+ void showPopup(int x, int y, std::list<Being*> &beings);
+
+ void showPlayerPopup(int x, int y, std::string nick);
+
+ /**
+ * Shows the floor item related popup menu at the specified
+ * mouse coords.
+ */
+ void showPopup(int x, int y, FloorItem *floorItem);
+
+ /**
+ * Shows the related popup menu when right click on the inventory
+ * at the specified mouse coordinates.
+ */
+ void showPopup(Window *parent, int x, int y, Item *item,
+ bool isInventory);
+
+ void showPopup(int x, int y, Button *button);
+
+ void showPopup(int x, int y, MapItem *mapItem);
+
+ void showItemPopup(int x, int y, Item *item);
+
+ void showItemPopup(int x, int y, int itemId);
+
+ void showDropPopup(int x, int y, Item *item);
+
+ void showOutfitsPopup(int x, int y);
+
+ void showSpellPopup(int x, int y, TextCommand *cmd);
+
+ /**
+ * Shows the related popup menu when right click on the chat
+ * at the specified mouse coordinates.
+ */
+ void showChatPopup(int x, int y, ChatTab *tab);
+
+ void showChangePos(int x, int y);
+
+ /**
+ * Handles link action.
+ */
+ void handleLink(const std::string &link,
+ gcn::MouseEvent *event _UNUSED_);
+
+ private:
+ BrowserBox* mBrowserBox;
+
+ int mBeingId;
+ FloorItem* mFloorItem;
+ Item *mItem;
+ int mItemId;
+ MapItem *mMapItem;
+ ChatTab *mTab;
+ TextCommand *mSpell;
+ Window *mWindow;
+ RenameListener mRenameListener;
+ TextDialog *mDialog;
+ std::string mNick;
+
+ /**
+ * Shared code for the various showPopup functions.
+ */
+ void showPopup(int x, int y);
+};
+
+#endif
diff --git a/src/gui/quitdialog.cpp b/src/gui/quitdialog.cpp
new file mode 100644
index 000000000..7b587dccc
--- /dev/null
+++ b/src/gui/quitdialog.cpp
@@ -0,0 +1,204 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/quitdialog.h"
+
+#include "client.h"
+
+#include "gui/chat.h"
+#include "gui/sdlinput.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/button.h"
+#include "gui/widgets/radiobutton.h"
+
+#include "net/charhandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+
+#include <assert.h>
+
+QuitDialog::QuitDialog(QuitDialog** pointerToMe):
+ Window(_("Quit"), true, NULL), mMyPointer(pointerToMe)
+{
+// int width = 200;
+// int height = 120;
+
+ mForceQuit = new RadioButton(_("Quit"), "quitdialog");
+ mLogoutQuit = new RadioButton(_("Quit"), "quitdialog");
+ mSaveState = new CheckBox(_("Save state"), true);
+ mSwitchAccountServer = new RadioButton(_("Switch server"), "quitdialog");
+ mSwitchCharacter = new RadioButton(_("Switch character"), "quitdialog");
+ mOkButton = new Button(_("OK"), "ok", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+// setContentSize(width, height);
+
+ addKeyListener(this);
+
+ ContainerPlacer place = getPlacer(0, 0);
+
+ const State state = Client::getState();
+
+ // All states, when we're not logged in to someone.
+ if (state == STATE_CHOOSE_SERVER ||
+ state == STATE_CONNECT_SERVER ||
+ state == STATE_LOGIN ||
+ state == STATE_LOGIN_ATTEMPT ||
+ state == STATE_UPDATE ||
+ state == STATE_LOAD_DATA)
+ {
+ placeOption(place, mForceQuit);
+ }
+ else
+ {
+ // Only added if we are connected to an accountserver or gameserver
+ placeOption(place, mLogoutQuit);
+ placeOption(place, mSwitchAccountServer);
+
+ // Only added if we are connected to a gameserver
+ if (state == STATE_GAME)
+ placeOption(place, mSwitchCharacter);
+ }
+
+ mOptions[0]->setSelected(true);
+
+ place = getPlacer(0, 1);
+
+ place(0, 0, mSaveState, 3);
+ place(1, 1, mOkButton, 1);
+ place(2, 1, mCancelButton, 1);
+
+ reflowLayout(200, 0);
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+ requestModalFocus();
+ mOkButton->requestFocus();
+}
+
+QuitDialog::~QuitDialog()
+{
+ if (mMyPointer)
+ *mMyPointer = 0;
+ // Optional widgets, so delete them by hand.
+ delete mForceQuit;
+ mForceQuit = 0;
+ delete mLogoutQuit;
+ mLogoutQuit = 0;
+ delete mSwitchAccountServer;
+ mSwitchAccountServer = 0;
+ delete mSwitchCharacter;
+ mSwitchCharacter = 0;
+}
+
+void QuitDialog::placeOption(ContainerPlacer &place, gcn::RadioButton *option)
+{
+ place(0, static_cast<int>(mOptions.size()), option, 3);
+ mOptions.push_back(option);
+}
+
+void QuitDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ if (viewport)
+ {
+ Map *map = viewport->getCurrentMap();
+ if (map)
+ map->saveExtraLayer();
+ }
+ if (chatWindow && mSaveState->isSelected())
+ chatWindow->saveState();
+
+ if (mForceQuit->isSelected())
+ {
+ Client::setState(STATE_FORCE_QUIT);
+ }
+ else if (mLogoutQuit->isSelected())
+ {
+ Client::setState(STATE_EXIT);
+ }
+ else if (mSwitchAccountServer->isSelected())
+ {
+ Client::setState(STATE_SWITCH_SERVER);
+ }
+ else if (mSwitchCharacter->isSelected())
+ {
+ assert(Client::getState() == STATE_GAME);
+
+ Net::getCharHandler()->switchCharacter();
+ }
+ }
+ scheduleDelete();
+}
+
+void QuitDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ const gcn::Key &key = keyEvent.getKey();
+ int dir = 0;
+
+ switch (key.getValue())
+ {
+ case Key::ENTER:
+ action(gcn::ActionEvent(NULL, mOkButton->getActionEventId()));
+ break;
+ case Key::ESCAPE:
+ action(gcn::ActionEvent(NULL, mCancelButton->getActionEventId()));
+ break;
+ case Key::UP:
+ dir = -1;
+ break;
+ case Key::DOWN:
+ dir = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (dir != 0)
+ {
+ std::vector<gcn::RadioButton*>::iterator it = mOptions.begin();
+
+ for (; it < mOptions.end(); it++)
+ {
+ if ((*it)->isSelected())
+ break;
+ }
+
+ if (it == mOptions.end())
+ {
+ if (mOptions[0])
+ mOptions[0]->setSelected(true);
+ return;
+ }
+ else if (it == mOptions.begin() && dir < 0)
+ it = mOptions.end();
+
+ it += dir;
+
+ if (it == mOptions.end())
+ it = mOptions.begin();
+
+ (*it)->setSelected(true);
+ }
+}
diff --git a/src/gui/quitdialog.h b/src/gui/quitdialog.h
new file mode 100644
index 000000000..a6763079e
--- /dev/null
+++ b/src/gui/quitdialog.h
@@ -0,0 +1,77 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef QUITDIALOG_H
+#define QUITDIALOG_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+
+#include <vector>
+
+/**
+ * The quit dialog.
+ *
+ * \ingroup Interface
+ */
+class QuitDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @pointerToMe will be set to NULL when the QuitDialog is destroyed
+ */
+ QuitDialog(QuitDialog **pointerToMe);
+
+ /**
+ * Destructor
+ */
+ ~QuitDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ private:
+ void placeOption(ContainerPlacer &place, gcn::RadioButton *option);
+ std::vector<gcn::RadioButton*> mOptions;
+
+ gcn::RadioButton *mLogoutQuit;
+ gcn::CheckBox *mSaveState;
+ gcn::RadioButton *mForceQuit;
+ gcn::RadioButton *mSwitchAccountServer;
+ gcn::RadioButton *mSwitchCharacter;
+ gcn::Button *mOkButton;
+ gcn::Button *mCancelButton;
+
+ QuitDialog **mMyPointer;
+};
+
+#endif
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
new file mode 100644
index 000000000..fbd63195f
--- /dev/null
+++ b/src/gui/register.cpp
@@ -0,0 +1,258 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/register.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "log.h"
+
+#include "gui/login.h"
+#include "gui/okdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/passwordfield.h"
+#include "gui/widgets/radiobutton.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+WrongDataNoticeListener::WrongDataNoticeListener():
+ mTarget(0)
+{
+}
+
+void WrongDataNoticeListener::setTarget(gcn::TextField *textField)
+{
+ mTarget = textField;
+}
+
+void WrongDataNoticeListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok" && mTarget)
+ mTarget->requestFocus();
+}
+
+RegisterDialog::RegisterDialog(LoginData *loginData):
+ Window(_("Register")),
+ mEmailField(0),
+ mMaleButton(0),
+ mFemaleButton(0),
+ mWrongDataNoticeListener(new WrongDataNoticeListener),
+ mLoginData(loginData)
+{
+ int optionalActions = Net::getLoginHandler()->supportedOptionalActions();
+
+ gcn::Label *userLabel = new Label(_("Name:"));
+ gcn::Label *passwordLabel = new Label(_("Password:"));
+ gcn::Label *confirmLabel = new Label(_("Confirm:"));
+ mUserField = new TextField(loginData->username);
+ mPasswordField = new PasswordField(loginData->password);
+ mConfirmField = new PasswordField;
+ mRegisterButton = new Button(_("Register"), "register", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+ place(0, 0, userLabel);
+ place(0, 1, passwordLabel);
+ place(0, 2, confirmLabel);
+
+ place(1, 0, mUserField, 3).setPadding(2);
+ place(1, 1, mPasswordField, 3).setPadding(2);
+ place(1, 2, mConfirmField, 3).setPadding(2);
+
+ int row = 3;
+
+ if (optionalActions & Net::LoginHandler::SetGenderOnRegister)
+ {
+ mMaleButton = new RadioButton(_("Male"), "sex", true);
+ mFemaleButton = new RadioButton(_("Female"), "sex", false);
+ place(1, row, mMaleButton);
+ place(2, row, mFemaleButton);
+
+ row++;
+ }
+
+ if (optionalActions & Net::LoginHandler::SetEmailOnRegister)
+ {
+ gcn::Label *emailLabel = new Label(_("Email:"));
+ mEmailField = new TextField;
+ place(0, row, emailLabel);
+ place(1, row, mEmailField, 3).setPadding(2);
+
+ row++;
+ }
+
+ place = getPlacer(0, 2);
+ place(1, 0, mRegisterButton);
+ place(2, 0, mCancelButton);
+ reflowLayout(250, 0);
+
+ mUserField->addKeyListener(this);
+ mPasswordField->addKeyListener(this);
+ mConfirmField->addKeyListener(this);
+
+ /* TODO:
+ * This is a quick and dirty way to respond to the ENTER key, regardless of
+ * which text field is selected. There may be a better way now with the new
+ * input system of Guichan 0.6.0. See also the login dialog.
+ */
+ mUserField->setActionEventId("register");
+ mPasswordField->setActionEventId("register");
+ mConfirmField->setActionEventId("register");
+
+ mUserField->addActionListener(this);
+ mPasswordField->addActionListener(this);
+ mConfirmField->addActionListener(this);
+
+ center();
+ setVisible(true);
+ mUserField->requestFocus();
+ mUserField->setCaretPosition(static_cast<unsigned>(
+ mUserField->getText().length()));
+
+ mRegisterButton->setEnabled(canSubmit());
+}
+
+RegisterDialog::~RegisterDialog()
+{
+ delete mWrongDataNoticeListener;
+ mWrongDataNoticeListener = 0;
+}
+
+void RegisterDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ Client::setState(STATE_LOGIN);
+ }
+ else if (event.getId() == "register" && canSubmit())
+ {
+ const std::string user = mUserField->getText();
+ logger->log("RegisterDialog::register Username is %s", user.c_str());
+
+ std::string errorMessage;
+ int error = 0;
+
+ unsigned int minUser = Net::getLoginHandler()->getMinUserNameLength();
+ unsigned int maxUser = Net::getLoginHandler()->getMaxUserNameLength();
+ unsigned int minPass = Net::getLoginHandler()->getMinPasswordLength();
+ unsigned int maxPass = Net::getLoginHandler()->getMaxPasswordLength();
+
+ if (user.length() < minUser)
+ {
+ // Name too short
+ errorMessage = strprintf
+ (_("The username needs to be at least %d characters long."),
+ minUser);
+ error = 1;
+ }
+ else if (user.length() > maxUser - 1 )
+ {
+ // Name too long
+ errorMessage = strprintf
+ (_("The username needs to be less than %d characters long."),
+ maxUser);
+ error = 1;
+ }
+ else if (mPasswordField->getText().length() < minPass)
+ {
+ // Pass too short
+ errorMessage = strprintf
+ (_("The password needs to be at least %d characters long."),
+ minPass);
+ error = 2;
+ }
+ else if (mPasswordField->getText().length() > maxPass - 1 )
+ {
+ // Pass too long
+ errorMessage = strprintf
+ (_("The password needs to be less than %d characters long."),
+ maxPass);
+ error = 2;
+ }
+ else if (mPasswordField->getText() != mConfirmField->getText())
+ {
+ // Password does not match with the confirmation one
+ errorMessage = _("Passwords do not match.");
+ error = 2;
+ }
+
+ // TODO: Check if a valid email address was given
+
+ if (error > 0)
+ {
+ if (error == 1)
+ {
+ mWrongDataNoticeListener->setTarget(this->mUserField);
+ }
+ else if (error == 2)
+ {
+ // Reset password confirmation
+ mPasswordField->setText("");
+ mConfirmField->setText("");
+
+ mWrongDataNoticeListener->setTarget(this->mPasswordField);
+ }
+
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage);
+ dlg->addActionListener(mWrongDataNoticeListener);
+ }
+ else
+ {
+ // No errors detected, register the new user.
+ mRegisterButton->setEnabled(false);
+
+ mLoginData->username = mUserField->getText();
+ mLoginData->password = mPasswordField->getText();
+ if (mFemaleButton)
+ mLoginData->gender = mFemaleButton->isSelected() ?
+ GENDER_FEMALE : GENDER_MALE;
+ if (mEmailField)
+ mLoginData->email = mEmailField->getText();
+ mLoginData->registerLogin = true;
+
+ Client::setState(STATE_REGISTER_ATTEMPT);
+ }
+ }
+}
+
+void RegisterDialog::keyPressed(gcn::KeyEvent &keyEvent _UNUSED_)
+{
+ mRegisterButton->setEnabled(canSubmit());
+}
+
+bool RegisterDialog::canSubmit() const
+{
+ return !mUserField->getText().empty() &&
+ !mPasswordField->getText().empty() &&
+ !mConfirmField->getText().empty() &&
+ Client::getState() == STATE_REGISTER;
+}
diff --git a/src/gui/register.h b/src/gui/register.h
new file mode 100644
index 000000000..f9c866768
--- /dev/null
+++ b/src/gui/register.h
@@ -0,0 +1,110 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef REGISTER_H
+#define REGISTER_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class LoginData;
+class OkDialog;
+
+/**
+ * Listener used while dealing with wrong data. It is used to direct the focus
+ * to the field which contained wrong data when the Ok button was pressed on
+ * the error notice.
+ */
+class WrongDataNoticeListener : public gcn::ActionListener
+{
+ public:
+ WrongDataNoticeListener();
+ void setTarget(gcn::TextField *textField);
+ void action(const gcn::ActionEvent &event);
+ private:
+ gcn::TextField *mTarget;
+};
+
+/**
+ * The registration dialog.
+ *
+ * \ingroup Interface
+ */
+class RegisterDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ /**
+ * Constructor. Name, password and server fields will be initialized to
+ * the information already present in the LoginData instance.
+ *
+ * @see Window::Window
+ */
+ RegisterDialog(LoginData *loginData);
+
+ /**
+ * Destructor
+ */
+ ~RegisterDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Called when a key is pressed in one of the text fields.
+ */
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ private:
+ /**
+ * Returns whether submit can be enabled. This is true in the register
+ * state, when all necessary fields have some text.
+ */
+ bool canSubmit() const;
+
+ gcn::TextField *mUserField;
+ gcn::TextField *mPasswordField;
+ gcn::TextField *mConfirmField;
+ gcn::TextField *mEmailField;
+
+ gcn::Button *mRegisterButton;
+ gcn::Button *mCancelButton;
+ gcn::RadioButton *mMaleButton;
+ gcn::RadioButton *mFemaleButton;
+
+ WrongDataNoticeListener *mWrongDataNoticeListener;
+
+ LoginData *mLoginData;
+};
+
+#endif
diff --git a/src/gui/sdlinput.cpp b/src/gui/sdlinput.cpp
new file mode 100644
index 000000000..a48f35be8
--- /dev/null
+++ b/src/gui/sdlinput.cpp
@@ -0,0 +1,432 @@
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessn and Per Larsson
+ * Copyright (C) 2007-2010 The Mana World Development Team
+ *
+ * Js_./
+ * Per Larsson a.k.a finalman _RqZ{a<^_aa
+ * Olof Naessn a.k.a jansem/yakslem _asww7!uY`> )\a//
+ * _Qhm`] _f "'c 1!5m
+ * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
+ * .)j(] .d_/ '-( P . S
+ * License: (BSD) <Td/Z <fP"5(\"??"\a. .L
+ * Redistribution and use in source and _dV>ws?a-?' ._/L #'
+ * binary forms, with or without )4d[#7r, . ' )d`)[
+ * modification, are permitted provided _Q-5'5W..j/?' -?!\)cam'
+ * that the following conditions are met: j<<WP+k/);. _W=j f
+ * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$
+ * retain the above copyright notice, ]E.pYY(Q]>. a J@\
+ * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a
+ * following disclaimer. 4'_uomm\. )L);-4 (3=
+ * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[
+ * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m
+ * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/
+ * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m
+ * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]'
+ * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W"
+ * 3. Neither the name of Guichan nor the :$we` _! + _/ . j?
+ * names of its contributors may be used =3)= _f (_yQmWW$#( "
+ * to endorse or promote products derived - W, sQQQQmZQ#Wwa]..
+ * from this software without specific (js, \[QQW$QWW#?!V"".
+ * prior written permission. ]y:.<\.. .
+ * -]n w/ ' [.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ !
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , '
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- %
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'.,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?"
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. .
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sdlinput.h"
+
+#include <guichan/exception.hpp>
+
+SDLInput::SDLInput()
+{
+ mMouseInWindow = true;
+ mMouseDown = false;
+}
+
+bool SDLInput::isKeyQueueEmpty()
+{
+ return mKeyInputQueue.empty();
+}
+
+gcn::KeyInput SDLInput::dequeueKeyInput()
+{
+ gcn::KeyInput keyInput;
+
+ if (mKeyInputQueue.empty())
+ {
+ throw GCN_EXCEPTION("The queue is empty.");
+ }
+
+ keyInput = mKeyInputQueue.front();
+ mKeyInputQueue.pop();
+
+ return keyInput;
+}
+
+bool SDLInput::isMouseQueueEmpty()
+{
+ return mMouseInputQueue.empty();
+}
+
+gcn::MouseInput SDLInput::dequeueMouseInput()
+{
+ gcn::MouseInput mouseInput;
+
+ if (mMouseInputQueue.empty())
+ {
+ throw GCN_EXCEPTION("The queue is empty.");
+ }
+
+ mouseInput = mMouseInputQueue.front();
+ mMouseInputQueue.pop();
+
+ return mouseInput;
+}
+
+void SDLInput::pushInput(SDL_Event event)
+{
+ gcn::KeyInput keyInput;
+ gcn::MouseInput mouseInput;
+
+ switch (event.type)
+ {
+ case SDL_KEYDOWN:
+ keyInput.setKey(gcn::Key(convertKeyCharacter(event)));
+ keyInput.setType(gcn::KeyInput::PRESSED);
+ keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
+ keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
+ keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
+ keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
+ keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
+ && event.key.keysym.sym <= SDLK_KP_EQUALS);
+
+ mKeyInputQueue.push(keyInput);
+ break;
+
+ case SDL_KEYUP:
+ keyInput.setKey(gcn::Key(convertKeyCharacter(event)));
+ keyInput.setType(gcn::KeyInput::RELEASED);
+ keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
+ keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
+ keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
+ keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
+ keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
+ && event.key.keysym.sym <= SDLK_KP_EQUALS);
+
+ mKeyInputQueue.push(keyInput);
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ mMouseDown = true;
+ mouseInput.setX(event.button.x);
+ mouseInput.setY(event.button.y);
+ mouseInput.setButton(convertMouseButton(event.button.button));
+
+ if (event.button.button == SDL_BUTTON_WHEELDOWN)
+ {
+ mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_DOWN);
+ }
+ else if (event.button.button == SDL_BUTTON_WHEELUP)
+ {
+ mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_UP);
+ }
+ else
+ {
+ mouseInput.setType(gcn::MouseInput::PRESSED);
+ }
+ mouseInput.setTimeStamp(SDL_GetTicks());
+ mMouseInputQueue.push(mouseInput);
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ mMouseDown = false;
+ mouseInput.setX(event.button.x);
+ mouseInput.setY(event.button.y);
+ mouseInput.setButton(convertMouseButton(event.button.button));
+ mouseInput.setType(gcn::MouseInput::RELEASED);
+ mouseInput.setTimeStamp(SDL_GetTicks());
+ mMouseInputQueue.push(mouseInput);
+ break;
+
+ case SDL_MOUSEMOTION:
+ mouseInput.setX(event.button.x);
+ mouseInput.setY(event.button.y);
+ mouseInput.setButton(gcn::MouseInput::EMPTY);
+ mouseInput.setType(gcn::MouseInput::MOVED);
+ mouseInput.setTimeStamp(SDL_GetTicks());
+ mMouseInputQueue.push(mouseInput);
+ break;
+
+ case SDL_ACTIVEEVENT:
+ /*
+ * This occurs when the mouse leaves the window and the Gui-chan
+ * application loses its mousefocus.
+ */
+ if ((event.active.state & SDL_APPMOUSEFOCUS)
+ && !event.active.gain)
+ {
+ mMouseInWindow = false;
+
+ if (!mMouseDown)
+ {
+ mouseInput.setX(-1);
+ mouseInput.setY(-1);
+ mouseInput.setButton(gcn::MouseInput::EMPTY);
+ mouseInput.setType(gcn::MouseInput::MOVED);
+ mMouseInputQueue.push(mouseInput);
+ }
+ }
+
+ if ((event.active.state & SDL_APPMOUSEFOCUS)
+ && event.active.gain)
+ {
+ mMouseInWindow = true;
+ }
+ break;
+
+ default:
+ break;
+
+ } // end switch
+}
+
+int SDLInput::convertMouseButton(int button)
+{
+ switch (button)
+ {
+ case SDL_BUTTON_LEFT:
+ return gcn::MouseInput::LEFT;
+ case SDL_BUTTON_RIGHT:
+ return gcn::MouseInput::RIGHT;
+ case SDL_BUTTON_MIDDLE:
+ return gcn::MouseInput::MIDDLE;
+ default:
+ // We have an unknown mouse type which is ignored.
+ return button;
+ }
+}
+
+int SDLInput::convertKeyCharacter(SDL_Event event)
+{
+ SDL_keysym keysym = event.key.keysym;
+
+ int value = keysym.unicode;
+
+ switch (keysym.sym)
+ {
+ case SDLK_TAB:
+ value = Key::TAB;
+ break;
+ case SDLK_LALT:
+ value = Key::LEFT_ALT;
+ break;
+ case SDLK_RALT:
+ value = Key::RIGHT_ALT;
+ break;
+ case SDLK_LSHIFT:
+ value = Key::LEFT_SHIFT;
+ break;
+ case SDLK_RSHIFT:
+ value = Key::RIGHT_SHIFT;
+ break;
+ case SDLK_LCTRL:
+ value = Key::LEFT_CONTROL;
+ break;
+ case SDLK_RCTRL:
+ value = Key::RIGHT_CONTROL;
+ break;
+ case SDLK_BACKSPACE:
+ value = Key::BACKSPACE;
+ break;
+ case SDLK_PAUSE:
+ value = Key::PAUSE;
+ break;
+ case SDLK_SPACE:
+ // Special characters like ~ (tilde) ends up
+ // with the keysym.sym SDLK_SPACE which
+ // without this check would be lost. The check
+ // is only valid on key down events in SDL.
+ if (event.type == SDL_KEYUP || keysym.unicode == ' ')
+ {
+ value = Key::SPACE;
+ }
+ break;
+ case SDLK_ESCAPE:
+ value = Key::ESCAPE;
+ break;
+ case SDLK_DELETE:
+ value = Key::DELETE;
+ break;
+ case SDLK_INSERT:
+ value = Key::INSERT;
+ break;
+ case SDLK_HOME:
+ value = Key::HOME;
+ break;
+ case SDLK_END:
+ value = Key::END;
+ break;
+ case SDLK_PAGEUP:
+ value = Key::PAGE_UP;
+ break;
+ case SDLK_PRINT:
+ value = Key::PRINT_SCREEN;
+ break;
+ case SDLK_PAGEDOWN:
+ value = Key::PAGE_DOWN;
+ break;
+ case SDLK_F1:
+ value = Key::F1;
+ break;
+ case SDLK_F2:
+ value = Key::F2;
+ break;
+ case SDLK_F3:
+ value = Key::F3;
+ break;
+ case SDLK_F4:
+ value = Key::F4;
+ break;
+ case SDLK_F5:
+ value = Key::F5;
+ break;
+ case SDLK_F6:
+ value = Key::F6;
+ break;
+ case SDLK_F7:
+ value = Key::F7;
+ break;
+ case SDLK_F8:
+ value = Key::F8;
+ break;
+ case SDLK_F9:
+ value = Key::F9;
+ break;
+ case SDLK_F10:
+ value = Key::F10;
+ break;
+ case SDLK_F11:
+ value = Key::F11;
+ break;
+ case SDLK_F12:
+ value = Key::F12;
+ break;
+ case SDLK_F13:
+ value = Key::F13;
+ break;
+ case SDLK_F14:
+ value = Key::F14;
+ break;
+ case SDLK_F15:
+ value = Key::F15;
+ break;
+ case SDLK_NUMLOCK:
+ value = Key::NUM_LOCK;
+ break;
+ case SDLK_CAPSLOCK:
+ value = Key::CAPS_LOCK;
+ break;
+ case SDLK_SCROLLOCK:
+ value = Key::SCROLL_LOCK;
+ break;
+ case SDLK_RMETA:
+ value = Key::RIGHT_META;
+ break;
+ case SDLK_LMETA:
+ value = Key::LEFT_META;
+ break;
+ case SDLK_LSUPER:
+ value = Key::LEFT_SUPER;
+ break;
+ case SDLK_RSUPER:
+ value = Key::RIGHT_SUPER;
+ break;
+ case SDLK_MODE:
+ value = Key::ALT_GR;
+ break;
+ case SDLK_UP:
+ value = Key::UP;
+ break;
+ case SDLK_DOWN:
+ value = Key::DOWN;
+ break;
+ case SDLK_LEFT:
+ value = Key::LEFT;
+ break;
+ case SDLK_RIGHT:
+ value = Key::RIGHT;
+ break;
+ case SDLK_RETURN:
+ value = Key::ENTER;
+ break;
+ case SDLK_KP_ENTER:
+ value = Key::ENTER;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!(keysym.mod & KMOD_NUM))
+ {
+ switch (keysym.sym)
+ {
+ case SDLK_KP0:
+ value = Key::INSERT;
+ break;
+ case SDLK_KP1:
+ value = Key::END;
+ break;
+ case SDLK_KP2:
+ value = Key::DOWN;
+ break;
+ case SDLK_KP3:
+ value = Key::PAGE_DOWN;
+ break;
+ case SDLK_KP4:
+ value = Key::LEFT;
+ break;
+ case SDLK_KP5:
+ value = 0;
+ break;
+ case SDLK_KP6:
+ value = Key::RIGHT;
+ break;
+ case SDLK_KP7:
+ value = Key::HOME;
+ break;
+ case SDLK_KP8:
+ value = Key::UP;
+ break;
+ case SDLK_KP9:
+ value = Key::PAGE_UP;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return value;
+}
diff --git a/src/gui/sdlinput.h b/src/gui/sdlinput.h
new file mode 100644
index 000000000..b441380a4
--- /dev/null
+++ b/src/gui/sdlinput.h
@@ -0,0 +1,188 @@
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessn and Per Larsson
+ * Copyright (C) 2007-2010 The Mana World Development Team
+ *
+ * Js_./
+ * Per Larsson a.k.a finalman _RqZ{a<^_aa
+ * Olof Naessn a.k.a jansem/yakslem _asww7!uY`> )\a//
+ * _Qhm`] _f "'c 1!5m
+ * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
+ * .)j(] .d_/ '-( P . S
+ * License: (BSD) <Td/Z <fP"5(\"??"\a. .L
+ * Redistribution and use in source and _dV>ws?a-?' ._/L #'
+ * binary forms, with or without )4d[#7r, . ' )d`)[
+ * modification, are permitted provided _Q-5'5W..j/?' -?!\)cam'
+ * that the following conditions are met: j<<WP+k/);. _W=j f
+ * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$
+ * retain the above copyright notice, ]E.pYY(Q]>. a J@\
+ * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a
+ * following disclaimer. 4'_uomm\. )L);-4 (3=
+ * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[
+ * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m
+ * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/
+ * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m
+ * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]'
+ * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W"
+ * 3. Neither the name of Guichan nor the :$we` _! + _/ . j?
+ * names of its contributors may be used =3)= _f (_yQmWW$#( "
+ * to endorse or promote products derived - W, sQQQQmZQ#Wwa]..
+ * from this software without specific (js, \[QQW$QWW#?!V"".
+ * prior written permission. ]y:.<\.. .
+ * -]n w/ ' [.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ !
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , '
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- %
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'.,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?"
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. .
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SDLINPUT_H
+#define SDLINPUT_H
+
+#include <queue>
+
+#include <SDL/SDL.h>
+
+#include <guichan/input.hpp>
+#include <guichan/keyinput.hpp>
+#include <guichan/mouseinput.hpp>
+#include <guichan/platform.hpp>
+
+namespace Key
+{
+ enum
+ {
+ SPACE = ' ',
+ TAB = '\t',
+ ENTER = '\n',
+ // Negative values, to avoid conflicts with higher character codes.
+ LEFT_ALT = -1000,
+ RIGHT_ALT,
+ LEFT_SHIFT,
+ RIGHT_SHIFT,
+ LEFT_CONTROL,
+ RIGHT_CONTROL,
+ LEFT_META,
+ RIGHT_META,
+ LEFT_SUPER,
+ RIGHT_SUPER,
+ INSERT,
+ HOME,
+ PAGE_UP,
+ DELETE,
+ END,
+ PAGE_DOWN,
+ ESCAPE,
+ CAPS_LOCK,
+ BACKSPACE,
+ F1,
+ F2,
+ F3,
+ F4,
+ F5,
+ F6,
+ F7,
+ F8,
+ F9,
+ F10,
+ F11,
+ F12,
+ F13,
+ F14,
+ F15,
+ PRINT_SCREEN,
+ SCROLL_LOCK,
+ PAUSE,
+ NUM_LOCK,
+ ALT_GR,
+ LEFT,
+ RIGHT,
+ UP,
+ DOWN
+ };
+}
+
+/**
+ * SDL implementation of Input.
+ */
+class SDLInput : public gcn::Input
+{
+public:
+
+ /**
+ * Constructor.
+ */
+ SDLInput();
+
+ /**
+ * Pushes an SDL event. It should be called at least once per frame to
+ * update input with user input.
+ *
+ * @param event an event from SDL.
+ */
+ virtual void pushInput(SDL_Event event);
+
+ /**
+ * Polls all input. It exists for input driver compatibility. If you
+ * only use SDL and plan sticking with SDL you can safely ignore this
+ * function as it in the SDL case does nothing.
+ */
+ virtual void _pollInput() { }
+
+
+ // Inherited from Input
+
+ virtual bool isKeyQueueEmpty();
+
+ virtual gcn::KeyInput dequeueKeyInput();
+
+ virtual bool isMouseQueueEmpty();
+
+ virtual gcn::MouseInput dequeueMouseInput();
+
+protected:
+ /**
+ * Converts a mouse button from SDL to a Guichan mouse button
+ * representation.
+ *
+ * @param button an SDL mouse button.
+ * @return a Guichan mouse button.
+ */
+ int convertMouseButton(int button);
+
+ /**
+ * Converts an SDL event key to a key value.
+ *
+ * @param event an SDL event with a key to convert.
+ * @return a key value.
+ * @see Key
+ */
+ int convertKeyCharacter(SDL_Event event);
+
+ std::queue<gcn::KeyInput> mKeyInputQueue;
+ std::queue<gcn::MouseInput> mMouseInputQueue;
+
+ bool mMouseDown;
+ bool mMouseInWindow;
+};
+
+#endif
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
new file mode 100644
index 000000000..85577b245
--- /dev/null
+++ b/src/gui/sell.cpp
@@ -0,0 +1,333 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/sell.h"
+
+#include "shopitem.h"
+#include "units.h"
+
+#include "gui/setup.h"
+#include "gui/trade.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/shopitems.h"
+#include "gui/widgets/shoplistbox.h"
+#include "gui/widgets/slider.h"
+
+#include "net/buysellhandler.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+SellDialog::DialogList SellDialog::instances;
+
+SellDialog::SellDialog(int npcId):
+ Window(_("Sell")),
+ mNpcId(npcId), mMaxItems(0), mAmountItems(0), mNick("")
+{
+ init();
+}
+
+SellDialog::SellDialog(std::string nick):
+ Window(_("Sell")),
+ mNpcId(-1), mMaxItems(0), mAmountItems(0), mNick(nick)
+{
+ init();
+}
+
+void SellDialog::init()
+{
+ setWindowName("Sell");
+ //setupWindow->registerWindowForReset(this);
+ setResizable(true);
+ setCloseButton(true);
+ setMinWidth(260);
+ setMinHeight(230);
+ setDefaultSize(260, 230, ImageRect::CENTER);
+
+ // Create a ShopItems instance, that is aware of duplicate entries.
+ mShopItems = new ShopItems(true);
+
+ mShopItemList = new ShopListBox(mShopItems, mShopItems);
+ mScrollArea = new ScrollArea(mShopItemList);
+ mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mSlider = new Slider(1.0);
+
+ mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mQuantityLabel->setAlignment(gcn::Graphics::CENTER);
+ mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"),
+ "", ""));
+
+ mIncreaseButton = new Button(_("+"), "inc", this);
+ mDecreaseButton = new Button(_("-"), "dec", this);
+ mSellButton = new Button(_("Sell"), "sell", this);
+ mQuitButton = new Button(_("Quit"), "quit", this);
+ mAddMaxButton = new Button(_("Max"), "max", this);
+
+ mDecreaseButton->adjustSize();
+ mDecreaseButton->setWidth(mIncreaseButton->getWidth());
+
+ mIncreaseButton->setEnabled(false);
+ mDecreaseButton->setEnabled(false);
+ mSellButton->setEnabled(false);
+ mSlider->setEnabled(false);
+
+ mShopItemList->setPriceCheck(false);
+ mShopItemList->addSelectionListener(this);
+ mSlider->setActionEventId("slider");
+ mSlider->addActionListener(this);
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mScrollArea, 8, 5).setPadding(3);
+ place(0, 5, mDecreaseButton);
+ place(1, 5, mSlider, 3);
+ place(4, 5, mIncreaseButton);
+ place(5, 5, mQuantityLabel, 2);
+ place(7, 5, mAddMaxButton);
+ place(0, 6, mMoneyLabel, 8);
+ place(6, 7, mSellButton);
+ place(7, 7, mQuitButton);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+
+ center();
+ loadWindowState();
+
+ instances.push_back(this);
+ setVisible(true);
+}
+
+SellDialog::~SellDialog()
+{
+ delete mShopItems;
+ mShopItems = 0;
+
+ instances.remove(this);
+}
+
+void SellDialog::reset()
+{
+ mShopItems->clear();
+ mSlider->setValue(0);
+
+ // Reset previous selected item to prevent failing asserts
+ mShopItemList->setSelected(-1);
+
+ updateButtonsAndLabels();
+}
+
+void SellDialog::addItem(const Item *item, int price)
+{
+ if (!item)
+ return;
+
+ mShopItems->addItem(item->getInvIndex(), item->getId(),
+ item->getQuantity(), price);
+
+ mShopItemList->adjustSize();
+}
+
+void SellDialog::addItem(int id, int amount, int price)
+{
+ mShopItems->addItem(id, amount, price);
+ mShopItemList->adjustSize();
+}
+
+
+void SellDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "quit")
+ {
+ close();
+ return;
+ }
+
+ int selectedItem = mShopItemList->getSelected();
+
+ // The following actions require a valid item selection
+ if (selectedItem == -1 ||
+ selectedItem >= static_cast<int>(mShopItems->getNumberOfElements()))
+ {
+ return;
+ }
+
+ if (event.getId() == "slider")
+ {
+ mAmountItems = static_cast<int>(mSlider->getValue());
+ updateButtonsAndLabels();
+ }
+ else if (event.getId() == "inc" && mAmountItems < mMaxItems)
+ {
+ mAmountItems++;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
+ else if (event.getId() == "dec" && mAmountItems > 1)
+ {
+ mAmountItems--;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
+ else if (event.getId() == "max")
+ {
+ mAmountItems = mMaxItems;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
+ else if (event.getId() == "sell" && mAmountItems > 0
+ && mAmountItems <= mMaxItems)
+ {
+ if (mNpcId != -1)
+ {
+ // Attempt sell
+ ShopItem *item = mShopItems->at(selectedItem);
+ int sellCount, itemIndex;
+ mPlayerMoney +=
+ mAmountItems * mShopItems->at(selectedItem)->getPrice();
+ mMaxItems -= mAmountItems;
+ while (mAmountItems > 0)
+ {
+ // This order is important, item->getCurrentInvIndex() would return
+ // the inventory index of the next Duplicate otherwise.
+ itemIndex = item->getCurrentInvIndex();
+ sellCount = item->sellCurrentDuplicate(mAmountItems);
+
+ // For Manaserv, the Item id is to be given as index.
+ if ((Net::getNetworkType() == ServerInfo::MANASERV))
+ itemIndex = item->getId();
+
+ Net::getNpcHandler()->sellItem(mNpcId, itemIndex, sellCount);
+ mAmountItems -= sellCount;
+ }
+
+ mPlayerMoney +=
+ mAmountItems * mShopItems->at(selectedItem)->getPrice();
+ mAmountItems = 1;
+ mSlider->setValue(0);
+
+ if (!mMaxItems)
+ {
+ // All were sold
+ mShopItemList->setSelected(-1);
+ delete mShopItems->at(selectedItem);
+ mShopItems->erase(selectedItem);
+
+ gcn::Rectangle scroll;
+ scroll.y = mShopItemList->getRowHeight() * (selectedItem + 1);
+ scroll.height = mShopItemList->getRowHeight();
+ mShopItemList->showPart(scroll);
+ }
+ }
+ else
+ {
+ ShopItem *item = mShopItems->at(selectedItem);
+
+ Net::getBuySellHandler()->sendSellRequest(mNick,
+ item, mAmountItems);
+
+ if (tradeWindow)
+ tradeWindow->addAutoItem(mNick, item, mAmountItems);
+ }
+ }
+}
+
+void SellDialog::valueChanged(const gcn::SelectionEvent &event _UNUSED_)
+{
+ // Reset amount of items and update labels
+ mAmountItems = 1;
+ mSlider->setValue(0);
+
+ updateButtonsAndLabels();
+ mSlider->gcn::Slider::setScale(1, mMaxItems);
+}
+
+void SellDialog::setMoney(int amount)
+{
+ mPlayerMoney = amount;
+ mShopItemList->setPlayersMoney(amount);
+}
+
+void SellDialog::updateButtonsAndLabels()
+{
+ int selectedItem = mShopItemList->getSelected();
+ int income = 0;
+
+ if (selectedItem > -1 && mShopItems->at(selectedItem))
+ {
+ mMaxItems = mShopItems->at(selectedItem)->getQuantity();
+ if (mAmountItems > mMaxItems)
+ mAmountItems = mMaxItems;
+
+ income = mAmountItems * mShopItems->at(selectedItem)->getPrice();
+ }
+ else
+ {
+ mMaxItems = 0;
+ mAmountItems = 0;
+ }
+
+ // Update Buttons and slider
+ mSellButton->setEnabled(mAmountItems > 0);
+ mDecreaseButton->setEnabled(mAmountItems > 1);
+ mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
+ mSlider->setEnabled(mMaxItems > 1);
+
+ // Update the quantity and money labels
+ mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"),
+ Units::formatCurrency(income).c_str(),
+ Units::formatCurrency(mPlayerMoney + income).c_str()));
+}
+
+void SellDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (visible)
+ {
+ if (mShopItemList)
+ mShopItemList->requestFocus();
+ }
+ else
+ {
+ scheduleDelete();
+ }
+}
+
+void SellDialog::closeAll()
+{
+ DialogList::iterator it = instances.begin();
+ DialogList::iterator it_end = instances.end();
+
+ for (; it != it_end; it++)
+ (*it)->close();
+}
diff --git a/src/gui/sell.h b/src/gui/sell.h
new file mode 100644
index 000000000..fd6245eb8
--- /dev/null
+++ b/src/gui/sell.h
@@ -0,0 +1,145 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SELL_H
+#define SELL_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#include <SDL_types.h>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Item;
+class ShopItems;
+class ShopListBox;
+
+/**
+ * The sell dialog.
+ *
+ * \ingroup Interface
+ */
+class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ SellDialog(int npcId);
+
+ /**
+ * Constructor.
+ */
+ SellDialog(std::string nick);
+
+ /**
+ * Destructor
+ */
+ virtual ~SellDialog();
+
+ void init();
+
+ /**
+ * Resets the dialog, clearing inventory.
+ */
+ void reset();
+
+ /**
+ * Adds an item to the inventory.
+ */
+ void addItem(const Item *item, int price);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Updates labels according to selected item.
+ *
+ * @see SelectionListener::selectionChanged
+ */
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ /**
+ * Gives Player's Money amount
+ */
+ void setMoney(int amount);
+
+ /**
+ * Sets the visibility of this window.
+ */
+ void setVisible(bool visible);
+
+ void addItem(int id, int amount, int price);
+
+ /**
+ * Returns true if any instances exist.
+ */
+ static bool isActive()
+ { return !instances.empty(); }
+
+ /**
+ * Closes all instances.
+ */
+ static void closeAll();
+
+ private:
+ typedef std::list<SellDialog*> DialogList;
+ static DialogList instances;
+
+ /**
+ * Updates the state of buttons and labels.
+ */
+ void updateButtonsAndLabels();
+
+ int mNpcId;
+
+ gcn::Button *mSellButton;
+ gcn::Button *mQuitButton;
+ gcn::Button *mAddMaxButton;
+ gcn::Button *mIncreaseButton;
+ gcn::Button *mDecreaseButton;
+ ShopListBox *mShopItemList;
+ gcn::ScrollArea *mScrollArea;
+ gcn::Label *mMoneyLabel;
+ gcn::Label *mQuantityLabel;
+ gcn::Slider *mSlider;
+
+ ShopItems *mShopItems;
+ int mPlayerMoney;
+
+ int mMaxItems;
+ int mAmountItems;
+
+ std::string mNick;
+};
+
+#endif
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp
new file mode 100644
index 000000000..c7e1d0f94
--- /dev/null
+++ b/src/gui/serverdialog.cpp
@@ -0,0 +1,768 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/serverdialog.h"
+
+#include "chatlog.h"
+#include "client.h"
+#include "configuration.h"
+#include "gui.h"
+#include "log.h"
+#include "main.h"
+
+#include "gui/login.h"
+#include "gui/okdialog.h"
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/dropdown.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/net.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+#include "widgets/dropdown.h"
+
+#include <guichan/font.hpp>
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+static const int MAX_SERVERLIST = 15;
+
+static std::string serverTypeToString(ServerInfo::Type type)
+{
+ switch (type)
+ {
+ case ServerInfo::TMWATHENA:
+ return "TmwAthena";
+ case ServerInfo::MANASERV:
+ return "ManaServ";
+ default:
+ return "";
+ }
+}
+
+static unsigned short defaultPortForServerType(ServerInfo::Type type)
+{
+ switch (type)
+ {
+ default:
+ case ServerInfo::TMWATHENA:
+ return 6901;
+ case ServerInfo::MANASERV:
+ return 9601;
+ }
+}
+
+ServersListModel::ServersListModel(ServerInfos *servers, ServerDialog *parent):
+ mServers(servers),
+ mVersionStrings(servers->size(), VersionString(0, "")),
+ mParent(parent)
+{
+}
+
+int ServersListModel::getNumberOfElements()
+{
+ MutexLocker lock = mParent->lock();
+ return static_cast<int>(mServers->size());
+}
+
+std::string ServersListModel::getElementAt(int elementIndex)
+{
+ MutexLocker lock = mParent->lock();
+ const ServerInfo &server = mServers->at(elementIndex);
+ std::string myServer;
+ myServer += server.hostname;
+ myServer += ":";
+ myServer += toString(server.port);
+ return myServer;
+}
+
+void ServersListModel::setVersionString(int index, const std::string &version)
+{
+ if (version.empty())
+ {
+ mVersionStrings[index] = VersionString(0, "");
+ }
+ else
+ {
+ int width = gui->getFont()->getWidth(version);
+ mVersionStrings[index] = VersionString(width, version);
+ }
+}
+
+std::string TypeListModel::getElementAt(int elementIndex)
+{
+ if (elementIndex == 0)
+ return "TmwAthena";
+ else if (elementIndex == 1)
+ return "ManaServ";
+ else
+ return "Unknown";
+}
+
+class ServersListBox : public ListBox
+{
+public:
+ ServersListBox(ServersListModel *model):
+ ListBox(model)
+ {
+ }
+
+ void draw(gcn::Graphics *graphics)
+ {
+ if (!mListModel)
+ return;
+
+ ServersListModel *model = static_cast<ServersListModel*>(mListModel);
+
+ updateAlpha();
+
+ graphics->setColor(Theme::getThemeColor(Theme::HIGHLIGHT,
+ static_cast<int>(mAlpha * 255.0f)));
+ graphics->setFont(getFont());
+
+ const int height = getRowHeight();
+ const gcn::Color unsupported =
+ Theme::getThemeColor(Theme::SERVER_VERSION_NOT_SUPPORTED,
+ static_cast<int>(mAlpha * 255.0f));
+
+ // Draw filled rectangle around the selected list element
+ if (mSelected >= 0)
+ {
+ graphics->fillRectangle(gcn::Rectangle(0, height * mSelected,
+ getWidth(), height));
+ }
+
+ // Draw the list elements
+ for (int i = 0, y = 0; i < model->getNumberOfElements();
+ ++i, y += height)
+ {
+ ServerInfo info = model->getServer(i);
+
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+
+ int top;
+
+ if (!info.name.empty())
+ {
+ graphics->setFont(boldFont);
+ graphics->drawText(info.name, 2, y);
+ top = y + height / 2;
+ }
+ else
+ {
+ top = y + height / 4;
+ }
+
+ graphics->setFont(getFont());
+
+ graphics->drawText(model->getElementAt(i), 2, top);
+
+ if (info.version.first > 0)
+ {
+ graphics->setColor(unsupported);
+
+ graphics->drawText(info.version.second,
+ getWidth() - info.version.first - 2, top);
+ }
+ }
+ }
+
+ unsigned int getRowHeight() const
+ {
+ return 2 * getFont()->getHeight();
+ }
+};
+
+
+ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
+ Window(_("Choose Your Server")),
+ mDir(dir),
+// mDownloadStatus(DOWNLOADING_PREPARING),
+ mDownloadStatus(DOWNLOADING_UNKNOWN),
+ mDownload(0),
+ mDownloadProgress(-1.0f),
+ mServers(ServerInfos()),
+ mServerInfo(serverInfo)
+{
+ if (isSafeMode)
+ setCaption("Choose Your Server *** SAFE MODE ***");
+
+ setWindowName("ServerDialog");
+
+ Label *serverLabel = new Label(_("Server:"));
+ Label *portLabel = new Label(_("Port:"));
+ Label *typeLabel = new Label(_("Server type:"));
+ mServerNameField = new TextField(mServerInfo->hostname);
+ mPortField = new TextField(toString(mServerInfo->port));
+
+ loadCustomServers();
+
+ mServersListModel = new ServersListModel(&mServers, this);
+
+ mServersList = new ServersListBox(mServersListModel);
+ mServersList->addMouseListener(this);
+
+ ScrollArea *usedScroll = new ScrollArea(mServersList);
+ usedScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mTypeListModel = new TypeListModel();
+ mTypeField = new DropDown(mTypeListModel);
+ mTypeField->setSelected((serverInfo->type == ServerInfo::MANASERV) ?
+ 1 : 0);
+
+ mDescription = new Label(std::string());
+
+ mQuitButton = new Button(_("Quit"), "quit", this);
+ mLoadButton = new Button(_("Load"), "load", this);
+ mConnectButton = new Button(_("Connect"), "connect", this);
+ mManualEntryButton = new Button(_("Custom Server"), "addEntry", this);
+ mDeleteButton = new Button(_("Delete"), "remove", this);
+
+ mServerNameField->setActionEventId("connect");
+ mPortField->setActionEventId("connect");
+
+ mServerNameField->addActionListener(this);
+ mPortField->addActionListener(this);
+ mManualEntryButton->addActionListener(this);
+ mServersList->addSelectionListener(this);
+ usedScroll->setVerticalScrollAmount(0);
+
+ place(0, 0, serverLabel);
+ place(1, 0, mServerNameField, 5).setPadding(3);
+ place(0, 1, portLabel);
+ place(1, 1, mPortField, 5).setPadding(3);
+ place(0, 2, typeLabel);
+ place(1, 2, mTypeField, 5).setPadding(3);
+ place(0, 3, usedScroll, 6, 5).setPadding(3);
+ place(0, 8, mDescription, 6);
+ place(0, 9, mManualEntryButton);
+ place(1, 9, mDeleteButton);
+ place(2, 9, mLoadButton);
+ place(4, 9, mQuitButton);
+ place(5, 9, mConnectButton);
+
+ // Make sure the list has enough height
+ getLayout().setRowHeight(3, 80);
+
+/*
+ reflowLayout(400, 300);
+ setDefaultSize(400, 300, ImageRect::CENTER);
+*/
+ // Do this manually instead of calling reflowLayout so we can enforce a
+ // minimum width.
+ int width = 0, height = 0;
+ getLayout().reflow(width, height);
+ if (width < 400)
+ {
+ width = 400;
+ getLayout().reflow(width, height);
+ }
+
+ setContentSize(width, height);
+
+ setMinWidth(getWidth());
+ setMinHeight(getHeight());
+ setDefaultSize(getWidth(), getHeight(), ImageRect::CENTER);
+
+ setResizable(true);
+ addKeyListener(this);
+
+ loadWindowState();
+
+ setFieldsReadOnly(true);
+ mServersList->setSelected(0); // Do this after for the Delete button
+ setVisible(true);
+
+ if (mServerNameField->getText().empty())
+ {
+ mServerNameField->requestFocus();
+ }
+ else
+ {
+ if (mPortField->getText().empty())
+ mPortField->requestFocus();
+ else
+ mConnectButton->requestFocus();
+ }
+
+ loadServers(false);
+
+ if (mServers.size() == 0)
+ downloadServerList();
+}
+
+ServerDialog::~ServerDialog()
+{
+ if (mDownload)
+ {
+ mDownload->cancel();
+ delete mDownload;
+ mDownload = 0;
+ }
+ delete mServersListModel;
+ mServersListModel = 0;
+ delete mTypeListModel;
+ mTypeListModel = 0;
+}
+
+void ServerDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ // Give focus back to the server dialog.
+ mServerNameField->requestFocus();
+ }
+ else if (event.getId() == "connect")
+ {
+ // Check login
+ if (mServerNameField->getText().empty()
+ || mPortField->getText().empty())
+ {
+ OkDialog *dlg = new OkDialog(_("Error"),
+ _("Please type both the address and the port of a server."));
+ dlg->addActionListener(this);
+ }
+ else
+ {
+ if (mDownload)
+ mDownload->cancel();
+
+ mQuitButton->setEnabled(false);
+ mConnectButton->setEnabled(false);
+ mLoadButton->setEnabled(false);
+
+ mServerInfo->hostname = mServerNameField->getText();
+ mServerInfo->port = static_cast<short>(
+ atoi(mPortField->getText().c_str()));
+
+ switch (mTypeField->getSelected())
+ {
+ case 0:
+ mServerInfo->type = ServerInfo::TMWATHENA;
+ break;
+ case 1:
+ mServerInfo->type = ServerInfo::MANASERV;
+ break;
+ default:
+ mServerInfo->type = ServerInfo::UNKNOWN;
+ }
+
+ // Save the selected server
+ mServerInfo->save = true;
+
+ if (chatLogger)
+ chatLogger->setServerName(mServerInfo->hostname);
+
+ saveCustomServers(*mServerInfo);
+
+ if (!LoginDialog::savedPasswordKey.empty())
+ {
+ if (mServerInfo->hostname != LoginDialog::savedPasswordKey)
+ LoginDialog::savedPassword = "";
+ }
+
+ Client::setState(STATE_CONNECT_SERVER);
+ }
+ }
+ else if (event.getId() == "quit")
+ {
+ if (mDownload)
+ mDownload->cancel();
+ Client::setState(STATE_FORCE_QUIT);
+ }
+ else if (event.getId() == "load")
+ {
+ downloadServerList();
+ }
+ else if (event.getId() == "addEntry")
+ {
+ setFieldsReadOnly(false);
+ }
+ else if (event.getId() == "remove")
+ {
+ int index = mServersList->getSelected();
+ mServersList->setSelected(0);
+ mServers.erase(mServers.begin() + index);
+
+ saveCustomServers();
+ }
+}
+
+void ServerDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ESCAPE)
+ Client::setState(STATE_EXIT);
+ else if (key.getValue() == Key::ENTER)
+ action(gcn::ActionEvent(NULL, mConnectButton->getActionEventId()));
+}
+
+void ServerDialog::valueChanged(const gcn::SelectionEvent &)
+{
+ const int index = mServersList->getSelected();
+ if (index == -1)
+ {
+ mDeleteButton->setEnabled(false);
+ return;
+ }
+
+ // Update the server and post fields according to the new selection
+ const ServerInfo &myServer = mServersListModel->getServer(index);
+ mDescription->setCaption(myServer.description);
+ mServerNameField->setText(myServer.hostname);
+ mPortField->setText(toString(myServer.port));
+ switch (myServer.type)
+ {
+ case ServerInfo::TMWATHENA:
+ case ServerInfo::UNKNOWN:
+ default:
+ mTypeField->setSelected(0);
+ break;
+ case ServerInfo::MANASERV:
+ mTypeField->setSelected(1);
+ break;
+ }
+ setFieldsReadOnly(true);
+
+ mDeleteButton->setEnabled(myServer.save);
+}
+
+void ServerDialog::mouseClicked(gcn::MouseEvent &mouseEvent)
+{
+ if (mouseEvent.getClickCount() == 2 &&
+ mouseEvent.getSource() == mServersList)
+ {
+ action(gcn::ActionEvent(mConnectButton,
+ mConnectButton->getActionEventId()));
+ }
+}
+
+void ServerDialog::logic()
+{
+ {
+ MutexLocker lock(&mMutex);
+ if (mDownloadStatus == DOWNLOADING_COMPLETE)
+ {
+ mDownloadStatus = DOWNLOADING_OVER;
+
+ mDescription->setCaption(std::string());
+ }
+ else if (mDownloadStatus == DOWNLOADING_IN_PROGRESS)
+ {
+ mDescription->setCaption(strprintf(_("Downloading server list..."
+ "%2.2f%%"),
+ mDownloadProgress * 100));
+ }
+ else if (mDownloadStatus == DOWNLOADING_IDLE)
+ {
+ mDescription->setCaption(_("Waiting for server..."));
+ }
+ else if (mDownloadStatus == DOWNLOADING_PREPARING)
+ {
+ mDescription->setCaption(_("Preparing download"));
+ }
+ else if (mDownloadStatus == DOWNLOADING_ERROR)
+ {
+ mDescription->setCaption(_("Error retreiving server list!"));
+ }
+ }
+
+ Window::logic();
+}
+
+void ServerDialog::setFieldsReadOnly(bool readOnly)
+{
+ if (!readOnly)
+ {
+ mDescription->setCaption(std::string());
+ mServersList->setSelected(-1);
+
+ mServerNameField->setText(std::string());
+ mPortField->setText(std::string("6901"));
+
+ mServerNameField->requestFocus();
+ }
+
+ mManualEntryButton->setEnabled(readOnly);
+ mDeleteButton->setEnabled(false);
+ mLoadButton->setEnabled(readOnly);
+ mDescription->setVisible(readOnly);
+
+ mServerNameField->setEnabled(!readOnly);
+ mPortField->setEnabled(!readOnly);
+ mTypeField->setEnabled(!readOnly);
+}
+
+void ServerDialog::downloadServerList()
+{
+ // Try to load the configuration value for the onlineServerList
+ std::string listFile = branding.getStringValue("onlineServerList");
+
+ if (listFile.empty())
+ listFile = config.getStringValue("onlineServerList");
+
+ // Fall back to manasource.org when neither branding nor config set it
+ if (listFile.empty())
+ listFile = "http://manasource.org/serverlist.xml";
+
+ mDownload = new Net::Download(this, listFile, &downloadUpdate);
+ mDownload->setFile(mDir + "/serverlist.xml");
+ mDownload->start();
+}
+
+void ServerDialog::loadServers(bool addNew)
+{
+ XML::Document doc(mDir + "/serverlist.xml", false);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "serverlist"))
+ {
+ logger->log1("Error loading server list!");
+ return;
+ }
+
+ int version = XML::getProperty(rootNode, "version", 0);
+ if (version != 1)
+ {
+ logger->log("Error: unsupported online server list version: %d",
+ version);
+ return;
+ }
+
+ for_each_xml_child_node(serverNode, rootNode)
+ {
+ if (!xmlStrEqual(serverNode->name, BAD_CAST "server"))
+ continue;
+
+ ServerInfo server;
+
+ std::string type = XML::getProperty(serverNode, "type", "unknown");
+
+ server.type = ServerInfo::parseType(type);
+
+ // Ignore unknown server types
+ if (server.type == ServerInfo::UNKNOWN)
+ {
+ logger->log("Ignoring server entry with unknown type: %s",
+ type.c_str());
+ continue;
+ }
+
+ server.name = XML::getProperty(serverNode, "name", std::string());
+
+ std::string version = XML::getProperty(serverNode, "minimumVersion",
+ std::string());
+
+ bool meetsMinimumVersion = (compareStrI(version, PACKAGE_VERSION)
+ <= 0);
+
+ // For display in the list
+ if (meetsMinimumVersion)
+ version.clear();
+ else if (version.empty())
+ version = _("requires a newer version");
+ else
+ version = strprintf(_("requires v%s"), version.c_str());
+
+ for_each_xml_child_node(subNode, serverNode)
+ {
+ if (xmlStrEqual(subNode->name, BAD_CAST "connection"))
+ {
+ server.hostname = XML::getProperty(subNode, "hostname", "");
+ server.port = static_cast<short unsigned>(
+ XML::getProperty(subNode, "port", 0));
+
+ if (server.port == 0)
+ {
+ // If no port is given, use the default for the given type
+ server.port = defaultPortForServerType(server.type);
+ }
+ }
+ else if (xmlStrEqual(subNode->name, BAD_CAST "description"))
+ {
+ server.description =
+ (const char*)subNode->xmlChildrenNode->content;
+ }
+ }
+
+ server.version.first = gui->getFont()->getWidth(version);
+ server.version.second = version;
+
+ MutexLocker lock(&mMutex);
+ // Add the server to the local list if it's not already present
+ bool found = false;
+ for (unsigned int i = 0; i < mServers.size(); i++)
+ {
+ if (mServers[i] == server)
+ {
+ // Use the name listed in the server list
+ mServers[i].name = server.name;
+ mServers[i].version = server.version;
+ mServersListModel->setVersionString(i, version);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found && addNew)
+ mServers.push_back(server);
+ }
+}
+
+void ServerDialog::loadCustomServers()
+{
+ for (int i = 0; i < MAX_SERVERLIST; ++i)
+ {
+ const std::string index = toString(i);
+ const std::string nameKey = "MostUsedServerName" + index;
+ const std::string typeKey = "MostUsedServerType" + index;
+ const std::string portKey = "MostUsedServerPort" + index;
+
+ ServerInfo server;
+ server.hostname = config.getValue(nameKey, "");
+ server.type = ServerInfo::parseType(config.getValue(typeKey, ""));
+
+ const int defaultPort = defaultPortForServerType(server.type);
+ server.port = static_cast<unsigned short>(
+ config.getValue(portKey, defaultPort));
+
+ // Stop on the first invalid server
+ if (!server.isValid())
+ break;
+
+ server.save = true;
+ mServers.push_back(server);
+ }
+}
+
+void ServerDialog::saveCustomServers(const ServerInfo &currentServer)
+{
+ // Make sure the current server is mentioned first
+ if (currentServer.isValid())
+ {
+ ServerInfos::iterator i, i_end = mServers.end();
+ for (i = mServers.begin(); i != i_end; ++i)
+ {
+ if (*i == currentServer)
+ {
+ mServers.erase(i);
+ break;
+ }
+ }
+ mServers.insert(mServers.begin(), currentServer);
+ }
+
+ int savedServerCount = 0;
+
+ for (unsigned i = 0;
+ i < mServers.size() && savedServerCount < MAX_SERVERLIST; ++i)
+ {
+ const ServerInfo &server = mServers.at(i);
+
+ // Only save servers that were loaded from settings
+ if (!(server.save && server.isValid()))
+ continue;
+
+ const std::string index = toString(savedServerCount);
+ const std::string nameKey = "MostUsedServerName" + index;
+ const std::string typeKey = "MostUsedServerType" + index;
+ const std::string portKey = "MostUsedServerPort" + index;
+
+ config.setValue(nameKey, toString(server.hostname));
+ config.setValue(typeKey, serverTypeToString(server.type));
+ config.setValue(portKey, toString(server.port));
+ ++savedServerCount;
+ }
+
+ // Insert an invalid entry at the end to make the loading stop there
+ if (savedServerCount < MAX_SERVERLIST)
+ config.setValue("MostUsedServerName" + toString(savedServerCount), "");
+}
+
+int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status,
+ size_t total, size_t remaining)
+{
+ if (status == DOWNLOAD_STATUS_CANCELLED)
+ return -1;
+
+ ServerDialog *sd = reinterpret_cast<ServerDialog*>(ptr);
+ bool finished = false;
+
+ if (!sd->mDownload)
+ return -1;
+
+ if (status == DOWNLOAD_STATUS_COMPLETE)
+ {
+ finished = true;
+ }
+ else if (status < 0)
+ {
+ logger->log("Error retreiving server list: %s\n",
+ sd->mDownload->getError());
+ sd->mDownloadStatus = DOWNLOADING_ERROR;
+ }
+ else
+ {
+ float progress = static_cast<float>(remaining);
+ if (total)
+ progress /= static_cast<float>(total);
+
+ if (progress != progress)
+ {
+ progress = 0.0f; // check for NaN
+ }
+ else if (progress < 0.0f)
+ {
+ progress = 0.0f; // no idea how this could ever happen,
+ // but why not check for it anyway.
+ }
+ else if (progress > 1.0f)
+ {
+ progress = 1.0f;
+ }
+
+ MutexLocker lock(&sd->mMutex);
+ sd->mDownloadStatus = DOWNLOADING_IN_PROGRESS;
+ sd->mDownloadProgress = progress;
+ }
+
+ if (finished)
+ {
+ sd->loadServers();
+
+ MutexLocker lock(&sd->mMutex);
+ sd->mDownloadStatus = DOWNLOADING_COMPLETE;
+ }
+
+ return 0;
+}
diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h
new file mode 100644
index 000000000..b9a67e246
--- /dev/null
+++ b/src/gui/serverdialog.h
@@ -0,0 +1,204 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SERVERDIALOG_H
+#define SERVERDIALOG_H
+
+#include "gui/widgets/window.h"
+
+#include "net/download.h"
+#include "net/serverinfo.h"
+
+#include "utils/mutex.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/listmodel.hpp>
+#include <guichan/mouselistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#include <string>
+#include <vector>
+
+class Button;
+class Label;
+class ListBox;
+class ServerDialog;
+class TextField;
+class DropDown;
+
+/**
+ * Server and Port List Model
+ */
+class ServersListModel : public gcn::ListModel
+{
+ public:
+ typedef std::pair<int, std::string> VersionString;
+
+ ServersListModel(ServerInfos *servers, ServerDialog *parent);
+
+ /**
+ * Used to get number of line in the list
+ */
+ int getNumberOfElements();
+
+ /**
+ * Used to get an element from the list
+ */
+ std::string getElementAt(int elementIndex);
+
+ /**
+ * Used to get the corresponding Server struct
+ */
+ const ServerInfo &getServer(int elementIndex) const
+ { return mServers->at(elementIndex); }
+
+ void setVersionString(int index, const std::string &version);
+
+ private:
+ typedef std::vector<VersionString> VersionStrings;
+
+ ServerInfos *mServers;
+ VersionStrings mVersionStrings;
+ ServerDialog *mParent;
+};
+
+/**
+ * Server Type List Model
+ */
+class TypeListModel : public gcn::ListModel
+{
+ public:
+ TypeListModel() {}
+
+ /**
+ * Used to get number of line in the list
+ */
+ int getNumberOfElements()
+ { return 2; }
+
+ /**
+ * Used to get an element from the list
+ */
+ std::string getElementAt(int elementIndex);
+};
+
+
+/**
+ * The server choice dialog.
+ *
+ * \ingroup Interface
+ */
+class ServerDialog : public Window,
+ public gcn::ActionListener,
+ public gcn::KeyListener,
+ public gcn::SelectionListener
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ ServerDialog(ServerInfo *serverInfo, const std::string &dir);
+
+ /**
+ * Destructor
+ */
+ ~ServerDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ /**
+ * Called when the selected value changed in the servers list box.
+ */
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ void mouseClicked(gcn::MouseEvent &mouseEvent);
+
+ void logic();
+
+ protected:
+ friend class ServersListModel;
+ MutexLocker lock()
+ { return MutexLocker(&mMutex); }
+
+ private:
+ /**
+ * Called to load a list of available server from an online xml file.
+ */
+ void downloadServerList();
+ void loadServers(bool addNew = true);
+
+ void loadCustomServers();
+ void saveCustomServers(const ServerInfo &currentServer = ServerInfo());
+
+ static int downloadUpdate(void *ptr, DownloadStatus status,
+ size_t total, size_t remaining);
+
+ void setFieldsReadOnly(bool readOnly);
+
+ TextField *mServerNameField;
+ TextField *mPortField;
+ Label *mDescription;
+ Button *mQuitButton;
+ Button *mConnectButton;
+ Button *mManualEntryButton;
+ Button *mDeleteButton;
+ Button *mLoadButton;
+
+ ListBox *mServersList;
+ ServersListModel *mServersListModel;
+
+ DropDown *mTypeField;
+ TypeListModel *mTypeListModel;
+
+ const std::string &mDir;
+
+ enum ServerDialogDownloadStatus
+ {
+ DOWNLOADING_UNKNOWN = 0,
+ DOWNLOADING_ERROR,
+ DOWNLOADING_PREPARING,
+ DOWNLOADING_IDLE,
+ DOWNLOADING_IN_PROGRESS,
+ DOWNLOADING_COMPLETE,
+ DOWNLOADING_OVER
+ };
+
+ /** Status of the current download. */
+ ServerDialogDownloadStatus mDownloadStatus;
+
+ Net::Download *mDownload;
+
+ Mutex mMutex;
+ float mDownloadProgress;
+
+ ServerInfos mServers;
+ ServerInfo *mServerInfo;
+};
+
+#endif
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
new file mode 100644
index 000000000..8206b0e7e
--- /dev/null
+++ b/src/gui/setup.cpp
@@ -0,0 +1,178 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "setup.h"
+
+#include "configuration.h"
+#include "main.h"
+
+#include "gui/setup_audio.h"
+#include "gui/setup_colors.h"
+#include "gui/setup_joystick.h"
+#include "gui/setup_other.h"
+#include "gui/setup_theme.h"
+#include "gui/setup_keyboard.h"
+#include "gui/setup_players.h"
+#include "gui/setup_video.h"
+#include "gui/setup_chat.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/tabbedarea.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+
+extern Window *statusWindow;
+
+Setup::Setup():
+ Window(_("Setup"))
+{
+ setCloseButton(true);
+ setResizable(true);
+
+ int width = 620;
+ int height = 450;
+
+ if (config.getIntValue("screenwidth") >= 730)
+ width += 100;
+
+ setContentSize(width, height);
+ //setMaxHeight(height);
+
+ static const char *buttonNames[] =
+ {
+ N_("Apply"),
+ N_("Cancel"),
+ N_("Store"),
+ N_("Reset Windows"),
+ 0
+ };
+ int x = width;
+ for (const char **curBtn = buttonNames; *curBtn; ++curBtn)
+ {
+ Button *btn = new Button(gettext(*curBtn), *curBtn, this);
+ x -= btn->getWidth() + 5;
+ btn->setPosition(x, height - btn->getHeight() - 5);
+ add(btn);
+
+ // Store this button, as it needs to be enabled/disabled
+ if (!strcmp(*curBtn, "Reset Windows"))
+ mResetWindows = btn;
+ }
+
+ mPanel = new TabbedArea;
+ mPanel->setDimension(gcn::Rectangle(5, 5, width - 10, height - 40));
+
+ mTabs.push_back(new Setup_Video);
+ mTabs.push_back(new Setup_Audio);
+ mTabs.push_back(new Setup_Joystick);
+ mTabs.push_back(new Setup_Keyboard);
+ mTabs.push_back(new Setup_Colors);
+ mTabs.push_back(new Setup_Chat);
+ mTabs.push_back(new Setup_Players);
+ mTabs.push_back(new Setup_Theme);
+ mTabs.push_back(new Setup_Other);
+
+ for (std::list<SetupTab*>::iterator i = mTabs.begin(), i_end = mTabs.end();
+ i != i_end; ++i)
+ {
+ SetupTab *tab = *i;
+ mPanel->addTab(tab->getName(), tab);
+ }
+
+ add(mPanel);
+
+ Label *version = new Label(FULL_VERSION);
+// version->setPosition(9, height - version->getHeight() - 9);
+ if (mResetWindows)
+ {
+ version->setPosition(9,
+ height - version->getHeight() - mResetWindows->getHeight() - 9);
+ }
+ else
+ {
+ version->setPosition(9, height - version->getHeight() - 30);
+ }
+ add(version);
+
+ center();
+
+ setInGame(false);
+}
+
+Setup::~Setup()
+{
+ delete_all(mTabs);
+}
+
+void Setup::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "Apply")
+ {
+ setVisible(false);
+ for_each(mTabs.begin(), mTabs.end(), std::mem_fun(&SetupTab::apply));
+ }
+ else if (event.getId() == "Cancel")
+ {
+ setVisible(false);
+ for_each(mTabs.begin(), mTabs.end(), std::mem_fun(&SetupTab::cancel));
+ }
+ else if (event.getId() == "Store")
+ {
+ config.write();
+ serverConfig.write();
+ }
+ else if (event.getId() == "Reset Windows")
+ {
+ // Bail out if this action happens to be activated before the windows
+ // are created (though it should be disabled then)
+ if (!statusWindow)
+ return;
+
+ for (std::list<Window*>::iterator it = mWindowsToReset.begin();
+ it != mWindowsToReset.end(); it++)
+ {
+ (*it)->resetToDefaultSize();
+ }
+ }
+}
+
+void Setup::setInGame(bool inGame)
+{
+ mResetWindows->setEnabled(inGame);
+}
+
+void Setup::externalUpdate()
+{
+ for (std::list<SetupTab*>::iterator it = mTabs.begin();
+ it != mTabs.end(); it++)
+ {
+ (*it)->externalUpdated();
+ }
+}
+
+void Setup::registerWindowForReset(Window *window)
+{
+ mWindowsToReset.push_back(window);
+}
+
+Setup *setupWindow;
diff --git a/src/gui/setup.h b/src/gui/setup.h
new file mode 100644
index 000000000..1f10a2a0d
--- /dev/null
+++ b/src/gui/setup.h
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SETUP_H
+#define SETUP_H
+
+#include "gui/widgets/tabbedarea.h"
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <list>
+
+class SetupTab;
+
+/**
+ * The setup dialog. Displays several tabs for configuring different aspects
+ * of the game.
+ *
+ * @see Setup_Audio
+ * @see Setup_Colors
+ * @see Setup_Joystick
+ * @see Setup_Keyboard
+ * @see Setup_Players
+ * @see Setup_Video
+ *
+ * \ingroup GUI
+ */
+class Setup : public Window, public gcn::ActionListener
+{
+ public:
+ Setup();
+ ~Setup();
+
+ /**
+ * Event handling method.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Enables the reset button when in game.
+ */
+ void setInGame(bool inGame);
+
+ void externalUpdate();
+
+ void registerWindowForReset(Window *window);
+
+ void clearWindowsForReset()
+ { mWindowsToReset.clear(); }
+
+ private:
+ std::list<SetupTab*> mTabs;
+ std::list<Window*> mWindowsToReset;
+ gcn::Button *mResetWindows;
+ TabbedArea *mPanel;
+};
+
+extern Setup* setupWindow;
+
+#endif
diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp
new file mode 100644
index 000000000..66a7a4e88
--- /dev/null
+++ b/src/gui/setup_audio.cpp
@@ -0,0 +1,179 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/setup_audio.h"
+
+#include "configuration.h"
+#include "log.h"
+#include "sound.h"
+
+#include "gui/okdialog.h"
+
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/slider.h"
+
+#include "utils/gettext.h"
+
+Setup_Audio::Setup_Audio():
+ mMusicVolume(config.getIntValue("musicVolume")),
+ mSfxVolume(config.getIntValue("sfxVolume")),
+ mAudioEnabled(config.getBoolValue("sound")),
+ mGameSoundEnabled(config.getBoolValue("playBattleSound")),
+ mGuiSoundEnabled(config.getBoolValue("playGuiSound")),
+ mMusicEnabled(config.getBoolValue("playMusic")),
+ mMumbleEnabled(config.getBoolValue("enableMumble")),
+ mDownloadEnabled(config.getBoolValue("download-music")),
+ mAudioCheckBox(new CheckBox(_("Enable Audio"), mAudioEnabled)),
+ mGameSoundCheckBox(new CheckBox(_("Enable game sfx"), mGameSoundEnabled)),
+ mGuiSoundCheckBox(new CheckBox(_("Enable gui sfx"), mGuiSoundEnabled)),
+ mMusicCheckBox(new CheckBox(_("Enable music"), mMusicEnabled)),
+ mMumbleCheckBox(new CheckBox(_("Enable mumble voice chat"),
+ mMumbleEnabled)),
+ mDownloadMusicCheckBox(new CheckBox(_("Download music"),
+ mDownloadEnabled)),
+ mSfxSlider(new Slider(0, sound.getMaxVolume())),
+ mMusicSlider(new Slider(0, sound.getMaxVolume()))
+{
+ setName(_("Audio"));
+ setDimension(gcn::Rectangle(0, 0, 250, 200));
+
+ gcn::Label *sfxLabel = new Label(_("Sfx volume"));
+ gcn::Label *musicLabel = new Label(_("Music volume"));
+
+ mSfxSlider->setActionEventId("sfx");
+ mMusicSlider->setActionEventId("music");
+
+ mSfxSlider->addActionListener(this);
+ mMusicSlider->addActionListener(this);
+
+ mAudioCheckBox->setPosition(10, 10);
+
+ mSfxSlider->setValue(mSfxVolume);
+ mMusicSlider->setValue(mMusicVolume);
+
+ mSfxSlider->setWidth(90);
+ mMusicSlider->setWidth(90);
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mAudioCheckBox);
+ place(0, 1, mMusicCheckBox);
+ place(0, 2, mGameSoundCheckBox);
+ place(0, 3, mGuiSoundCheckBox);
+ place(0, 4, mSfxSlider);
+ place(1, 4, sfxLabel);
+ place(0, 5, mMusicSlider);
+ place(1, 5, musicLabel);
+ place(0, 6, mMumbleCheckBox);
+ place(0, 7, mDownloadMusicCheckBox);
+
+ setDimension(gcn::Rectangle(0, 0, 365, 280));
+}
+
+void Setup_Audio::apply()
+{
+ mAudioEnabled = mAudioCheckBox->isSelected();
+ mGameSoundEnabled = mGameSoundCheckBox->isSelected();
+ mGuiSoundEnabled = mGuiSoundCheckBox->isSelected();
+ mMusicEnabled = mMusicCheckBox->isSelected();
+ mMumbleEnabled = mMumbleCheckBox->isSelected();
+ mDownloadEnabled = mDownloadMusicCheckBox->isSelected();
+ mSfxVolume = config.getIntValue("sfxVolume");
+ mMusicVolume = config.getIntValue("musicVolume");
+
+ config.setValue("sound", mAudioEnabled);
+ config.setValue("playBattleSound", mGameSoundEnabled);
+ config.setValue("playGuiSound", mGuiSoundEnabled);
+ config.setValue("playMusic", mMusicEnabled);
+
+ config.setValue("enableMumble", mMumbleEnabled);
+
+ // Display a message if user has selected to download music,
+ // And if downloadmusic is not already enabled
+ if (mDownloadEnabled && !config.getBoolValue("download-music"))
+ {
+ new OkDialog(_("Notice"), _("You may have to restart your client "
+ "if you want to download new music"));
+ }
+ config.setValue("download-music", mDownloadEnabled);
+
+ if (mAudioEnabled)
+ {
+ try
+ {
+ sound.init();
+ }
+ catch (const char *err)
+ {
+ new OkDialog(_("Sound Engine"), err);
+ logger->log("Warning: %s", err);
+ }
+ }
+ else
+ {
+ sound.close();
+ }
+}
+
+void Setup_Audio::cancel()
+{
+ mAudioCheckBox->setSelected(mAudioEnabled);
+ mGameSoundCheckBox->setSelected(mGameSoundEnabled);
+ mGuiSoundCheckBox->setSelected(mGuiSoundEnabled);
+ mMusicCheckBox->setSelected(mMusicEnabled);
+ mMumbleCheckBox->setSelected(mMumbleEnabled);
+ mDownloadMusicCheckBox->setSelected(mDownloadEnabled);
+
+ sound.setSfxVolume(mSfxVolume);
+ mSfxSlider->setValue(mSfxVolume);
+
+ sound.setMusicVolume(mMusicVolume);
+ mMusicSlider->setValue(mMusicVolume);
+
+ config.setValue("sound", mAudioEnabled);
+ config.setValue("playBattleSound", mGameSoundEnabled);
+ config.setValue("playGuiSound", mGuiSoundEnabled);
+ config.setValue("playMusic", mMusicEnabled);
+ config.setValue("enableMumble", mMumbleEnabled);
+ config.setValue("download-music", mDownloadEnabled);
+ config.setValue("sfxVolume", mSfxVolume);
+ config.setValue("musicVolume", mMusicVolume);
+}
+
+void Setup_Audio::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "sfx")
+ {
+ config.setValueInt("sfxVolume",
+ static_cast<int>(mSfxSlider->getValue()));
+ sound.setSfxVolume(static_cast<int>(mSfxSlider->getValue()));
+ }
+ else if (event.getId() == "music")
+ {
+ config.setValueInt("musicVolume",
+ static_cast<int>(mMusicSlider->getValue()));
+ sound.setMusicVolume(static_cast<int>(mMusicSlider->getValue()));
+ }
+}
diff --git a/src/gui/setup_audio.h b/src/gui/setup_audio.h
new file mode 100644
index 000000000..c16c4fb23
--- /dev/null
+++ b/src/gui/setup_audio.h
@@ -0,0 +1,53 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_SETUP_AUDIO_H
+#define GUI_SETUP_AUDIO_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+
+class Setup_Audio : public SetupTab, public gcn::ActionListener
+{
+ public:
+ Setup_Audio();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ int mMusicVolume, mSfxVolume;
+ bool mAudioEnabled, mGameSoundEnabled, mGuiSoundEnabled;
+ bool mMusicEnabled, mMumbleEnabled;
+ bool mDownloadEnabled;
+
+ gcn::CheckBox *mAudioCheckBox, *mGameSoundCheckBox, *mGuiSoundCheckBox;
+ gcn::CheckBox *mMusicCheckBox, *mMumbleCheckBox;
+ gcn::CheckBox *mDownloadMusicCheckBox;
+ gcn::Slider *mSfxSlider, *mMusicSlider;
+};
+
+#endif
diff --git a/src/gui/setup_chat.cpp b/src/gui/setup_chat.cpp
new file mode 100644
index 000000000..1dba2ed85
--- /dev/null
+++ b/src/gui/setup_chat.cpp
@@ -0,0 +1,306 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/setup_chat.h"
+#include "gui/editdialog.h"
+#include "gui/chat.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/inttextfield.h"
+#include "gui/widgets/chattab.h"
+
+#include "configuration.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "utils/gettext.h"
+
+#define ACTION_REMOVE_COLORS "remove colors"
+#define ACTION_MAGIC_IN_DEBUG "magic in debug"
+#define ACTION_ALLOW_COMMANDS_IN_CHATTABS "allow commands"
+#define ACTION_SERVER_MSG_IN_DEBUG "server in debug"
+#define ACTION_SHOW_CHAT_COLORS "show chat colors"
+#define ACTION_MAX_CHAR_LIMIT "char limit"
+#define ACTION_EDIT_CHAR_LIMIT "edit char limit"
+#define ACTION_EDIT_CHAR_OK "edit char ok"
+#define ACTION_MAX_LINES_LIMIT "lines limit"
+#define ACTION_EDIT_LINES_LIMIT "edit lines limit"
+#define ACTION_EDIT_LINES_OK "edit lines ok"
+#define ACTION_CHAT_LOGGER "chat logger"
+#define ACTION_TRADE_TAB "trade tab"
+#define ACTION_HIDE_SHOP_MESSAGES "hide shop messages"
+#define ACTION_SHOW_CHAT_HISTORY "show chat history"
+#define ACTION_ENABLE_BATTLE_TAB "show battle tab"
+#define ACTION_SHOW_BATTLE_EVENTS "show battle events"
+
+Setup_Chat::Setup_Chat()
+{
+ setName(_("Chat"));
+
+ mRemoveColors = config.getBoolValue("removeColors");
+ mRemoveColorsCheckBox = new CheckBox(
+ _("Remove colors from received chat messages"),
+ mRemoveColors, this, ACTION_REMOVE_COLORS);
+
+ mMagicInDebug = config.getBoolValue("showMagicInDebug");
+ mMagicInDebugCheckBox = new CheckBox(_("Log magic messages in debug tab"),
+ mMagicInDebug, this, ACTION_MAGIC_IN_DEBUG);
+
+ mAllowCommandsInChatTabs = config.getBoolValue(
+ "allowCommandsInChatTabs");
+
+ mAllowCommandsInChatTabsCheckBox = new CheckBox(
+ _("Allow magic and GM commands in all chat tabs"),
+ mAllowCommandsInChatTabs, this, ACTION_ALLOW_COMMANDS_IN_CHATTABS);
+
+ mServerMsgInDebug = config.getBoolValue("serverMsgInDebug");
+ mServerMsgInDebugCheckBox = new CheckBox(
+ _("Show server messages in debug tab"),
+ mServerMsgInDebug, this, ACTION_SERVER_MSG_IN_DEBUG);
+
+ mEnableChatLogger = config.getBoolValue("enableChatLog");
+ mEnableChatLoggerCheckBox = new CheckBox(_("Enable chat Log"),
+ mEnableChatLogger, this, ACTION_CHAT_LOGGER);
+
+ mEnableTradeTab = config.getBoolValue("enableTradeTab");
+ mEnableTradeTabCheckBox = new CheckBox(_("Enable trade tab"),
+ mEnableTradeTab, this, ACTION_TRADE_TAB);
+
+ mHideShopMessages = config.getBoolValue("hideShopMessages");
+ mHideShopMessagesCheckBox = new CheckBox(_("Hide shop messages"),
+ mHideShopMessages, this, ACTION_HIDE_SHOP_MESSAGES);
+
+ mShowChatHistory = config.getBoolValue("showChatHistory");
+ mShowChatHistoryCheckBox = new CheckBox(_("Show chat history"),
+ mShowChatHistory, this, ACTION_SHOW_CHAT_HISTORY);
+
+ mEnableBattleTab = config.getBoolValue("enableBattleTab");
+ mEnableBattleTabCheckBox = new CheckBox(_("Enable battle tab"),
+ mEnableBattleTab, this, ACTION_ENABLE_BATTLE_TAB);
+
+ mShowBattleEvents = config.getBoolValue("showBattleEvents");
+ mShowBattleEventsCheckBox = new CheckBox(_("Show battle events"),
+ mShowBattleEvents, this, ACTION_SHOW_BATTLE_EVENTS);
+
+ mShowChatColors = config.getBoolValue("showChatColorsList");
+ mShowChatColorsCheckBox = new CheckBox(_("Show chat colors list"),
+ mShowChatColors, this, ACTION_SHOW_CHAT_COLORS);
+
+ mMaxCharButton = new Button(_("Edit"), ACTION_EDIT_CHAR_LIMIT, this);
+ int maxCharLimit = config.getIntValue("chatMaxCharLimit");
+ mMaxChar = (maxCharLimit != 0);
+ mMaxCharCheckBox = new CheckBox(_("Limit max chars in chat line"),
+ mMaxChar, this, ACTION_MAX_CHAR_LIMIT);
+
+ mMaxCharField = new IntTextField(maxCharLimit, 0, 500, mMaxChar, 20);
+
+ mMaxLinesButton = new Button(_("Edit"), ACTION_EDIT_LINES_LIMIT, this);
+ int maxLinesLimit = config.getIntValue("chatMaxLinesLimit");
+ mMaxLines = (maxLinesLimit != 0);
+
+ mMaxLinesCheckBox = new CheckBox(_("Limit max lines in chat"),
+ mMaxLines,
+ this, ACTION_MAX_LINES_LIMIT);
+
+ mMaxLinesField = new IntTextField(maxLinesLimit, 0, 500, mMaxLines, 20);
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mRemoveColorsCheckBox, 10);
+ place(0, 1, mMagicInDebugCheckBox, 10);
+ place(0, 2, mAllowCommandsInChatTabsCheckBox, 10);
+ place(0, 3, mServerMsgInDebugCheckBox, 10);
+ place(0, 4, mShowChatColorsCheckBox, 10);
+ place(0, 5, mMaxCharCheckBox, 6);
+ place(6, 5, mMaxCharField, 2);
+ place(8, 5, mMaxCharButton, 2);
+ place(0, 6, mEnableChatLoggerCheckBox, 10);
+ place(0, 7, mMaxLinesCheckBox, 6);
+ place(6, 7, mMaxLinesField, 2);
+ place(8, 7, mMaxLinesButton, 2);
+ place(0, 8, mEnableTradeTabCheckBox, 10);
+ place(0, 9, mHideShopMessagesCheckBox, 10);
+ place(0, 10, mShowChatHistoryCheckBox, 10);
+ place(0, 11, mEnableBattleTabCheckBox, 10);
+ place(0, 12, mShowBattleEventsCheckBox, 10);
+
+ place.getCell().matchColWidth(0, 0);
+ place = h.getPlacer(0, 1);
+
+ setDimension(gcn::Rectangle(0, 0, 500, 500));
+}
+
+void Setup_Chat::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == ACTION_REMOVE_COLORS)
+ {
+ mRemoveColors = mRemoveColorsCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_MAGIC_IN_DEBUG)
+ {
+ mMagicInDebug = mMagicInDebugCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_ALLOW_COMMANDS_IN_CHATTABS)
+ {
+ mAllowCommandsInChatTabs
+ = mAllowCommandsInChatTabsCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SERVER_MSG_IN_DEBUG)
+ {
+ mServerMsgInDebug = mServerMsgInDebugCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SHOW_CHAT_COLORS)
+ {
+ mShowChatColors = mShowChatColorsCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_MAX_CHAR_LIMIT)
+ {
+ mMaxChar = mMaxCharCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_EDIT_CHAR_LIMIT)
+ {
+ mEditDialog = new EditDialog("Limit max chars in chat line",
+ toString(mMaxCharField->getValue()),
+ ACTION_EDIT_CHAR_OK);
+ mEditDialog->addActionListener(this);
+ }
+ else if (event.getId() == ACTION_EDIT_CHAR_OK)
+ {
+ mMaxCharField->setValue(atoi(mEditDialog->getMsg().c_str()));
+ }
+ else if (event.getId() == ACTION_MAX_LINES_LIMIT)
+ {
+ mMaxLines = mMaxLinesCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_EDIT_LINES_LIMIT)
+ {
+ mEditDialog = new EditDialog("Limit max lines in chat",
+ toString(mMaxLinesField->getValue()),
+ ACTION_EDIT_LINES_OK);
+ mEditDialog->addActionListener(this);
+ }
+ else if (event.getId() == ACTION_EDIT_LINES_OK)
+ {
+ mMaxLinesField->setValue(atoi(mEditDialog->getMsg().c_str()));
+ }
+ else if (event.getId() == ACTION_CHAT_LOGGER)
+ {
+ mEnableChatLogger = mEnableChatLoggerCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_TRADE_TAB)
+ {
+ mEnableTradeTab = mEnableTradeTabCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_HIDE_SHOP_MESSAGES)
+ {
+ mHideShopMessages = mHideShopMessagesCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SHOW_CHAT_HISTORY)
+ {
+ mShowChatHistory = mShowChatHistoryCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_ENABLE_BATTLE_TAB)
+ {
+ mEnableBattleTab = mEnableBattleTabCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SHOW_BATTLE_EVENTS)
+ {
+ mShowBattleEvents = mShowBattleEventsCheckBox->isSelected();
+ }
+}
+
+void Setup_Chat::cancel()
+{
+ mRemoveColors = config.getBoolValue("removeColors");
+ mRemoveColorsCheckBox->setSelected(mRemoveColors);
+
+ mMagicInDebug = config.getBoolValue("showMagicInDebug");
+ mMagicInDebugCheckBox->setSelected(mMagicInDebug);
+
+ mAllowCommandsInChatTabs
+ = config.getBoolValue("allowCommandsInChatTabs");
+ mAllowCommandsInChatTabsCheckBox->setSelected(mAllowCommandsInChatTabs);
+
+ mServerMsgInDebug = config.getBoolValue("serverMsgInDebug");
+ mServerMsgInDebugCheckBox->setSelected(mServerMsgInDebug);
+
+ mShowChatColors = config.getBoolValue("showChatColorsList");
+ mShowChatColorsCheckBox->setSelected(mShowChatColors);
+
+ int maxCharLimit = config.getIntValue("chatMaxCharLimit");
+ mMaxChar = (maxCharLimit != 0);
+ mMaxCharCheckBox->setSelected(mMaxChar);
+ mMaxCharField->setValue(maxCharLimit);
+ mMaxCharField->setEnabled(mMaxChar);
+
+ int maxLinesLimit = config.getIntValue("chatMaxLinesLimit");
+ mMaxLines = (maxLinesLimit != 0);
+ mMaxLinesCheckBox->setSelected(mMaxLines);
+ mMaxLinesField->setValue(maxLinesLimit);
+ mMaxLinesField->setEnabled(mMaxLines);
+
+ mEnableChatLogger = config.getBoolValue("enableChatLog");
+ mEnableChatLoggerCheckBox->setSelected(mEnableChatLogger);
+
+ mEnableTradeTab = config.getBoolValue("enableTradeTab");
+ mEnableTradeTabCheckBox->setSelected(mEnableTradeTab);
+
+ mHideShopMessages = config.getBoolValue("hideShopMessages");
+ mHideShopMessagesCheckBox->setSelected(mHideShopMessages);
+
+ mShowChatHistory = config.getBoolValue("showChatHistory");
+ mShowChatHistoryCheckBox->setSelected(mShowChatHistory);
+
+ mEnableBattleTab = config.getBoolValue("enableBattleTab");
+ mEnableBattleTabCheckBox->setSelected(mEnableBattleTab);
+
+ mShowBattleEvents = config.getBoolValue("showBattleEvents");
+ mShowBattleEventsCheckBox->setSelected(mShowBattleEvents);
+}
+
+void Setup_Chat::apply()
+{
+ config.setValue("removeColors", mRemoveColors);
+ config.setValue("showMagicInDebug", mMagicInDebug);
+ config.setValue("allowCommandsInChatTabs", mAllowCommandsInChatTabs);
+ config.setValue("serverMsgInDebug", mServerMsgInDebug);
+ config.setValue("showChatColorsList", mShowChatColors);
+ if (mMaxChar)
+ config.setValue("chatMaxCharLimit", mMaxCharField->getValue());
+ else
+ config.setValue("chatMaxCharLimit", 0);
+ if (mMaxLines)
+ config.setValue("chatMaxLinesLimit", mMaxLinesField->getValue());
+ else
+ config.setValue("chatMaxLinesLimit", 0);
+ config.setValue("enableChatLog", mEnableChatLogger);
+ config.setValue("enableTradeTab", mEnableTradeTab);
+ config.setValue("hideShopMessages", mHideShopMessages);
+ config.setValue("showChatHistory", mShowChatHistory);
+ config.setValue("enableBattleTab", mEnableBattleTab);
+ config.setValue("showBattleEvents", mShowBattleEvents);
+}
diff --git a/src/gui/setup_chat.h b/src/gui/setup_chat.h
new file mode 100644
index 000000000..30a59895a
--- /dev/null
+++ b/src/gui/setup_chat.h
@@ -0,0 +1,92 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_SETUP_CHAT_H
+#define GUI_SETUP_CHAT_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+
+class IntTextField;
+class EditDialog;
+
+class Setup_Chat : public SetupTab, public gcn::ActionListener
+{
+ public:
+ Setup_Chat();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::CheckBox *mRemoveColorsCheckBox;
+ bool mRemoveColors;
+
+ gcn::CheckBox *mMagicInDebugCheckBox;
+ bool mMagicInDebug;
+
+ gcn::CheckBox *mAllowCommandsInChatTabsCheckBox;
+ bool mAllowCommandsInChatTabs;
+
+ gcn::CheckBox *mServerMsgInDebugCheckBox;
+ bool mServerMsgInDebug;
+
+ gcn::CheckBox *mShowChatColorsCheckBox;
+ bool mShowChatColors;
+
+ gcn::CheckBox *mMaxCharCheckBox;
+ IntTextField *mMaxCharField;
+ gcn::Button *mMaxCharButton;
+ bool mMaxChar;
+
+ gcn::CheckBox *mMaxLinesCheckBox;
+ IntTextField *mMaxLinesField;
+ gcn::Button *mMaxLinesButton;
+ bool mMaxLines;
+
+ gcn::CheckBox *mEnableChatLoggerCheckBox;
+ bool mEnableChatLogger;
+
+ gcn::CheckBox *mEnableTradeTabCheckBox;
+ bool mEnableTradeTab;
+
+ gcn::CheckBox *mHideShopMessagesCheckBox;
+ bool mHideShopMessages;
+
+ gcn::CheckBox *mShowChatHistoryCheckBox;
+ bool mShowChatHistory;
+
+ gcn::CheckBox *mEnableBattleTabCheckBox;
+ bool mEnableBattleTab;
+
+ gcn::CheckBox *mShowBattleEventsCheckBox;
+ bool mShowBattleEvents;
+
+ EditDialog *mEditDialog;
+};
+
+#endif
diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp
new file mode 100644
index 000000000..76510a283
--- /dev/null
+++ b/src/gui/setup_colors.cpp
@@ -0,0 +1,443 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/setup_colors.h"
+
+#include "configuration.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+#include "gui/userpalette.h"
+
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/itemlinkhandler.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/slider.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/textpreview.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
+#include <cmath>
+
+const std::string Setup_Colors::rawmsg =
+ _("This is what the color looks like");
+
+Setup_Colors::Setup_Colors() :
+ mSelected(-1)
+{
+ setName(_("Colors"));
+
+ mColorBox = new ListBox(userPalette);
+ mColorBox->addSelectionListener(this);
+
+ mScroll = new ScrollArea(mColorBox);
+ mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mTextPreview = new TextPreview(rawmsg);
+
+ mPreview = new BrowserBox(BrowserBox::AUTO_WRAP);
+ mPreview->setOpaque(false);
+
+ // don't do anything with links
+ mPreview->setLinkHandler(NULL);
+
+ mPreviewBox = new ScrollArea(mPreview);
+ mPreviewBox->setHeight(20);
+ mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
+ gcn::ScrollArea::SHOW_NEVER);
+
+ mGradTypeLabel = new Label(_("Type:"));
+
+ mGradTypeSlider = new Slider(0, 3);
+ mGradTypeSlider->setWidth(180);
+ mGradTypeSlider->setActionEventId("slider_grad");
+ mGradTypeSlider->setValue(0);
+ mGradTypeSlider->addActionListener(this);
+ mGradTypeSlider->setEnabled(false);
+
+ mGradTypeText = new Label;
+
+ std::string longText = _("Static");
+
+ if (getFont()->getWidth(_("Pulse")) > getFont()->getWidth(longText))
+ longText = _("Pulse");
+ if (getFont()->getWidth(_("Rainbow")) > getFont()->getWidth(longText))
+ longText = _("Rainbow");
+ if (getFont()->getWidth(_("Spectrum")) > getFont()->getWidth(longText))
+ longText = _("Spectrum");
+
+ mGradTypeText->setCaption(longText);
+
+ mGradDelayLabel = new Label(_("Delay:"));
+
+ mGradDelayText = new TextField();
+ mGradDelayText->setWidth(40);
+ mGradDelayText->setRange(20, 100);
+ mGradDelayText->setNumeric(true);
+ mGradDelayText->setEnabled(false);
+
+ mGradDelaySlider = new Slider(20, 100);
+ mGradDelaySlider->setWidth(180);
+ mGradDelaySlider->setValue(mGradDelayText->getValue());
+ mGradDelaySlider->setActionEventId("slider_graddelay");
+ mGradDelaySlider->addActionListener(this);
+ mGradDelaySlider->setEnabled(false);
+
+ mRedLabel = new Label(_("Red:"));
+
+ mRedText = new TextField;
+ mRedText->setWidth(40);
+ mRedText->setRange(0, 255);
+ mRedText->setNumeric(true);
+ mRedText->setEnabled(false);
+
+ mRedSlider = new Slider(0, 255);
+ mRedSlider->setWidth(180);
+ mRedSlider->setValue(mRedText->getValue());
+ mRedSlider->setActionEventId("slider_red");
+ mRedSlider->addActionListener(this);
+ mRedSlider->setEnabled(false);
+
+ mGreenLabel = new Label(_("Green:"));
+
+ mGreenText = new TextField;
+ mGreenText->setWidth(40);
+ mGreenText->setRange(0, 255);
+ mGreenText->setNumeric(true);
+ mGreenText->setEnabled(false);
+
+ mGreenSlider = new Slider(0, 255);
+ mGreenSlider->setWidth(180);
+ mGreenSlider->setValue(mGreenText->getValue());
+ mGreenSlider->setActionEventId("slider_green");
+ mGreenSlider->addActionListener(this);
+ mGreenSlider->setEnabled(false);
+
+ mBlueLabel = new Label(_("Blue:"));
+
+ mBlueText = new TextField;
+ mBlueText->setWidth(40);
+ mBlueText->setRange(0, 255);
+ mBlueText->setNumeric(true);
+ mBlueText->setEnabled(false);
+
+ mBlueSlider = new Slider(0, 255);
+ mBlueSlider->setWidth(180);
+ mBlueSlider->setValue(mBlueText->getValue());
+ mBlueSlider->setActionEventId("slider_blue");
+ mBlueSlider->addActionListener(this);
+ mBlueSlider->setEnabled(false);
+
+ setOpaque(false);
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mScroll, 6, 6).setPadding(2);
+ place(0, 6, mPreviewBox, 6).setPadding(2);
+ place(0, 7, mGradTypeLabel, 3);
+ place(3, 7, mGradTypeSlider);
+ place(4, 7, mGradTypeText, 2).setPadding(1);
+ place(0, 8, mRedLabel, 3);
+ place(3, 8, mRedSlider);
+ place(5, 8, mRedText).setPadding(1);
+ place(0, 9, mGreenLabel, 3);
+ place(3, 9, mGreenSlider);
+ place(5, 9, mGreenText).setPadding(1);
+ place(0, 10, mBlueLabel, 3);
+ place(3, 10, mBlueSlider);
+ place(5, 10, mBlueText).setPadding(1);
+ place(0, 11, mGradDelayLabel, 3);
+ place(3, 11, mGradDelaySlider);
+ place(5, 11, mGradDelayText).setPadding(1);
+
+ mGradTypeText->setCaption("");
+
+ setDimension(gcn::Rectangle(0, 0, 365, 350));
+}
+
+Setup_Colors::~Setup_Colors()
+{
+ if (mPreviewBox && mPreviewBox->getContent() == mPreview)
+ {
+ delete mTextPreview;
+ mTextPreview = 0;
+ }
+ else
+ {
+ delete mPreview;
+ mPreview = 0;
+ }
+}
+
+void Setup_Colors::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "slider_grad")
+ {
+ updateGradType();
+ updateColor();
+ return;
+ }
+
+ if (event.getId() == "slider_graddelay")
+ {
+ mGradDelayText->setText(toString(
+ std::floor(mGradDelaySlider->getValue())));
+ updateColor();
+ return;
+ }
+
+ if (event.getId() == "slider_red")
+ {
+ mRedText->setText(toString(std::floor(mRedSlider->getValue())));
+ updateColor();
+ return;
+ }
+
+ if (event.getId() == "slider_green")
+ {
+ mGreenText->setText(toString(std::floor(mGreenSlider->getValue())));
+ updateColor();
+ return;
+ }
+
+ if (event.getId() == "slider_blue")
+ {
+ mBlueText->setText(toString(std::floor(mBlueSlider->getValue())));
+ updateColor();
+ return;
+ }
+}
+
+void Setup_Colors::valueChanged(const gcn::SelectionEvent &event _UNUSED_)
+{
+ if (!userPalette)
+ return;
+
+ mSelected = mColorBox->getSelected();
+ int type = userPalette->getColorTypeAt(mSelected);
+ const gcn::Color *col = &userPalette->getColor(type);
+ Palette::GradientType grad = userPalette->getGradientType(type);
+ const int delay = userPalette->getGradientDelay(type);
+
+ mPreview->clearRows();
+ mPreviewBox->setContent(mTextPreview);
+ mTextPreview->setFont(boldFont);
+ mTextPreview->setTextColor(col);
+ mTextPreview->setTextBGColor(NULL);
+ mTextPreview->setOpaque(false);
+ mTextPreview->setShadow(true);
+ mTextPreview->setOutline(true);
+ mTextPreview->useTextAlpha(false);
+
+ switch (type)
+ {
+ case UserPalette::COLLISION_HIGHLIGHT:
+ case UserPalette::PORTAL_HIGHLIGHT:
+ case UserPalette::HOME_PLACE:
+ case UserPalette::ROAD_POINT:
+ mTextPreview->setBGColor(col);
+ mTextPreview->setOpaque(true);
+ mTextPreview->setOutline(false);
+ mTextPreview->setShadow(false);
+ break;
+ case UserPalette::ATTACK_RANGE_BORDER:
+ case UserPalette::HOME_PLACE_BORDER:
+ mTextPreview->setFont(gui->getFont());
+ mTextPreview->setTextColor(col);
+ mTextPreview->setOutline(false);
+ mTextPreview->setShadow(false);
+ break;
+ case UserPalette::PARTICLE:
+ case UserPalette::EXP_INFO:
+ case UserPalette::PICKUP_INFO:
+ case UserPalette::HIT_PLAYER_MONSTER:
+ case UserPalette::HIT_MONSTER_PLAYER:
+ case UserPalette::HIT_CRITICAL:
+ case UserPalette::MISS:
+ case UserPalette::HIT_LOCAL_PLAYER_MONSTER:
+ case UserPalette::HIT_LOCAL_PLAYER_CRITICAL:
+ case UserPalette::HIT_LOCAL_PLAYER_MISS:
+ case UserPalette::ATTACK_RANGE:
+ case UserPalette::MONSTER_ATTACK_RANGE:
+ mTextPreview->setShadow(false);
+ default:
+ break;
+ }
+
+ switch (type)
+ {
+ case UserPalette::PORTAL_HIGHLIGHT:
+ case UserPalette::ATTACK_RANGE:
+ case UserPalette::ATTACK_RANGE_BORDER:
+ case UserPalette::MONSTER_ATTACK_RANGE:
+ case UserPalette::HOME_PLACE:
+ case UserPalette::HOME_PLACE_BORDER:
+ case UserPalette::COLLISION_HIGHLIGHT:
+ case UserPalette::WALKABLE_HIGHLIGHT:
+ case UserPalette::ROAD_POINT:
+ case UserPalette::MONSTER_HP:
+ case UserPalette::MONSTER_HP2:
+ mGradDelayLabel->setCaption(_("Alpha:"));
+ mGradDelayText->setRange(0, 255);
+ mGradDelaySlider->setScale(0, 255);
+ break;
+ default:
+ mGradDelayLabel->setCaption(_("Delay:"));
+ mGradDelayText->setRange(20, 100);
+ mGradDelaySlider->setScale(20, 100);
+ break;
+ }
+ if (grad != Palette::STATIC && grad != Palette::PULSE)
+ { // If nonstatic color, don't display the current, but the committed
+ // color at the sliders
+ col = &userPalette->getCommittedColor(type);
+ }
+ else if (grad == Palette::PULSE)
+ {
+ col = &userPalette->getTestColor(type);
+ }
+
+ setEntry(mGradDelaySlider, mGradDelayText, delay);
+ setEntry(mRedSlider, mRedText, col->r);
+ setEntry(mGreenSlider, mGreenText, col->g);
+ setEntry(mBlueSlider, mBlueText, col->b);
+
+ mGradTypeSlider->setValue(grad);
+ updateGradType();
+ mGradTypeSlider->setEnabled(true);
+}
+
+void Setup_Colors::setEntry(gcn::Slider *s, TextField *t, int value)
+{
+ if (s)
+ s->setValue(value);
+ if (t)
+ {
+ char buffer[100];
+ sprintf(buffer, "%d", value);
+ t->setText(buffer);
+ }
+}
+
+void Setup_Colors::apply()
+{
+ if (userPalette)
+ userPalette->commit();
+}
+
+void Setup_Colors::cancel()
+{
+ if (!userPalette)
+ return;
+
+ userPalette->rollback();
+ int type = userPalette->getColorTypeAt(mSelected);
+ const gcn::Color *col = &userPalette->getColor(type);
+ mGradTypeSlider->setValue(userPalette->getGradientType(type));
+ const int delay = userPalette->getGradientDelay(type);
+ setEntry(mGradDelaySlider, mGradDelayText, delay);
+ setEntry(mRedSlider, mRedText, col->r);
+ setEntry(mGreenSlider, mGreenText, col->g);
+ setEntry(mBlueSlider, mBlueText, col->b);
+}
+
+#if 0
+void Setup_Colors::listen(const TextField *tf)
+{
+ if (!tf)
+ return;
+
+ if (tf == mGradDelayText)
+ mGradDelaySlider->setValue(tf->getValue());
+ else if (tf == mRedText)
+ mRedSlider->setValue(tf->getValue());
+ else if (tf == mGreenText)
+ mGreenSlider->setValue(tf->getValue());
+ else if (tf == mBlueText)
+ mBlueSlider->setValue(tf->getValue());
+
+ updateColor();
+}
+#endif
+
+void Setup_Colors::updateGradType()
+{
+ if (mSelected == -1 || !userPalette)
+ return;
+
+ mSelected = mColorBox->getSelected();
+ int type = userPalette->getColorTypeAt(mSelected);
+ Palette::GradientType grad = userPalette->getGradientType(type);
+
+ mGradTypeText->setCaption(
+ (grad == Palette::STATIC) ? _("Static") :
+ (grad == Palette::PULSE) ? _("Pulse") :
+ (grad == Palette::RAINBOW) ? _("Rainbow") : _("Spectrum"));
+
+ const bool enable = (grad == Palette::STATIC || grad == Palette::PULSE);
+// const bool delayEnable = (grad != Palette::STATIC);
+ const bool delayEnable = true;
+
+ mGradDelayText->setEnabled(delayEnable);
+ mGradDelaySlider->setEnabled(delayEnable);
+
+ mRedText->setEnabled(enable);
+ mRedSlider->setEnabled(enable);
+ mGreenText->setEnabled(enable);
+ mGreenSlider->setEnabled(enable);
+ mBlueText->setEnabled(enable);
+ mBlueSlider->setEnabled(enable);
+}
+
+void Setup_Colors::updateColor()
+{
+ if (mSelected == -1 || !userPalette)
+ return;
+
+ int type = userPalette->getColorTypeAt(mSelected);
+ Palette::GradientType grad = static_cast<Palette::GradientType>(
+ static_cast<int>(mGradTypeSlider->getValue()));
+ int delay = static_cast<int>(mGradDelaySlider->getValue());
+ userPalette->setGradient(type, grad);
+ userPalette->setGradientDelay(type, delay);
+
+ if (grad == Palette::STATIC)
+ {
+ userPalette->setColor(type,
+ static_cast<int>(mRedSlider->getValue()),
+ static_cast<int>(mGreenSlider->getValue()),
+ static_cast<int>(mBlueSlider->getValue()));
+ }
+ else if (grad == Palette::PULSE)
+ {
+ userPalette->setTestColor(type, gcn::Color(
+ static_cast<int>(mRedSlider->getValue()),
+ static_cast<int>(mGreenSlider->getValue()),
+ static_cast<int>(mBlueSlider->getValue())));
+ }
+}
diff --git a/src/gui/setup_colors.h b/src/gui/setup_colors.h
new file mode 100644
index 000000000..1b3985850
--- /dev/null
+++ b/src/gui/setup_colors.h
@@ -0,0 +1,96 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SETUP_COLORS_H
+#define SETUP_COLORS_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class BrowserBox;
+class TextField;
+class TextPreview;
+
+class Setup_Colors : public SetupTab,
+ public gcn::ActionListener,
+ public gcn::SelectionListener
+{
+ public:
+ Setup_Colors();
+ ~Setup_Colors();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ private:
+ static const std::string rawmsg;
+
+ gcn::ListBox *mColorBox;
+ gcn::ScrollArea *mScroll;
+ BrowserBox *mPreview;
+ TextPreview *mTextPreview;
+ gcn::ScrollArea *mPreviewBox;
+ int mSelected;
+
+ gcn::Label *mGradTypeLabel;
+ gcn::Slider *mGradTypeSlider;
+ gcn::Label *mGradTypeText;
+
+ gcn::Label *mGradDelayLabel;
+ gcn::Slider *mGradDelaySlider;
+ TextField *mGradDelayText;
+
+ gcn::Label *mRedLabel;
+ gcn::Slider *mRedSlider;
+ TextField *mRedText;
+ int mRedValue;
+
+ gcn::Label *mGreenLabel;
+ gcn::Slider *mGreenSlider;
+ TextField *mGreenText;
+ int mGreenValue;
+
+ gcn::Label *mBlueLabel;
+ gcn::Slider *mBlueSlider;
+ TextField *mBlueText;
+ int mBlueValue;
+
+ void setEntry(gcn::Slider *s, TextField *t, int value);
+ void updateColor();
+ void updateGradType();
+};
+
+#endif // SETUP_COLORS_H
diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp
new file mode 100644
index 000000000..5f8f11993
--- /dev/null
+++ b/src/gui/setup_joystick.cpp
@@ -0,0 +1,101 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/setup_joystick.h"
+
+#include "configuration.h"
+#include "joystick.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+
+#include "utils/gettext.h"
+
+extern Joystick *joystick;
+
+Setup_Joystick::Setup_Joystick():
+ mCalibrateLabel(new Label(_("Press the button to start calibration"))),
+ mCalibrateButton(new Button(_("Calibrate"), "calibrate", this)),
+ mJoystickEnabled(new CheckBox(_("Enable joystick")))
+{
+ setName(_("Joystick"));
+
+ mOriginalJoystickEnabled = !config.getBoolValue("joystickEnabled");
+ mJoystickEnabled->setSelected(mOriginalJoystickEnabled);
+
+ mJoystickEnabled->addActionListener(this);
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mJoystickEnabled);
+ place(0, 1, mCalibrateLabel);
+ place.getCell().matchColWidth(0, 0);
+ place = h.getPlacer(0, 1);
+ place(0, 0, mCalibrateButton);
+
+ setDimension(gcn::Rectangle(0, 0, 365, 75));
+}
+
+void Setup_Joystick::action(const gcn::ActionEvent &event)
+{
+ if (!joystick)
+ return;
+
+ if (event.getSource() == mJoystickEnabled)
+ {
+ joystick->setEnabled(mJoystickEnabled->isSelected());
+ }
+ else
+ {
+ if (joystick->isCalibrating())
+ {
+ mCalibrateButton->setCaption(_("Calibrate"));
+ mCalibrateLabel->setCaption
+ (_("Press the button to start calibration"));
+ joystick->finishCalibration();
+ }
+ else
+ {
+ mCalibrateButton->setCaption(_("Stop"));
+ mCalibrateLabel->setCaption(_("Rotate the stick"));
+ joystick->startCalibration();
+ }
+ }
+}
+
+void Setup_Joystick::cancel()
+{
+ if (joystick)
+ joystick->setEnabled(mOriginalJoystickEnabled);
+
+ mJoystickEnabled->setSelected(mOriginalJoystickEnabled);
+}
+
+void Setup_Joystick::apply()
+{
+ config.setValue("joystickEnabled",
+ joystick ? joystick->isEnabled() : false);
+}
+
diff --git a/src/gui/setup_joystick.h b/src/gui/setup_joystick.h
new file mode 100644
index 000000000..f848f45c1
--- /dev/null
+++ b/src/gui/setup_joystick.h
@@ -0,0 +1,48 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_SETUP_JOYSTICK_H
+#define GUI_SETUP_JOYSTICK_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+
+class Setup_Joystick : public SetupTab, public gcn::ActionListener
+{
+ public:
+ Setup_Joystick();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::Label *mCalibrateLabel;
+ gcn::Button *mCalibrateButton;
+ bool mOriginalJoystickEnabled;
+ gcn::CheckBox *mJoystickEnabled;
+};
+
+#endif
diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp
new file mode 100644
index 000000000..4e55ecb35
--- /dev/null
+++ b/src/gui/setup_keyboard.cpp
@@ -0,0 +1,210 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/setup_keyboard.h"
+
+#include "keyboardconfig.h"
+
+#include "gui/okdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/scrollarea.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/listmodel.hpp>
+
+#include <SDL_keyboard.h>
+
+/**
+ * The list model for key function list.
+ *
+ * \ingroup Interface
+ */
+class KeyListModel : public gcn::ListModel
+{
+ public:
+ /**
+ * Returns the number of elements in container.
+ */
+ int getNumberOfElements()
+ { return keyboard.KEY_TOTAL; }
+
+ /**
+ * Returns element from container.
+ */
+ std::string getElementAt(int i)
+ { return mKeyFunctions[i]; }
+
+ /**
+ * Sets element from container.
+ */
+ void setElementAt(int i, const std::string &caption)
+ { mKeyFunctions[i] = caption; }
+
+ private:
+ std::string mKeyFunctions[KeyboardConfig::KEY_TOTAL];
+};
+
+Setup_Keyboard::Setup_Keyboard():
+ mKeyListModel(new KeyListModel),
+ mKeyList(new ListBox(mKeyListModel)),
+ mKeySetting(false)
+{
+ keyboard.setSetupKeyboard(this);
+ setName(_("Keyboard"));
+
+ refreshKeys();
+
+ mKeyList->addActionListener(this);
+
+ ScrollArea *scrollArea = new ScrollArea(mKeyList);
+ scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mAssignKeyButton = new Button(_("Assign"), "assign", this);
+ mAssignKeyButton->addActionListener(this);
+ mAssignKeyButton->setEnabled(false);
+
+ mUnassignKeyButton = new Button(_("Unassign"), "unassign", this);
+ mUnassignKeyButton->addActionListener(this);
+ mUnassignKeyButton->setEnabled(false);
+
+ mMakeDefaultButton = new Button(_("Default"), "makeDefault", this);
+ mMakeDefaultButton->addActionListener(this);
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, scrollArea, 4, 6).setPadding(2);
+ place(0, 6, mMakeDefaultButton);
+ place(2, 6, mAssignKeyButton);
+ place(3, 6, mUnassignKeyButton);
+
+ setDimension(gcn::Rectangle(0, 0, 500, 350));
+}
+
+Setup_Keyboard::~Setup_Keyboard()
+{
+ delete mKeyList;
+ mKeyList = 0;
+ delete mKeyListModel;
+ mKeyListModel = 0;
+
+ delete mAssignKeyButton;
+ mAssignKeyButton = 0;
+ delete mUnassignKeyButton;
+ mUnassignKeyButton = 0;
+ delete mMakeDefaultButton;
+ mMakeDefaultButton = 0;
+}
+
+void Setup_Keyboard::apply()
+{
+ keyUnresolved();
+
+ if (keyboard.hasConflicts())
+ {
+ new OkDialog(_("Key Conflict(s) Detected."),
+ keyboard.getBindError());
+ }
+ keyboard.setEnabled(true);
+ keyboard.store();
+}
+
+void Setup_Keyboard::cancel()
+{
+ keyUnresolved();
+
+ keyboard.retrieve();
+ keyboard.setEnabled(true);
+
+ refreshKeys();
+}
+
+void Setup_Keyboard::action(const gcn::ActionEvent &event)
+{
+ if (event.getSource() == mKeyList)
+ {
+ if (!mKeySetting)
+ {
+ mAssignKeyButton->setEnabled(true);
+ mUnassignKeyButton->setEnabled(true);
+ }
+ }
+ else if (event.getId() == "assign")
+ {
+ mKeySetting = true;
+ mAssignKeyButton->setEnabled(false);
+ keyboard.setEnabled(false);
+ int i(mKeyList->getSelected());
+ keyboard.setNewKeyIndex(i);
+ mKeyListModel->setElementAt(i, keyboard.getKeyCaption(i) + ": ?");
+ }
+ else if (event.getId() == "unassign")
+ {
+ int i(mKeyList->getSelected());
+ keyboard.setNewKeyIndex(i);
+ refreshAssignedKey(mKeyList->getSelected());
+ keyboard.setNewKey(keyboard.KEY_NO_VALUE);
+ mAssignKeyButton->setEnabled(true);
+ }
+ else if (event.getId() == "makeDefault")
+ {
+ keyboard.makeDefault();
+ refreshKeys();
+ }
+}
+
+void Setup_Keyboard::refreshAssignedKey(int index)
+{
+ std::string caption;
+ char *temp = SDL_GetKeyName(
+ static_cast<SDLKey>(keyboard.getKeyValue(index)));
+ caption = keyboard.getKeyCaption(index) + ": " + toString(temp);
+ mKeyListModel->setElementAt(index, caption);
+}
+
+void Setup_Keyboard::newKeyCallback(int index)
+{
+ mKeySetting = false;
+ refreshAssignedKey(index);
+ mAssignKeyButton->setEnabled(true);
+}
+
+void Setup_Keyboard::refreshKeys()
+{
+ for (int i = 0; i < keyboard.KEY_TOTAL; i++)
+ refreshAssignedKey(i);
+}
+
+void Setup_Keyboard::keyUnresolved()
+{
+ if (mKeySetting)
+ {
+ newKeyCallback(keyboard.getNewKeyIndex());
+ keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE);
+ }
+}
diff --git a/src/gui/setup_keyboard.h b/src/gui/setup_keyboard.h
new file mode 100644
index 000000000..4c916705c
--- /dev/null
+++ b/src/gui/setup_keyboard.h
@@ -0,0 +1,81 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_SETUP_KEYBOARD_H
+#define GUI_SETUP_KEYBOARD_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <string>
+
+class Setup_Keyboard : public SetupTab, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor
+ */
+ Setup_Keyboard();
+
+ /**
+ * Destructor
+ */
+ ~Setup_Keyboard();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Get an update on the assigned key.
+ */
+ void refreshAssignedKey(int index);
+
+ /**
+ * The callback function when a new key has been pressed.
+ */
+ void newKeyCallback(int index);
+
+ /**
+ * Shorthand method to update all the keys.
+ */
+ void refreshKeys();
+
+ /**
+ * If a key function is unresolved, then this reverts it.
+ */
+ void keyUnresolved();
+
+ private:
+ class KeyListModel *mKeyListModel;
+ gcn::ListBox *mKeyList;
+
+ gcn::Button *mAssignKeyButton;
+ gcn::Button *mUnassignKeyButton;
+ gcn::Button *mMakeDefaultButton;
+
+ bool mKeySetting; /**< flag to check if key being set. */
+};
+
+#endif
diff --git a/src/gui/setup_other.cpp b/src/gui/setup_other.cpp
new file mode 100644
index 000000000..54ec1c65d
--- /dev/null
+++ b/src/gui/setup_other.cpp
@@ -0,0 +1,426 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/setup_other.h"
+#include "gui/editdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/textfield.h"
+
+#include "configuration.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "utils/gettext.h"
+
+#define ACTION_SHOW_TAKEDDAMAGE "taked damage"
+#define ACTION_NO_RAIN "no rain"
+#define ACTION_ONLY_REACHABLE "only reachable"
+#define ACTION_ERRORS_IN_DEBUG "errors in debug"
+#define ACTION_HIGHLIGHT_PORTALS "highlight portals"
+#define ACTION_HIGHLIGHT_ATTACK_RANGE "highlight attack"
+#define ACTION_HIGHLIGHT_MONSTER_ATTACK_RANGE "highlight monster attack"
+#define ACTION_CYCLE_PLAYERS "cycle players"
+#define ACTION_CYCLE_MONSTERS "cycle monsters"
+#define ACTION_ENABLE_BOTCHECKER "bot checker"
+#define ACTION_FLOORITEMS_HIGHLIGHT "floor items"
+#define ACTION_MOVE_PROGRAM "move program"
+#define ACTION_EDIT_PROGRAM "edit program"
+#define ACTION_EDIT_PROGRAM_OK "edit program ok"
+#define ACTION_AFK "move afk"
+#define ACTION_EDIT_AFK "edit afk"
+#define ACTION_EDIT_AFK_OK "edit afk ok"
+#define ACTION_ENABLE_AFK "enable afk"
+#define ACTION_TRADEBOT "trade bot"
+#define ACTION_BUGGY_SERVERS "buggy servers"
+#define ACTION_DEBUG_LOG "debug log"
+#define ACTION_SERVER_ATTACK "server attack"
+#define ACTION_FIX_POS "fix pos"
+#define ACTION_ATTACK_MOVING "attack moving"
+#define ACTION_QUICK_STATS "quick stats"
+#define ACTION_WARP_PARTICLE "warp particle"
+#define ACTION_AUTO_SHOP "auto shop"
+#define ACTION_SHOW_MOB_HP "show mob hp"
+
+Setup_Other::Setup_Other():
+ mShowMonstersTakedDamage(config.getBoolValue("showMonstersTakedDamage")),
+ mTargetOnlyReachable(config.getBoolValue("targetOnlyReachable")),
+ mErrorsInDebug(config.getBoolValue("errorsInDebug")),
+ mHighlightPortals(config.getBoolValue("highlightMapPortals")),
+ mHighlightAttackRange(config.getBoolValue("highlightAttackRange")),
+ mHighlightMonsterAttackRange(
+ config.getBoolValue("highlightMonsterAttackRange")),
+ mCyclePlayers(config.getBoolValue("cyclePlayers")),
+ mCycleMonsters(config.getBoolValue("cycleMonsters")),
+ mEnableBotChecker(config.getBoolValue("enableBotCheker")),
+ mFloorItemsHighlight(config.getBoolValue("floorItemsHighlight")),
+ mMoveProgram(config.getStringValue("crazyMoveProgram")),
+ mAfk(config.getStringValue("afkMessage")),
+ mTradeBot(config.getBoolValue("tradebot")),
+ mBuggyServers(serverConfig.getValueBool("enableBuggyServers", true)),
+ mDebugLog(config.getBoolValue("debugLog")),
+ mServerAttack(config.getBoolValue("serverAttack")),
+ mAutofixPos(config.getBoolValue("autofixPos")),
+ mAttackMoving(config.getBoolValue("attackMoving")),
+ mQuickStats(config.getBoolValue("quickStats")),
+ mWarpParticle(config.getBoolValue("warpParticle")),
+ mAutoShop(config.getBoolValue("autoShop")),
+ mShowMobHP(config.getBoolValue("showMobHP"))
+{
+ setName(_("Misc"));
+
+ mShowMonstersTakedDamageCheckBox = new CheckBox(
+ _("Show damage inflicted to monsters"),
+ mShowMonstersTakedDamage,
+ this, ACTION_SHOW_TAKEDDAMAGE);
+
+ mTargetOnlyReachableCheckBox = new CheckBox(
+ _("Auto target only reachable monsters"),
+ mTargetOnlyReachable,
+ this, ACTION_ONLY_REACHABLE);
+
+ mHighlightPortalsCheckBox = new CheckBox(_("Highlight map portals"),
+ mHighlightPortals,
+ this, ACTION_HIGHLIGHT_PORTALS);
+
+ mHighlightAttackRangeCheckBox = new CheckBox(
+ _("Highlight player attack range"),
+ mHighlightAttackRange,
+ this, ACTION_HIGHLIGHT_ATTACK_RANGE);
+
+ mHighlightMonsterAttackRangeCheckBox = new CheckBox(
+ _("Highlight monster attack range"),
+ mHighlightMonsterAttackRange,
+ this, ACTION_HIGHLIGHT_MONSTER_ATTACK_RANGE);
+
+ mCyclePlayersCheckBox = new CheckBox(_("Cycle player targets"),
+ mCyclePlayers, this, ACTION_CYCLE_PLAYERS);
+
+ mCycleMonstersCheckBox = new CheckBox(_("Cycle monster targets"),
+ mCycleMonsters, this, ACTION_CYCLE_MONSTERS);
+
+ mEnableBotCheckerCheckBox = new CheckBox(_("Enable bot checker"),
+ mEnableBotChecker, this, ACTION_ENABLE_BOTCHECKER);
+
+ mFloorItemsHighlightCheckBox = new CheckBox(_("Highlight floor items"),
+ mFloorItemsHighlight, this, ACTION_FLOORITEMS_HIGHLIGHT);
+
+ mMoveProgramLabel = new Label(_("Crazy move A program"));
+
+ mMoveProgramField = new TextField(mMoveProgram, true,
+ this, ACTION_MOVE_PROGRAM);
+
+ mMoveProgramButton = new Button(_("Edit"), ACTION_EDIT_PROGRAM, this);
+
+ mAfkField = new TextField(mAfk, true, this, ACTION_AFK);
+
+ mAfkButton = new Button(_("Edit"), ACTION_EDIT_AFK, this);
+
+ mTradeBotCheckBox = new CheckBox(_("Enable shop mode"),
+ mTradeBot,
+ this, ACTION_TRADEBOT);
+
+ mBuggyServersCheckBox = new CheckBox(_("Enable buggy servers protection"),
+ mBuggyServers,
+ this, ACTION_BUGGY_SERVERS);
+
+ mDebugLogCheckBox = new CheckBox(_("Enable debug log"),
+ mDebugLog,
+ this, ACTION_DEBUG_LOG);
+
+ mServerAttackCheckBox = new CheckBox(_("Enable server side attack"),
+ mServerAttack,
+ this, ACTION_SERVER_ATTACK);
+
+ mAutofixPosCheckBox = new CheckBox(_("Auto fix position"),
+ mAutofixPos,
+ this, ACTION_FIX_POS);
+
+ mAttackMovingCheckBox = new CheckBox(_("Attack while moving"),
+ mAttackMoving,
+ this, ACTION_ATTACK_MOVING);
+
+ mQuickStatsCheckBox = new CheckBox(_("Enable quick stats"),
+ mQuickStats,
+ this, ACTION_QUICK_STATS);
+
+ mWarpParticleCheckBox = new CheckBox(_("Show warps particles"),
+ mWarpParticle,
+ this, ACTION_WARP_PARTICLE);
+
+ mAutoShopCheckBox = new CheckBox(_("Accept sell/buy requests"),
+ mAutoShop,
+ this, ACTION_AUTO_SHOP);
+
+ mShowMobHPCheckBox = new CheckBox(_("Show monster hp bar"),
+ mShowMobHP,
+ this, ACTION_SHOW_MOB_HP);
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mShowMonstersTakedDamageCheckBox, 12);
+ place(12, 0, mServerAttackCheckBox, 10);
+ place(0, 1, mTargetOnlyReachableCheckBox, 12);
+ place(12, 1, mAutofixPosCheckBox, 10);
+ place(0, 2, mHighlightPortalsCheckBox, 12);
+ place(12, 2, mAttackMovingCheckBox, 10);
+ place(12, 3, mQuickStatsCheckBox, 10);
+ place(12, 4, mWarpParticleCheckBox, 10);
+ place(12, 5, mAutoShopCheckBox, 10);
+ place(12, 6, mShowMobHPCheckBox, 10);
+ place(0, 3, mFloorItemsHighlightCheckBox, 12);
+ place(0, 4, mHighlightAttackRangeCheckBox, 12);
+ place(0, 5, mHighlightMonsterAttackRangeCheckBox, 12);
+ place(0, 6, mCyclePlayersCheckBox, 12);
+ place(0, 7, mCycleMonstersCheckBox, 12);
+ place(0, 8, mEnableBotCheckerCheckBox, 12);
+ place(0, 9, mMoveProgramLabel, 12);
+ place(0, 10, mMoveProgramField, 9);
+ place(9, 10, mMoveProgramButton, 2);
+ place(0, 11, mAfkField, 9);
+ place(9, 11, mAfkButton, 2);
+ place(0, 12, mTradeBotCheckBox, 12);
+ place(0, 13, mBuggyServersCheckBox, 12);
+ place(0, 14, mDebugLogCheckBox, 12);
+
+ place.getCell().matchColWidth(0, 0);
+ place = h.getPlacer(0, 1);
+
+ setDimension(gcn::Rectangle(0, 0, 550, 500));
+}
+
+void Setup_Other::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == ACTION_SHOW_TAKEDDAMAGE)
+ {
+ mShowMonstersTakedDamage = mShowMonstersTakedDamageCheckBox
+ ->isSelected();
+ }
+ else if (event.getId() == ACTION_ONLY_REACHABLE)
+ {
+ mTargetOnlyReachable = mTargetOnlyReachableCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_HIGHLIGHT_PORTALS)
+ {
+ mHighlightPortals = mHighlightPortalsCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_HIGHLIGHT_ATTACK_RANGE)
+ {
+ mHighlightAttackRange = mHighlightAttackRangeCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_HIGHLIGHT_MONSTER_ATTACK_RANGE)
+ {
+ mHighlightMonsterAttackRange = mHighlightMonsterAttackRangeCheckBox
+ ->isSelected();
+ }
+ else if (event.getId() == ACTION_CYCLE_PLAYERS)
+ {
+ mCyclePlayers = mCyclePlayersCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_CYCLE_MONSTERS)
+ {
+ mCycleMonsters = mCycleMonstersCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_ENABLE_BOTCHECKER)
+ {
+ mEnableBotChecker = mEnableBotCheckerCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_FLOORITEMS_HIGHLIGHT)
+ {
+ mFloorItemsHighlight = mFloorItemsHighlightCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_MOVE_PROGRAM)
+ {
+ mMoveProgram = mMoveProgramField->getText();
+ }
+ else if (event.getId() == ACTION_EDIT_PROGRAM)
+ {
+ mEditDialog = new EditDialog("Crazy Move A",
+ mMoveProgramField->getText(), ACTION_EDIT_PROGRAM_OK);
+ mEditDialog->addActionListener(this);
+ }
+ else if (event.getId() == ACTION_EDIT_PROGRAM_OK)
+ {
+ mMoveProgramField->setText(mEditDialog->getMsg());
+ }
+
+ else if (event.getId() == ACTION_AFK)
+ mAfk = mAfkField->getText();
+ else if (event.getId() == ACTION_EDIT_AFK)
+ {
+ mEditDialog = new EditDialog("Afk message", mAfkField->getText(),
+ ACTION_EDIT_AFK_OK);
+ mEditDialog->addActionListener(this);
+ }
+ else if (event.getId() == ACTION_EDIT_AFK_OK)
+ {
+ mAfkField->setText(mEditDialog->getMsg());
+ }
+ else if (event.getId() == ACTION_TRADEBOT)
+ {
+ mTradeBot = mTradeBotCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_BUGGY_SERVERS)
+ {
+ mBuggyServers = mBuggyServersCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_DEBUG_LOG)
+ {
+ mDebugLog = mDebugLogCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SERVER_ATTACK)
+ {
+ mServerAttack = mServerAttackCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_FIX_POS)
+ {
+ mAutofixPos = mAutofixPosCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_ATTACK_MOVING)
+ {
+ mAttackMoving = mAttackMovingCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_QUICK_STATS)
+ {
+ mQuickStats = mQuickStatsCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_WARP_PARTICLE)
+ {
+ mWarpParticle = mWarpParticleCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_AUTO_SHOP)
+ {
+ mAutoShop = mAutoShopCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SHOW_MOB_HP)
+ {
+ mShowMobHP = mShowMobHPCheckBox->isSelected();
+ }
+}
+
+void Setup_Other::cancel()
+{
+ mShowMonstersTakedDamage = config.getBoolValue(
+ "showMonstersTakedDamage");
+ mShowMonstersTakedDamageCheckBox->setSelected(mShowMonstersTakedDamage);
+
+ mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable");
+ mTargetOnlyReachableCheckBox->setSelected(mTargetOnlyReachable);
+
+ mHighlightPortals = config.getBoolValue("highlightMapPortals");
+ mHighlightPortalsCheckBox->setSelected(mHighlightPortals);
+
+ mHighlightAttackRange = config.getBoolValue("highlightAttackRange");
+ mHighlightAttackRangeCheckBox->setSelected(mHighlightAttackRange);
+
+ mHighlightMonsterAttackRange = config.getBoolValue(
+ "highlightMonsterAttackRange");
+ mHighlightMonsterAttackRangeCheckBox->setSelected(
+ mHighlightMonsterAttackRange);
+
+ mCyclePlayers = config.getBoolValue("cyclePlayers");
+ mCyclePlayersCheckBox->setSelected(mCyclePlayers);
+
+ mCycleMonsters = config.getBoolValue("cycleMonsters");
+ mCycleMonstersCheckBox->setSelected(mCycleMonsters);
+
+ mEnableBotChecker = config.getBoolValue("enableBotCheker");
+ mEnableBotCheckerCheckBox->setSelected(mEnableBotChecker);
+
+ mFloorItemsHighlight = config.getBoolValue("floorItemsHighlight");
+ mFloorItemsHighlightCheckBox->setSelected(mFloorItemsHighlight);
+
+ mMoveProgram = config.getStringValue("crazyMoveProgram");
+ mMoveProgramField->setText(mMoveProgram);
+
+ mAfk = config.getStringValue("afkMessage");
+ mAfkField->setText(mAfk);
+
+ mTradeBot = config.getBoolValue("tradebot");
+ mTradeBotCheckBox->setSelected(mTradeBot);
+
+ mBuggyServers = serverConfig.getValueBool("enableBuggyServers", true);
+ mBuggyServersCheckBox->setSelected(mBuggyServers);
+
+ mDebugLog = config.getBoolValue("debugLog");
+ mDebugLogCheckBox->setSelected(mDebugLog);
+
+ mServerAttack = config.getBoolValue("serverAttack");
+ mServerAttackCheckBox->setSelected(mServerAttack);
+
+ mAutofixPos = config.getBoolValue("autofixPos");
+ mAutofixPosCheckBox->setSelected(mAutofixPos);
+
+ mAttackMoving = config.getBoolValue("attackMoving");
+ mAttackMovingCheckBox->setSelected(mAttackMoving);
+
+ mQuickStats = config.getBoolValue("quickStats");
+ mQuickStatsCheckBox->setSelected(mQuickStats);
+
+ mWarpParticle = config.getBoolValue("warpParticle");
+ mWarpParticleCheckBox->setSelected(mWarpParticle);
+
+ mAutoShop = config.getBoolValue("autoShop");
+ mAutoShopCheckBox->setSelected(mAutoShop);
+
+ mShowMobHP = config.getBoolValue("showMobHP");
+ mShowMobHPCheckBox->setSelected(mShowMobHP);
+}
+
+void Setup_Other::apply()
+{
+ config.setValue("showMonstersTakedDamage", mShowMonstersTakedDamage);
+ config.setValue("targetOnlyReachable", mTargetOnlyReachable);
+ config.setValue("errorsInDebug", mErrorsInDebug);
+ config.setValue("highlightMapPortals", mHighlightPortals);
+ config.setValue("highlightAttackRange", mHighlightAttackRange);
+ config.setValue("highlightMonsterAttackRange",
+ mHighlightMonsterAttackRange);
+ config.setValue("cyclePlayers", mCyclePlayers);
+ config.setValue("cycleMonsters", mCycleMonsters);
+ config.setValue("enableBotCheker", mEnableBotChecker);
+ config.setValue("floorItemsHighlight", mFloorItemsHighlight);
+ config.setValue("crazyMoveProgram", mMoveProgramField->getText());
+ config.setValue("afkMessage", mAfkField->getText());
+ config.setValue("tradebot", mTradeBot);
+ serverConfig.setValue("enableBuggyServers", mBuggyServers);
+ config.setValue("debugLog", mDebugLog);
+ config.setValue("serverAttack", mServerAttack);
+ config.setValue("autofixPos", mAutofixPos);
+ config.setValue("attackMoving", mAttackMoving);
+ config.setValue("quickStats", mQuickStats);
+ config.setValue("warpParticle", mWarpParticle);
+ config.setValue("autoShop", mAutoShop);
+ config.setValue("showMobHP", mShowMobHP);
+ logger->setDebugLog(mDebugLog);
+}
+
+void Setup_Other::externalUpdated()
+{
+ mBuggyServers = serverConfig.getValueBool("enableBuggyServers", true);
+ mBuggyServersCheckBox->setSelected(mBuggyServers);
+} \ No newline at end of file
diff --git a/src/gui/setup_other.h b/src/gui/setup_other.h
new file mode 100644
index 000000000..b20401be5
--- /dev/null
+++ b/src/gui/setup_other.h
@@ -0,0 +1,125 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_Setup_Other_H
+#define GUI_Setup_Other_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+
+class EditDialog;
+
+class Setup_Other : public SetupTab, public gcn::ActionListener
+{
+ public:
+ Setup_Other();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ virtual void externalUpdated();
+
+ private:
+ gcn::CheckBox *mShowMonstersTakedDamageCheckBox;
+ bool mShowMonstersTakedDamage;
+
+ gcn::CheckBox *mNoRainCheckBox;
+ bool mNoRain;
+
+ gcn::CheckBox *mTargetOnlyReachableCheckBox;
+ bool mTargetOnlyReachable;
+
+ int mOverlayDetail;
+ gcn::DropDown *mFontSizeDropDown;
+
+ gcn::CheckBox *mErrorsInDebugCheckBox;
+ bool mErrorsInDebug;
+
+ gcn::CheckBox *mHighlightPortalsCheckBox;
+ bool mHighlightPortals;
+
+ gcn::CheckBox *mHighlightAttackRangeCheckBox;
+ bool mHighlightAttackRange;
+
+ gcn::CheckBox *mHighlightMonsterAttackRangeCheckBox;
+ bool mHighlightMonsterAttackRange;
+
+ gcn::CheckBox *mCyclePlayersCheckBox;
+ bool mCyclePlayers;
+
+ gcn::CheckBox *mCycleMonstersCheckBox;
+ bool mCycleMonsters;
+
+ gcn::CheckBox *mEnableBotCheckerCheckBox;
+ bool mEnableBotChecker;
+
+ gcn::CheckBox *mFloorItemsHighlightCheckBox;
+ bool mFloorItemsHighlight;
+
+ gcn::Label *mMoveProgramLabel;
+ gcn::TextField *mMoveProgramField;
+ gcn::Button *mMoveProgramButton;
+ std::string mMoveProgram;
+
+ gcn::TextField *mAfkField;
+ gcn::Button *mAfkButton;
+ std::string mAfk;
+
+ gcn::CheckBox *mTradeBotCheckBox;
+ bool mTradeBot;
+
+ gcn::CheckBox *mBuggyServersCheckBox;
+ bool mBuggyServers;
+
+ gcn::CheckBox *mDebugLogCheckBox;
+ bool mDebugLog;
+
+ gcn::CheckBox *mServerAttackCheckBox;
+ bool mServerAttack;
+
+ gcn::CheckBox *mAutofixPosCheckBox;
+ bool mAutofixPos;
+
+ gcn::CheckBox *mAttackMovingCheckBox;
+ bool mAttackMoving;
+
+ gcn::CheckBox *mQuickStatsCheckBox;
+ bool mQuickStats;
+
+ gcn::CheckBox *mWarpParticleCheckBox;
+ bool mWarpParticle;
+
+ gcn::CheckBox *mAutoShopCheckBox;
+ bool mAutoShop;
+
+ gcn::CheckBox *mShowMobHPCheckBox;
+ bool mShowMobHP;
+
+ EditDialog *mEditDialog;
+};
+
+#endif
diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp
new file mode 100644
index 000000000..6f4d50888
--- /dev/null
+++ b/src/gui/setup_players.cpp
@@ -0,0 +1,505 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/setup_players.h"
+
+#include "actorspritemanager.h"
+#include "configuration.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/okdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/dropdown.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/table.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+
+#include <string>
+#include <vector>
+
+#define COLUMNS_NR 2 // name plus listbox
+#define NAME_COLUMN 0
+#define RELATION_CHOICE_COLUMN 1
+
+#define ROW_HEIGHT 12
+// The following column widths really shouldn't be hardcoded but should scale with the size of the widget... except
+// that, right now, the widget doesn't exactly scale either.
+#define NAME_COLUMN_WIDTH 230
+#define RELATION_CHOICE_COLUMN_WIDTH 80
+
+#define WIDGET_AT(row, column) (((row) * COLUMNS_NR) + column)
+
+static const char *table_titles[COLUMNS_NR] =
+{
+ N_("Name"),
+ N_("Relation")
+};
+
+static const char *RELATION_NAMES[PlayerRelation::RELATIONS_NR] =
+{
+ N_("Neutral"),
+ N_("Friend"),
+ N_("Disregarded"),
+ N_("Ignored"),
+ N_("Erased")
+};
+
+class PlayerRelationListModel : public gcn::ListModel
+{
+public:
+ virtual ~PlayerRelationListModel() { }
+
+ virtual int getNumberOfElements()
+ {
+ return PlayerRelation::RELATIONS_NR;
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return "";
+ return gettext(RELATION_NAMES[i]);
+ }
+};
+
+class PlayerTableModel : public TableModel
+{
+public:
+ PlayerTableModel() :
+ mPlayers(NULL),
+ mListModel(new PlayerRelationListModel)
+ {
+ playerRelationsUpdated();
+ }
+
+ virtual ~PlayerTableModel()
+ {
+ freeWidgets();
+ delete mListModel;
+ mListModel = 0;
+ delete mPlayers;
+ mPlayers = 0;
+ }
+
+ virtual int getRows() const
+ {
+ if (mPlayers)
+ return static_cast<int>(mPlayers->size());
+ else
+ return 0;
+ }
+
+ virtual int getColumns() const
+ {
+ return COLUMNS_NR;
+ }
+
+ virtual int getRowHeight() const
+ {
+ return ROW_HEIGHT;
+ }
+
+ virtual int getColumnWidth(int index) const
+ {
+ if (index == NAME_COLUMN)
+ return NAME_COLUMN_WIDTH;
+ else
+ return RELATION_CHOICE_COLUMN_WIDTH;
+ }
+
+ virtual void playerRelationsUpdated()
+ {
+ signalBeforeUpdate();
+
+ freeWidgets();
+ std::vector<std::string> *player_names = player_relations.getPlayers();
+
+ if (!player_names)
+ return;
+
+ delete mPlayers;
+ mPlayers = player_names;
+
+ // set up widgets
+ for (unsigned int r = 0; r < player_names->size(); ++r)
+ {
+ std::string name = (*player_names)[r];
+ gcn::Widget *widget = new Label(name);
+ mWidgets.push_back(widget);
+
+ gcn::DropDown *choicebox = new DropDown(mListModel);
+ choicebox->setSelected(player_relations.getRelation(name));
+ mWidgets.push_back(choicebox);
+ }
+
+ signalAfterUpdate();
+ }
+
+ virtual void updateModelInRow(int row)
+ {
+ gcn::DropDown *choicebox = static_cast<gcn::DropDown *>(
+ getElementAt(row, RELATION_CHOICE_COLUMN));
+ player_relations.setRelation(getPlayerAt(row),
+ static_cast<PlayerRelation::Relation>(
+ choicebox->getSelected()));
+ }
+
+
+ virtual gcn::Widget *getElementAt(int row, int column) const
+ {
+ return mWidgets[WIDGET_AT(row, column)];
+ }
+
+ virtual void freeWidgets()
+ {
+ delete mPlayers;
+ mPlayers = 0;
+
+ delete_all(mWidgets);
+ mWidgets.clear();
+ }
+
+ std::string getPlayerAt(int index) const
+ {
+ return (*mPlayers)[index];
+ }
+
+protected:
+ std::vector<std::string> *mPlayers;
+ std::vector<gcn::Widget *> mWidgets;
+ PlayerRelationListModel *mListModel;
+};
+
+/**
+ * Class for choosing one of the various `what to do when ignoring a player' options
+ */
+class IgnoreChoicesListModel : public gcn::ListModel
+{
+public:
+ virtual ~IgnoreChoicesListModel() { }
+
+ virtual int getNumberOfElements()
+ {
+ return static_cast<int>(player_relations.getPlayerIgnoreStrategies()
+ ->size());
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return (*player_relations.getPlayerIgnoreStrategies())
+ [i]->mDescription;
+ }
+};
+
+#define ACTION_DELETE "delete"
+#define ACTION_OLD "old"
+#define ACTION_TABLE "table"
+#define ACTION_STRATEGY "strategy"
+#define ACTION_WHISPER_TAB "whisper tab"
+#define ACTION_SHOW_GENDER "show gender"
+#define ACTION_SHOW_LEVEL "show level"
+#define ACTION_TARGET_DEAD "target dead"
+#define ACTION_SHOW_OWN_NAME "show own name"
+
+Setup_Players::Setup_Players():
+ mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)),
+ mPlayerTableModel(new PlayerTableModel),
+ mPlayerTable(new GuiTable(mPlayerTableModel)),
+ mPlayerTitleTable(new GuiTable(mPlayerTableTitleModel)),
+ mPlayerScrollArea(new ScrollArea(mPlayerTable)),
+ mDefaultTrading(new CheckBox(_("Allow trading"),
+ player_relations.getDefault() & PlayerRelation::TRADE)),
+ mDefaultWhisper(new CheckBox(_("Allow whispers"),
+ player_relations.getDefault() & PlayerRelation::WHISPER)),
+ mDeleteButton(new Button(_("Delete"), ACTION_DELETE, this)),
+ mOldButton(new Button(_("Old"), ACTION_OLD, this)),
+ mWhisperTab(config.getBoolValue("whispertab")),
+ mWhisperTabCheckBox(new CheckBox(_("Put all whispers in tabs"),
+ mWhisperTab)),
+ mShowGender(config.getBoolValue("showgender")),
+ mShowGenderCheckBox(new CheckBox(_("Show gender"), mShowGender)),
+ mShowLevel(config.getBoolValue("showlevel")),
+ mShowOwnName(config.getBoolValue("showownname")),
+ mTargetDead(config.getBoolValue("targetDeadPlayers"))
+{
+ setName(_("Players"));
+
+ mPlayerTable->setOpaque(false);
+
+ mPlayerTableTitleModel->fixColumnWidth(NAME_COLUMN, NAME_COLUMN_WIDTH);
+ mPlayerTableTitleModel->fixColumnWidth(RELATION_CHOICE_COLUMN,
+ RELATION_CHOICE_COLUMN_WIDTH);
+ mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf));
+
+ mIgnoreActionChoicesModel = new IgnoreChoicesListModel;
+ mIgnoreActionChoicesBox = new DropDown(mIgnoreActionChoicesModel);
+
+ for (int i = 0; i < COLUMNS_NR; i++)
+ {
+ mPlayerTableTitleModel->set(0, i,
+ new Label(gettext(table_titles[i])));
+ }
+
+ mPlayerTitleTable->setLinewiseSelection(true);
+
+ mPlayerScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mPlayerTable->setActionEventId(ACTION_TABLE);
+ mPlayerTable->setLinewiseSelection(true);
+ mPlayerTable->addActionListener(this);
+
+ gcn::Label *ignore_action_label = new Label(_("When ignoring:"));
+
+ mIgnoreActionChoicesBox->setActionEventId(ACTION_STRATEGY);
+ mIgnoreActionChoicesBox->addActionListener(this);
+
+ int ignore_strategy_index = 0; // safe default
+
+ if (player_relations.getPlayerIgnoreStrategy())
+ {
+ ignore_strategy_index = player_relations.getPlayerIgnoreStrategyIndex(
+ player_relations.getPlayerIgnoreStrategy()->mShortName);
+ if (ignore_strategy_index < 0)
+ ignore_strategy_index = 0;
+ }
+ mIgnoreActionChoicesBox->setSelected(ignore_strategy_index);
+ mIgnoreActionChoicesBox->adjustHeight();
+
+ mWhisperTabCheckBox->setActionEventId(ACTION_WHISPER_TAB);
+ mWhisperTabCheckBox->addActionListener(this);
+
+ mShowGenderCheckBox->setActionEventId(ACTION_SHOW_GENDER);
+ mShowGenderCheckBox->addActionListener(this);
+
+ mShowLevelCheckBox = new CheckBox(_("Show level"), mShowLevel);
+ mShowLevelCheckBox->setActionEventId(ACTION_SHOW_LEVEL);
+ mShowLevelCheckBox->addActionListener(this);
+
+ mShowOwnNameCheckBox = new CheckBox(_("Show own name"), mShowOwnName);
+ mShowOwnNameCheckBox->setActionEventId(ACTION_SHOW_OWN_NAME);
+ mShowOwnNameCheckBox->addActionListener(this);
+
+ mTargetDeadCheckBox = new CheckBox(_("Target dead players"), mTargetDead);
+ mTargetDeadCheckBox->setActionEventId(ACTION_TARGET_DEAD);
+ mTargetDeadCheckBox->addActionListener(this);
+
+ reset();
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mPlayerTitleTable, 5);
+ place(0, 1, mPlayerScrollArea, 5, 4).setPadding(2);
+ place(0, 5, mDeleteButton);
+ place(0, 6, mShowGenderCheckBox, 3).setPadding(2);
+ place(0, 7, mShowLevelCheckBox, 3).setPadding(2);
+ place(0, 8, mShowOwnNameCheckBox, 3).setPadding(2);
+ place(1, 5, mOldButton, 1);
+ place(3, 5, ignore_action_label);
+ place(3, 6, mIgnoreActionChoicesBox, 2).setPadding(2);
+ place(3, 7, mDefaultTrading);
+ place(3, 8, mDefaultWhisper);
+ place(0, 9, mWhisperTabCheckBox, 4).setPadding(4);
+ place(0, 10, mTargetDeadCheckBox, 4).setPadding(4);
+
+ player_relations.addListener(this);
+
+ setDimension(gcn::Rectangle(0, 0, 500, 350));
+}
+
+Setup_Players::~Setup_Players()
+{
+ player_relations.removeListener(this);
+ delete mIgnoreActionChoicesModel;
+ mIgnoreActionChoicesModel = 0;
+}
+
+
+void Setup_Players::reset()
+{
+ // We now have to search through the list of ignore choices to find the
+ // current selection. We could use an index into the table of config
+ // options in player_relations instead of strategies to sidestep this.
+ int selection = 0;
+ for (unsigned int i = 0;
+ i < player_relations.getPlayerIgnoreStrategies()->size();
+ ++i)
+ if ((*player_relations.getPlayerIgnoreStrategies())[i] ==
+ player_relations.getPlayerIgnoreStrategy())
+ {
+
+ selection = i;
+ break;
+ }
+
+ mIgnoreActionChoicesBox->setSelected(selection);
+}
+
+void Setup_Players::apply()
+{
+ player_relations.store();
+
+ unsigned int old_default_relations = player_relations.getDefault() &
+ ~(PlayerRelation::TRADE |
+ PlayerRelation::WHISPER);
+ player_relations.setDefault(old_default_relations
+ | (mDefaultTrading->isSelected() ?
+ PlayerRelation::TRADE : 0)
+ | (mDefaultWhisper->isSelected() ?
+ PlayerRelation::WHISPER : 0));
+ config.setValue("whispertab", mWhisperTab);
+ config.setValue("showlevel", mShowLevel);
+ config.setValue("showownname", mShowOwnName);
+ config.setValue("targetDeadPlayers", mTargetDead);
+ config.setValue("showgender", mShowGender);
+
+ if (actorSpriteManager)
+ actorSpriteManager->updatePlayerNames();
+
+ if (player_node)
+ player_node->setCheckNameSetting(true);
+}
+
+void Setup_Players::cancel()
+{
+ mWhisperTab = config.getBoolValue("whispertab");
+ mWhisperTabCheckBox->setSelected(mWhisperTab);
+ mShowGender = config.getBoolValue("showgender");
+ mShowGenderCheckBox->setSelected(mShowGender);
+ mShowLevel = config.getBoolValue("showlevel");
+ mShowLevelCheckBox->setSelected(mShowLevel);
+ mShowOwnName = config.getBoolValue("showownname");
+ mShowOwnNameCheckBox->setSelected(mShowOwnName);
+ mTargetDead = config.getBoolValue("targetDeadPlayers");
+ mTargetDeadCheckBox->setSelected(mTargetDead);
+}
+
+void Setup_Players::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == ACTION_TABLE)
+ {
+ // temporarily eliminate ourselves: we are fully aware of this change,
+ // so there is no need for asynchronous updates. (In fact, thouse
+ // might destroy the widet that triggered them, which would be rather
+ // embarrassing.)
+ player_relations.removeListener(this);
+
+ int row = mPlayerTable->getSelectedRow();
+ if (row >= 0)
+ mPlayerTableModel->updateModelInRow(row);
+
+ player_relations.addListener(this);
+
+ }
+ else if (event.getId() == ACTION_DELETE)
+ {
+ int player_index = mPlayerTable->getSelectedRow();
+
+ if (player_index < 0)
+ return;
+
+ std::string name = mPlayerTableModel->getPlayerAt(player_index);
+
+ player_relations.removePlayer(name);
+ }
+ else if (event.getId() == ACTION_OLD)
+ {
+ player_relations.load(true);
+ updateAll();
+ }
+ else if (event.getId() == ACTION_STRATEGY)
+ {
+ PlayerIgnoreStrategy *s =
+ (*player_relations.getPlayerIgnoreStrategies())[
+ mIgnoreActionChoicesBox->getSelected()];
+
+ player_relations.setPlayerIgnoreStrategy(s);
+ }
+ else if (event.getId() == ACTION_WHISPER_TAB)
+ {
+ mWhisperTab = mWhisperTabCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SHOW_GENDER)
+ {
+ mShowGender = mShowGenderCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SHOW_LEVEL)
+ {
+ mShowLevel = mShowLevelCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_SHOW_OWN_NAME)
+ {
+ mShowOwnName = mShowOwnNameCheckBox->isSelected();
+ }
+ else if (event.getId() == ACTION_TARGET_DEAD)
+ {
+ mTargetDead = mTargetDeadCheckBox->isSelected();
+ }
+}
+
+
+void Setup_Players::updatedPlayer(const std::string &name _UNUSED_)
+{
+ mPlayerTableModel->playerRelationsUpdated();
+ mDefaultTrading->setSelected(
+ player_relations.getDefault() & PlayerRelation::TRADE);
+ mDefaultWhisper->setSelected(
+ player_relations.getDefault() & PlayerRelation::WHISPER);
+ if (player_node)
+ player_node->updateName();
+}
+
+void Setup_Players::updateAll()
+{
+ PlayerTableModel *model = new PlayerTableModel();
+ mPlayerTable->setModel(model);
+ delete mPlayerTableModel;
+ mPlayerTableModel = model;
+ int ignore_strategy_index = 0; // safe default
+
+ if (player_relations.getPlayerIgnoreStrategy())
+ {
+ ignore_strategy_index = player_relations.getPlayerIgnoreStrategyIndex(
+ player_relations.getPlayerIgnoreStrategy()->mShortName);
+ if (ignore_strategy_index < 0)
+ ignore_strategy_index = 0;
+ }
+ mIgnoreActionChoicesBox->setSelected(ignore_strategy_index);
+ mIgnoreActionChoicesBox->adjustHeight();
+ reset();
+}
+void Setup_Players::externalUpdated()
+{
+ mDefaultTrading->setSelected(
+ player_relations.getDefault() & PlayerRelation::TRADE);
+ mDefaultWhisper->setSelected(
+ player_relations.getDefault() & PlayerRelation::WHISPER);
+} \ No newline at end of file
diff --git a/src/gui/setup_players.h b/src/gui/setup_players.h
new file mode 100644
index 000000000..21d3bb3e8
--- /dev/null
+++ b/src/gui/setup_players.h
@@ -0,0 +1,95 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_SETUP_PLAYERS_H
+#define GUI_SETUP_PLAYERS_H
+
+#include "guichanfwd.h"
+#include "playerrelations.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class GuiTable;
+class PlayerTableModel;
+class StaticTableModel;
+
+class Setup_Players : public SetupTab,
+ public gcn::ActionListener,
+ public PlayerRelationsListener
+{
+public:
+ Setup_Players();
+ virtual ~Setup_Players();
+
+ void apply();
+ void cancel();
+
+ void reset();
+
+ void action(const gcn::ActionEvent &event);
+
+ virtual void updatedPlayer(const std::string &name);
+
+ virtual void updateAll();
+
+ virtual void externalUpdated();
+
+private:
+ StaticTableModel *mPlayerTableTitleModel;
+ PlayerTableModel *mPlayerTableModel;
+ GuiTable *mPlayerTable;
+ GuiTable *mPlayerTitleTable;
+ gcn::ScrollArea *mPlayerScrollArea;
+
+ gcn::CheckBox *mDefaultTrading;
+ gcn::CheckBox *mDefaultWhisper;
+
+ gcn::Button *mDeleteButton;
+ gcn::Button *mOldButton;
+
+ gcn::ListModel *mIgnoreActionChoicesModel;
+ gcn::DropDown *mIgnoreActionChoicesBox;
+
+ bool mWhisperTab;
+ gcn::CheckBox *mWhisperTabCheckBox;
+
+ bool mShowGender;
+ gcn::CheckBox *mShowGenderCheckBox;
+
+ bool mShowLevel;
+ gcn::CheckBox *mShowLevelCheckBox;
+
+ bool mShowOwnName;
+ gcn::CheckBox *mShowOwnNameCheckBox;
+
+ bool mTargetDead;
+ gcn::CheckBox *mTargetDeadCheckBox;
+};
+
+#endif
diff --git a/src/gui/setup_theme.cpp b/src/gui/setup_theme.cpp
new file mode 100644
index 000000000..faaeeb00f
--- /dev/null
+++ b/src/gui/setup_theme.cpp
@@ -0,0 +1,239 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/setup_theme.h"
+
+#include "gui/gui.h"
+#include "gui/editdialog.h"
+#include "gui/okdialog.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/dropdown.h"
+
+#include "configuration.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "utils/gettext.h"
+
+#include "resources/resourcemanager.h"
+
+const char* ACTION_THEME = "theme";
+const char* ACTION_FONT = "font";
+const char* ACTION_BOLD_FONT = "bold font";
+const char* ACTION_PARTICLE_FONT = "particle font";
+const char* ACTION_HELP_FONT = "help font";
+
+class NamesModel : public gcn::ListModel
+{
+public:
+ NamesModel()
+ {
+ }
+
+ virtual ~NamesModel() { }
+
+ virtual int getNumberOfElements()
+ {
+ return static_cast<int>(mNames.size());
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return mNames[i];
+ }
+
+protected:
+ std::vector<std::string> mNames;
+};
+
+class ThemesModel : public NamesModel
+{
+public:
+ ThemesModel()
+ {
+ mNames.push_back("(default)");
+ Theme::fillSkinsList(mNames);
+ }
+
+ virtual ~ThemesModel()
+ { }
+};
+
+class FontsModel : public NamesModel
+{
+public:
+ FontsModel()
+ { Theme::fillFontsList(mNames); }
+
+ virtual ~FontsModel()
+ { }
+};
+
+Setup_Theme::Setup_Theme():
+ mTheme(config.getValue("theme", config.getValue("selectedSkin", ""))),
+ mFont(config.getStringValue("font")),
+ mBoldFont(config.getStringValue("boldFont")),
+ mParticleFont(config.getStringValue("particleFont")),
+ mHelpFont(config.getStringValue("helpFont"))
+{
+ setName(_("Theme"));
+
+ mThemeLabel = new Label(_("Gui theme"));
+ mFontLabel = new Label(_("Main Font"));
+ mBoldFontLabel = new Label(_("Bold font"));
+ mParticleFontLabel = new Label(_("Particle font"));
+ mHelpFontLabel = new Label(_("Help font"));
+ mThemesModel = new ThemesModel();
+ mFontsModel = new FontsModel();
+
+ mThemeDropDown = new DropDown(mThemesModel);
+ mThemeDropDown->setActionEventId(ACTION_THEME);
+ mThemeDropDown->addActionListener(this);
+
+ mFontDropDown = new DropDown(mFontsModel);
+ mFontDropDown->setActionEventId(ACTION_FONT);
+ mFontDropDown->addActionListener(this);
+
+ mBoldFontDropDown = new DropDown(mFontsModel);
+ mBoldFontDropDown->setActionEventId(ACTION_BOLD_FONT);
+ mBoldFontDropDown->addActionListener(this);
+
+ mParticleFontDropDown = new DropDown(mFontsModel);
+ mParticleFontDropDown->setActionEventId(ACTION_PARTICLE_FONT);
+ mParticleFontDropDown->addActionListener(this);
+
+ mHelpFontDropDown = new DropDown(mFontsModel);
+ mHelpFontDropDown->setActionEventId(ACTION_HELP_FONT);
+ mHelpFontDropDown->addActionListener(this);
+
+ std::string skin = Theme::getThemeName();
+ if (!skin.empty())
+ mThemeDropDown->setSelectedString(skin);
+ else
+ mThemeDropDown->setSelected(0);
+
+ mFontDropDown->setSelectedString(getFileName(
+ config.getStringValue("font")));
+ mBoldFontDropDown->setSelectedString(getFileName(
+ config.getStringValue("boldFont")));
+ mParticleFontDropDown->setSelectedString(getFileName(
+ config.getStringValue("particleFont")));
+ mHelpFontDropDown->setSelectedString(getFileName(
+ config.getStringValue("helpFont")));
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, mThemeLabel, 10);
+ place(0, 1, mThemeDropDown, 6);
+ place(0, 2, mFontLabel, 10);
+ place(0, 3, mFontDropDown, 6);
+ place(0, 4, mBoldFontLabel, 10);
+ place(0, 5, mBoldFontDropDown, 6);
+ place(0, 6, mParticleFontLabel, 10);
+ place(0, 7, mParticleFontDropDown, 6);
+ place(0, 8, mHelpFontLabel, 10);
+ place(0, 9, mHelpFontDropDown, 6);
+
+ place.getCell().matchColWidth(0, 0);
+ place = h.getPlacer(0, 1);
+
+ setDimension(gcn::Rectangle(0, 0, 365, 500));
+}
+
+Setup_Theme::~Setup_Theme()
+{
+ delete mThemesModel;
+ mThemesModel = 0;
+
+ delete mFontsModel;
+ mFontsModel = 0;
+}
+
+void Setup_Theme::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == ACTION_THEME)
+ {
+ if (mThemeDropDown->getSelected() == 0)
+ mTheme = "";
+ else
+ mTheme = mThemeDropDown->getSelectedString();
+ }
+ else if (event.getId() == ACTION_FONT)
+ {
+ mFont = mFontDropDown->getSelectedString();
+ }
+ else if (event.getId() == ACTION_BOLD_FONT)
+ {
+ mBoldFont = mBoldFontDropDown->getSelectedString();
+ }
+ else if (event.getId() == ACTION_PARTICLE_FONT)
+ {
+ mParticleFont = mParticleFontDropDown->getSelectedString();
+ }
+ else if (event.getId() == ACTION_HELP_FONT)
+ {
+ mHelpFont = mHelpFontDropDown->getSelectedString();
+ }
+}
+
+void Setup_Theme::cancel()
+{
+ mTheme = config.getValue("theme", config.getValue("selectedSkin", ""));
+ mFont = getFileName(config.getStringValue("font"));
+ mBoldFont = getFileName(config.getStringValue("boldFont"));
+ mParticleFont = getFileName(config.getStringValue("particleFont"));
+ mHelpFont = getFileName(config.getStringValue("helpFont"));
+}
+
+void Setup_Theme::apply()
+{
+ if (config.getValue("theme",
+ config.getValue("selectedSkin", "")) != mTheme)
+ {
+ new OkDialog(_("Theme Changed"),
+ _("Restart your client for the change to take effect."));
+ }
+ config.setValue("selectedSkin", "");
+ config.setValue("theme", mTheme);
+ if (config.getValue("font", "dejavusans.ttf") != mFont
+ || config.getValue("boldFont", "dejavusans-bold.ttf") != mBoldFont
+ || config.getValue("particleFont", "dejavusans.ttf") != mParticleFont
+ || config.getValue("helpFont", "dejavusansmono.ttf") != mHelpFont)
+ {
+ config.setValue("font", "fonts/" + getFileName(mFont));
+ config.setValue("boldFont", "fonts/" + getFileName(mBoldFont));
+ config.setValue("particleFont", "fonts/" + getFileName(mParticleFont));
+ config.setValue("helpFont", "fonts/" + getFileName(mHelpFont));
+ gui->updateFonts();
+ }
+}
diff --git a/src/gui/setup_theme.h b/src/gui/setup_theme.h
new file mode 100644
index 000000000..6b2c99999
--- /dev/null
+++ b/src/gui/setup_theme.h
@@ -0,0 +1,74 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_Setup_Theme_H
+#define GUI_Setup_Theme_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+
+class FontsModel;
+class EditDialog;
+class DropDown;
+class ThemesModel;
+
+class Setup_Theme : public SetupTab, public gcn::ActionListener
+{
+ public:
+ Setup_Theme();
+ ~Setup_Theme();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::Label *mThemeLabel;
+ DropDown *mThemeDropDown;
+ std::string mTheme;
+ ThemesModel *mThemesModel;
+ FontsModel *mFontsModel;
+
+ gcn::Label *mFontLabel;
+ DropDown *mFontDropDown;
+ std::string mFont;
+
+ gcn::Label *mBoldFontLabel;
+ DropDown *mBoldFontDropDown;
+ std::string mBoldFont;
+
+ gcn::Label *mParticleFontLabel;
+ DropDown *mParticleFontDropDown;
+ std::string mParticleFont;
+
+ gcn::Label *mHelpFontLabel;
+ DropDown *mHelpFontDropDown;
+ std::string mHelpFont;
+
+ EditDialog *mEditDialog;
+};
+
+#endif
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
new file mode 100644
index 000000000..9399756aa
--- /dev/null
+++ b/src/gui/setup_video.cpp
@@ -0,0 +1,819 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/setup_video.h"
+
+#include "configuration.h"
+#include "game.h"
+#include "graphics.h"
+#include "localplayer.h"
+#include "log.h"
+#include "main.h"
+#include "particle.h"
+
+#include "gui/gui.h"
+#include "gui/okdialog.h"
+#include "gui/textdialog.h"
+
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/slider.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/dropdown.h"
+
+#include "resources/image.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/key.hpp>
+#include <guichan/listmodel.hpp>
+
+#include <SDL.h>
+
+#include <string>
+#include <vector>
+
+extern Graphics *graphics;
+
+/**
+ * The list model for mode list.
+ *
+ * \ingroup Interface
+ */
+class ModeListModel : public gcn::ListModel
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ModeListModel();
+
+ /**
+ * Destructor.
+ */
+ virtual ~ModeListModel()
+ { }
+
+ /**
+ * Returns the number of elements in container.
+ */
+ int getNumberOfElements()
+ { return static_cast<int>(mVideoModes.size()); }
+
+ /**
+ * Returns element from container.
+ */
+ std::string getElementAt(int i)
+ { return mVideoModes[i]; }
+
+ /**
+ * Returns the index corresponding to the given video mode.
+ * E.g.: "800x600".
+ * or -1 if not found.
+ */
+ int getIndexOf(const std::string &widthXHeightMode);
+
+ private:
+ std::vector<std::string> mVideoModes;
+};
+
+ModeListModel::ModeListModel()
+{
+ /* Get available fullscreen/hardware modes */
+ SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
+
+ /* Check which modes are available */
+ if (modes == static_cast<SDL_Rect **>(0))
+ {
+ logger->log1("No modes available");
+ }
+ else if (modes == (SDL_Rect **)-1)
+ {
+ logger->log1("All resolutions available");
+ }
+ else
+ {
+ for (int i = 0; modes[i]; ++i)
+ {
+ const std::string modeString =
+ toString(static_cast<int>(modes[i]->w)) + "x"
+ + toString(static_cast<int>(modes[i]->h));
+ mVideoModes.push_back(modeString);
+ }
+ }
+ mVideoModes.push_back("custom");
+}
+
+int ModeListModel::getIndexOf(const std::string &widthXHeightMode)
+{
+ std::string currentMode = "";
+ for (int i = 0; i < getNumberOfElements(); i++)
+ {
+ currentMode = getElementAt(i);
+ if (currentMode == widthXHeightMode)
+ return i;
+ }
+ return -1;
+}
+
+const char *SIZE_NAME[6] =
+{
+ N_("Tiny (10)"),
+ N_("Small (11)"),
+ N_("Medium (12)"),
+ N_("Large (13)"),
+ N_("Big (14)"),
+ N_("Huge (15)"),
+};
+
+class FontSizeChoiceListModel : public gcn::ListModel
+{
+public:
+ virtual ~FontSizeChoiceListModel()
+ { }
+
+ virtual int getNumberOfElements()
+ { return 6; }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return SIZE_NAME[i];
+ }
+};
+
+const char *OPENGL_NAME[3] =
+{
+ N_("Software"),
+ N_("Fast OpenGL"),
+ N_("Safe OpenGL"),
+};
+
+class OpenGLListModel : public gcn::ListModel
+{
+public:
+ virtual ~OpenGLListModel()
+ { }
+
+ virtual int getNumberOfElements()
+ { return 3; }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return OPENGL_NAME[i];
+ }
+};
+
+static const char *speechModeToString(Being::Speech mode)
+{
+ switch (mode)
+ {
+ case Being::NO_SPEECH:
+ default:
+ return _("No text");
+ case Being::TEXT_OVERHEAD:
+ return _("Text");
+ case Being::NO_NAME_IN_BUBBLE:
+ return _("Bubbles, no names");
+ case Being::NAME_IN_BUBBLE:
+ return _("Bubbles with names");
+ }
+ return "";
+}
+
+const char *Setup_Video::overlayDetailToString(int detail)
+{
+ if (detail == -1)
+ detail = config.getIntValue("OverlayDetail");
+
+ switch (detail)
+ {
+ case 0:
+ return _("off");
+ case 1:
+ return _("low");
+ case 2:
+ return _("high");
+ default:
+ return "";
+ }
+ return "";
+}
+
+const char *Setup_Video::particleDetailToString(int detail)
+{
+ if (detail == -1)
+ detail = 3 - config.getIntValue("particleEmitterSkip");
+
+ switch (detail)
+ {
+ case 0:
+ return _("low");
+ case 1:
+ return _("medium");
+ case 2:
+ return _("high");
+ case 3:
+ return _("max");
+ default:
+ return "";
+ }
+ return "";
+}
+
+Setup_Video::Setup_Video():
+ mFullScreenEnabled(config.getBoolValue("screen")),
+ mOpenGLEnabled(config.getIntValue("opengl")),
+ mHwAccelEnabled(config.getBoolValue("hwaccel")),
+ mCustomCursorEnabled(config.getBoolValue("customcursor")),
+ mVisibleNamesEnabled(config.getBoolValue("visiblenames")),
+ mParticleEffectsEnabled(config.getBoolValue("particleeffects")),
+ mNPCLogEnabled(config.getBoolValue("logNpcInGui")),
+ mPickupChatEnabled(config.getBoolValue("showpickupchat")),
+ mPickupParticleEnabled(config.getBoolValue("showpickupparticle")),
+ mOpacity(config.getFloatValue("guialpha")),
+ mFps(config.getIntValue("fpslimit")),
+ mAltFps(config.getIntValue("altfpslimit")),
+ mHideShieldSprite(config.getBoolValue("hideShield")),
+ mLowTraffic(config.getBoolValue("lowTraffic")),
+ mSyncPlayerMove(config.getBoolValue("syncPlayerMove")),
+ mDrawHotKeys(config.getBoolValue("drawHotKeys")),
+ mDrawPath(config.getBoolValue("drawPath")),
+ mShowJob(serverConfig.getBoolValue("showJob")),
+ mAlphaCache(config.getBoolValue("alphaCache")),
+ mShowBackground(config.getBoolValue("showBackground")),
+ mSpeechMode(static_cast<Being::Speech>(
+ config.getIntValue("speech"))),
+ mModeListModel(new ModeListModel),
+ mModeList(new ListBox(mModeListModel)),
+ mFsCheckBox(new CheckBox(_("Full screen"), mFullScreenEnabled)),
+ mHwAccelCheckBox(new CheckBox(_("Hw acceleration"), mHwAccelEnabled)),
+ mCustomCursorCheckBox(new CheckBox(_("Custom cursor"),
+ mCustomCursorEnabled)),
+ mVisibleNamesCheckBox(new CheckBox(_("Visible names"),
+ mVisibleNamesEnabled)),
+ mParticleEffectsCheckBox(new CheckBox(_("Particle effects"),
+ mParticleEffectsEnabled)),
+ mNPCLogCheckBox(new CheckBox(_("Log NPC dialogue"), mNPCLogEnabled)),
+ mPickupNotifyLabel(new Label(_("Show pickup notification"))),
+ // TRANSLATORS: Refers to "Show own name"
+ mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)),
+ // TRANSLATORS: Refers to "Show own name"
+ mPickupParticleCheckBox(new CheckBox(_("as particle"),
+ mPickupParticleEnabled)),
+ mHideShieldSpriteCheckBox(new CheckBox(_("Hide shield sprite"),
+ mHideShieldSprite)),
+ mLowTrafficCheckBox(new CheckBox(_("Low traffic mode"),
+ mLowTraffic)),
+ mSyncPlayerMoveCheckBox(new CheckBox(_("Sync player move"),
+ mSyncPlayerMove)),
+ mDrawHotKeysCheckBox(new CheckBox(_("Draw hotkeys on map"),
+ mDrawHotKeys)),
+ mDrawPathCheckBox(new CheckBox(_("Draw path"), mDrawPath)),
+ mShowJobCheckBox(new CheckBox(_("Show job"), mShowJob)),
+ mAlphaCacheCheckBox(new CheckBox(_("Enable opacity cache"), mAlphaCache)),
+ mShowBackgroundCheckBox(new CheckBox(_("Show background"),
+ mShowBackground)),
+ mSpeechSlider(new Slider(0, 3)),
+ mSpeechLabel(new Label("")),
+ mAlphaSlider(new Slider(0.1, 1.0)),
+ mFpsCheckBox(new CheckBox(_("FPS limit:"))),
+ mFpsSlider(new Slider(2, 160)),
+ mFpsLabel(new Label),
+ mAltFpsSlider(new Slider(2, 160)),
+ mAltFpsLabel(new Label(_("Alt FPS limit: "))),
+ mOverlayDetail(config.getIntValue("OverlayDetail")),
+ mOverlayDetailSlider(new Slider(0, 2)),
+ mOverlayDetailField(new Label),
+ mParticleDetail(3 - config.getIntValue("particleEmitterSkip")),
+ mParticleDetailSlider(new Slider(0, 3)),
+ mParticleDetailField(new Label),
+ mFontSize(config.getIntValue("fontSize")),
+ mDialog(0)
+{
+ setName(_("Video"));
+
+ ScrollArea *scrollArea = new ScrollArea(mModeList);
+ scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ speechLabel = new Label(_("Overhead text"));
+ alphaLabel = new Label(_("Gui opacity"));
+ overlayDetailLabel = new Label(_("Ambient FX"));
+ particleDetailLabel = new Label(_("Particle detail"));
+ fontSizeLabel = new Label(_("Font size"));
+
+ mOpenGLListModel = new OpenGLListModel;
+ mOpenGLDropDown = new DropDown(mOpenGLListModel),
+ mOpenGLDropDown->setSelected(mOpenGLEnabled);
+
+ mFontSizeListModel = new FontSizeChoiceListModel;
+ mFontSizeDropDown = new DropDown(mFontSizeListModel);
+
+ mModeList->setEnabled(true);
+
+#ifndef USE_OPENGL
+ mOpenGLDropDown->setSelected(0);
+#endif
+
+ mAlphaSlider->setValue(mOpacity);
+ mAlphaSlider->setWidth(90);
+
+ mFpsLabel->setCaption(mFps > 0 ? toString(mFps) : _("None"));
+ mFpsLabel->setWidth(60);
+ mAltFpsLabel->setCaption(_("Alt FPS limit: ") + (mAltFps > 0
+ ? toString(mAltFps) : _("None")));
+ mAltFpsLabel->setWidth(150);
+ mFpsSlider->setValue(mFps);
+ mFpsSlider->setEnabled(mFps > 0);
+ mAltFpsSlider->setValue(mAltFps);
+ mAltFpsSlider->setEnabled(mAltFps > 0);
+ mFpsCheckBox->setSelected(mFps > 0);
+
+ // Pre-select the current video mode.
+ std::string videoMode = toString(graphics->getWidth()) + "x"
+ + toString(graphics->getHeight());
+ mModeList->setSelected(mModeListModel->getIndexOf(videoMode));
+
+ mModeList->setActionEventId("videomode");
+ mCustomCursorCheckBox->setActionEventId("customcursor");
+ mVisibleNamesCheckBox->setActionEventId("visiblenames");
+ mParticleEffectsCheckBox->setActionEventId("particleeffects");
+ mPickupChatCheckBox->setActionEventId("pickupchat");
+ mPickupParticleCheckBox->setActionEventId("pickupparticle");
+ mNPCLogCheckBox->setActionEventId("lognpc");
+ mAlphaSlider->setActionEventId("guialpha");
+ mFpsCheckBox->setActionEventId("fpslimitcheckbox");
+ mSpeechSlider->setActionEventId("speech");
+ mFpsSlider->setActionEventId("fpslimitslider");
+ mAltFpsSlider->setActionEventId("altfpslimitslider");
+ mOverlayDetailSlider->setActionEventId("overlaydetailslider");
+ mOverlayDetailField->setActionEventId("overlaydetailfield");
+ mParticleDetailSlider->setActionEventId("particledetailslider");
+ mParticleDetailField->setActionEventId("particledetailfield");
+ mHideShieldSpriteCheckBox->setActionEventId("hideshieldsprite1");
+ mLowTrafficCheckBox->setActionEventId("lowTraffic1");
+ mSyncPlayerMoveCheckBox->setActionEventId("syncPlayerMove1");
+ mDrawHotKeysCheckBox->setActionEventId("drawHotKeys");
+ mDrawPathCheckBox->setActionEventId("drawPath1");
+ mShowJobCheckBox->setActionEventId("showJob");
+ mAlphaCacheCheckBox->setActionEventId("alphaCache");
+
+ mModeList->addActionListener(this);
+ mCustomCursorCheckBox->addActionListener(this);
+ mVisibleNamesCheckBox->addActionListener(this);
+ mParticleEffectsCheckBox->addActionListener(this);
+ mPickupChatCheckBox->addActionListener(this);
+ mPickupParticleCheckBox->addActionListener(this);
+ mNPCLogCheckBox->addActionListener(this);
+ mAlphaSlider->addActionListener(this);
+ mFpsCheckBox->addActionListener(this);
+ mSpeechSlider->addActionListener(this);
+ mFpsSlider->addActionListener(this);
+ mAltFpsSlider->addActionListener(this);
+ mOverlayDetailSlider->addActionListener(this);
+ mOverlayDetailField->addKeyListener(this);
+ mParticleDetailSlider->addActionListener(this);
+ mParticleDetailField->addKeyListener(this);
+ mHideShieldSpriteCheckBox->addKeyListener(this);
+ mLowTrafficCheckBox->addKeyListener(this);
+ mSyncPlayerMoveCheckBox->addKeyListener(this);
+ mDrawHotKeysCheckBox->addKeyListener(this);
+ mDrawPathCheckBox->addKeyListener(this);
+ mShowJobCheckBox->addKeyListener(this);
+ mAlphaCacheCheckBox->addKeyListener(this);
+
+ mSpeechLabel->setCaption(speechModeToString(mSpeechMode));
+ mSpeechSlider->setValue(mSpeechMode);
+
+ mOverlayDetailField->setCaption(overlayDetailToString(mOverlayDetail));
+ mOverlayDetailSlider->setValue(mOverlayDetail);
+
+ mParticleDetailField->setCaption(particleDetailToString(mParticleDetail));
+ mParticleDetailSlider->setValue(mParticleDetail);
+
+ mFontSizeDropDown->setSelected(mFontSize - 10);
+ mFontSizeDropDown->adjustHeight();
+
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = h.getPlacer(0, 0);
+
+ place(0, 0, scrollArea, 1, 5).setPadding(2);
+ place(1, 0, mFsCheckBox, 2);
+ place(3, 0, mOpenGLDropDown, 1);
+
+ place(1, 1, mCustomCursorCheckBox, 3);
+ place(3, 1, mHwAccelCheckBox, 1);
+
+ place(1, 2, mVisibleNamesCheckBox, 3);
+
+ place(3, 2, mAlphaCacheCheckBox, 4);
+
+ place(1, 3, mParticleEffectsCheckBox, 2);
+
+ place(1, 4, mPickupNotifyLabel, 4);
+
+ place(1, 5, mPickupChatCheckBox, 1);
+ place(2, 5, mPickupParticleCheckBox, 2);
+
+ place(0, 6, fontSizeLabel, 3);
+ place(1, 6, mFontSizeDropDown, 1);
+
+ place(0, 7, mAlphaSlider);
+ place(1, 7, alphaLabel, 3);
+
+ place(0, 8, mFpsSlider);
+ place(1, 8, mFpsCheckBox).setPadding(3);
+ place(2, 8, mFpsLabel).setPadding(1);
+
+ place(0, 9, mAltFpsSlider);
+ place(1, 9, mAltFpsLabel).setPadding(3);
+
+ place(0, 10, mSpeechSlider);
+ place(1, 10, speechLabel);
+ place(2, 10, mSpeechLabel, 3).setPadding(2);
+
+ place(0, 11, mOverlayDetailSlider);
+ place(1, 11, overlayDetailLabel);
+ place(2, 11, mOverlayDetailField, 3).setPadding(2);
+
+ place(0, 12, mParticleDetailSlider);
+ place(1, 12, particleDetailLabel);
+ place(2, 12, mParticleDetailField, 3).setPadding(2);
+
+ place(3, 7, mHideShieldSpriteCheckBox);
+ place(3, 8, mLowTrafficCheckBox);
+ place(0, 13, mShowBackgroundCheckBox);
+ place(0, 14, mSyncPlayerMoveCheckBox);
+ place(0, 15, mDrawHotKeysCheckBox);
+ place(2, 13, mDrawPathCheckBox, 2);
+ place(2, 14, mShowJobCheckBox, 2);
+ place(2, 15, mNPCLogCheckBox, 2);
+
+ int width = 600;
+
+ if (config.getIntValue("screenwidth") >= 730)
+ width += 100;
+
+ setDimension(gcn::Rectangle(0, 0, width, 300));
+}
+
+Setup_Video::~Setup_Video()
+{
+ delete mModeListModel;
+ mModeListModel = 0;
+ delete mModeList;
+ mModeList = 0;
+ delete mFontSizeListModel;
+ mFontSizeListModel = 0;
+ delete mOpenGLListModel;
+ mOpenGLListModel = 0;
+ delete mDialog;
+ mDialog = 0;
+}
+
+void Setup_Video::apply()
+{
+ // Full screen changes
+ bool fullscreen = mFsCheckBox->isSelected();
+ if (fullscreen != config.getBoolValue("screen"))
+ {
+ /* The OpenGL test is only necessary on Windows, since switching
+ * to/from full screen works fine on Linux. On Windows we'd have to
+ * reinitialize the OpenGL state and reload all textures.
+ *
+ * See http://libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode
+ */
+
+#if defined(WIN32) || defined(__APPLE__)
+ // checks for opengl usage
+ if (!config.getIntValue("opengl"))
+ {
+#endif
+ if (!graphics->setFullscreen(fullscreen))
+ {
+ fullscreen = !fullscreen;
+ if (!graphics->setFullscreen(fullscreen))
+ {
+ std::stringstream errorMessage;
+ if (fullscreen)
+ {
+ errorMessage << _("Failed to switch to windowed mode "
+ "and restoration of old mode also "
+ "failed!") << std::endl;
+ }
+ else
+ {
+ errorMessage << _("Failed to switch to fullscreen mode"
+ " and restoration of old mode also "
+ "failed!") << std::endl;
+ }
+ logger->error(errorMessage.str());
+ }
+ }
+#if defined(WIN32) || defined(__APPLE__)
+ }
+ else
+ {
+ new OkDialog(_("Switching to Full Screen"),
+ _("Restart needed for changes to take effect."));
+ }
+#endif
+ config.setValue("screen", fullscreen);
+ }
+
+ // OpenGL change
+ if (mOpenGLDropDown->getSelected() != mOpenGLEnabled)
+ {
+ config.setValue("opengl", mOpenGLDropDown->getSelected());
+
+ // OpenGL can currently only be changed by restarting, notify user.
+ new OkDialog(_("Changing to OpenGL"),
+ _("Applying change to OpenGL requires restart."));
+ }
+
+ mFps = mFpsCheckBox->isSelected() ?
+ static_cast<int>(mFpsSlider->getValue()) : 0;
+
+ mAltFps = static_cast<int>(mAltFpsSlider->getValue());
+
+ mFpsSlider->setEnabled(mFps > 0);
+
+ mAltFpsSlider->setEnabled(mAltFps > 0);
+
+ config.setValue("hwaccel", mHwAccelCheckBox->isSelected());
+
+ // FPS change
+ config.setValue("fpslimit", mFps);
+ config.setValue("altfpslimit", mAltFps);
+
+ if (config.getIntValue("fontSize")
+ != static_cast<int>(mFontSizeDropDown->getSelected()) + 10)
+ {
+ config.setValue("fontSize", mFontSizeDropDown->getSelected() + 10);
+ gui->updateFonts();
+ }
+
+ config.setValue("hideShield", mHideShieldSpriteCheckBox->isSelected());
+ config.setValue("lowTraffic", mLowTrafficCheckBox->isSelected());
+ config.setValue("syncPlayerMove", mSyncPlayerMoveCheckBox->isSelected());
+ config.setValue("drawHotKeys", mDrawHotKeysCheckBox->isSelected());
+ config.setValue("drawPath", mDrawPathCheckBox->isSelected());
+ serverConfig.setValue("showJob", mShowJobCheckBox->isSelected());
+ config.setValue("alphaCache", mAlphaCacheCheckBox->isSelected());
+ config.setValue("showBackground", mShowBackgroundCheckBox->isSelected());
+
+ // We sync old and new values at apply time
+ mFullScreenEnabled = config.getBoolValue("screen");
+ mCustomCursorEnabled = config.getBoolValue("customcursor");
+ mVisibleNamesEnabled = config.getBoolValue("visiblenames");
+ mParticleEffectsEnabled = config.getBoolValue("particleeffects");
+ mNPCLogEnabled = config.getBoolValue("logNpcInGui");
+ mHideShieldSprite = config.getBoolValue("hideShield");
+ mLowTraffic = config.getBoolValue("lowTraffic");
+ mSyncPlayerMove = config.getBoolValue("syncPlayerMove");
+ mDrawHotKeys = config.getBoolValue("drawHotKeys");
+ mDrawPath = config.getBoolValue("drawPath");
+ mShowJob = serverConfig.getBoolValue("showJob");
+ mAlphaCache = config.getBoolValue("alphaCache");
+ mShowBackground = config.getBoolValue("showBackground");
+
+ mSpeechMode = static_cast<Being::Speech>(
+ config.getIntValue("speech"));
+ mOpacity = config.getFloatValue("guialpha");
+ mOverlayDetail = config.getIntValue("OverlayDetail");
+ mOpenGLEnabled = config.getIntValue("opengl");
+ mHwAccelEnabled = config.getBoolValue("hwaccel");
+ mPickupChatEnabled = config.getBoolValue("showpickupchat");
+ mPickupParticleEnabled = config.getBoolValue("showpickupparticle");
+}
+
+void Setup_Video::cancel()
+{
+ mFpsCheckBox->setSelected(mFps > 0);
+ mFsCheckBox->setSelected(mFullScreenEnabled);
+ mOpenGLDropDown->setSelected(mOpenGLEnabled);
+ mHwAccelCheckBox->setSelected(mHwAccelEnabled);
+ mCustomCursorCheckBox->setSelected(mCustomCursorEnabled);
+ mVisibleNamesCheckBox->setSelected(mVisibleNamesEnabled);
+ mParticleEffectsCheckBox->setSelected(mParticleEffectsEnabled);
+ mFpsSlider->setValue(mFps);
+ mFpsSlider->setEnabled(mFps > 0);
+ mAltFpsSlider->setValue(mAltFps);
+ mAltFpsSlider->setEnabled(mAltFps > 0);
+ mSpeechSlider->setValue(mSpeechMode);
+ mNPCLogCheckBox->setSelected(mNPCLogEnabled);
+ mHideShieldSpriteCheckBox->setSelected(mHideShieldSprite);
+ mLowTrafficCheckBox->setSelected(mLowTraffic);
+ mSyncPlayerMoveCheckBox->setSelected(mSyncPlayerMove);
+ mDrawHotKeysCheckBox->setSelected(mDrawHotKeys);
+ mDrawPathCheckBox->setSelected(mDrawPath);
+ mShowJobCheckBox->setSelected(mShowJob);
+ mAlphaCacheCheckBox->setSelected(mAlphaCache);
+ mShowBackgroundCheckBox->setSelected(mShowBackground);
+ mAlphaSlider->setValue(mOpacity);
+ mOverlayDetailSlider->setValue(mOverlayDetail);
+ mParticleDetailSlider->setValue(mParticleDetail);
+ mFpsLabel->setCaption(mFpsCheckBox->isSelected()
+ ? toString(mFps) : _("None"));
+ mAltFpsLabel->setCaption(_("Alt FPS limit: ") + toString(mAltFps));
+
+ config.setValue("screen", mFullScreenEnabled);
+
+ // Set back to the current video mode.
+ std::string videoMode = toString(graphics->getWidth()) + "x"
+ + toString(graphics->getHeight());
+ mModeList->setSelected(mModeListModel->getIndexOf(videoMode));
+ config.setValue("screenwidth", graphics->getWidth());
+ config.setValue("screenheight", graphics->getHeight());
+
+ config.setValue("customcursor", mCustomCursorEnabled);
+ config.setValue("visiblenames", mVisibleNamesEnabled);
+ config.setValue("particleeffects", mParticleEffectsEnabled);
+ config.setValue("speech", static_cast<int>(mSpeechMode));
+ config.setValue("logNpcInGui", mNPCLogEnabled);
+ config.setValue("hideShield", mHideShieldSprite);
+ config.setValue("lowTraffic", mLowTraffic);
+ config.setValue("syncPlayerMove", mSyncPlayerMove);
+ config.setValue("drawHotKeys", mDrawHotKeys);
+ config.setValue("drawPath", mDrawPath);
+ serverConfig.setValue("showJob", mShowJob);
+ config.setValue("alphaCache", mAlphaCache);
+ config.setValue("showBackground", mShowBackground);
+ config.setValue("guialpha", mOpacity);
+ Image::setEnableAlpha(mOpacity != 1.0f);
+ config.setValue("opengl", mOpenGLEnabled);
+ config.setValue("hwaccel", mHwAccelEnabled);
+ config.setValue("showpickupchat", mPickupChatEnabled);
+ config.setValue("showpickupparticle", mPickupParticleEnabled);
+}
+
+void Setup_Video::action(const gcn::ActionEvent &event)
+{
+ const std::string &id = event.getId();
+
+ if (id == "videomode")
+ {
+ std::string mode = mModeListModel->getElementAt(
+ mModeList->getSelected());
+
+ if (mode == "custom")
+ {
+ if (mDialog)
+ {
+ mode = mDialog->getText();
+ mDialog = 0;
+ }
+ else
+ {
+ mDialog = new TextDialog(
+ _("Custom resolution (example: 1024x768)"),
+ _("Enter new resolution: "));
+ mDialog->setActionEventId("videomode");
+ mDialog->addActionListener(this);
+ return;
+ }
+ }
+ const int width = atoi(mode.substr(0, mode.find("x")).c_str());
+ const int height = atoi(mode.substr(mode.find("x") + 1).c_str());
+ if (!width || !height)
+ return;
+
+ // TODO: Find out why the drawing area doesn't resize without a restart.
+ if (width != graphics->getWidth() || height != graphics->getHeight())
+ {
+ if (width < graphics->getWidth() || height < graphics->getHeight())
+ new OkDialog(_("Screen Resolution Changed"),
+ _("Restart your client for the change to take effect.")
+ + std::string("\n") +
+ _("Some windows may be moved to fit the lowered resolution."));
+ else
+ new OkDialog(_("Screen Resolution Changed"),
+ _("Restart your client for the change to take effect."));
+ }
+
+ config.setValue("screenwidth", width);
+ config.setValue("screenheight", height);
+ }
+ if (id == "~videomode")
+ {
+ mDialog = 0;
+ }
+ else if (id == "guialpha")
+ {
+ config.setValue("guialpha", mAlphaSlider->getValue());
+ Image::setEnableAlpha(config.getFloatValue("guialpha") != 1.0f);
+ }
+ else if (id == "customcursor")
+ {
+ config.setValue("customcursor", mCustomCursorCheckBox->isSelected());
+ }
+ else if (id == "visiblenames")
+ {
+ config.setValue("visiblenames", mVisibleNamesCheckBox->isSelected());
+ }
+ else if (id == "particleeffects")
+ {
+ config.setValue("particleeffects",
+ mParticleEffectsCheckBox->isSelected());
+ Particle::enabled = mParticleEffectsCheckBox->isSelected();
+
+ if (Game::instance())
+ {
+ new OkDialog(_("Particle Effect Settings Changed."),
+ _("Changes will take effect on map change."));
+ }
+ }
+ else if (id == "pickupchat")
+ {
+ config.setValue("showpickupchat", mPickupChatCheckBox->isSelected());
+ }
+ else if (id == "pickupparticle")
+ {
+ config.setValue("showpickupparticle",
+ mPickupParticleCheckBox->isSelected());
+ }
+ else if (id == "speech")
+ {
+ Being::Speech val = static_cast<Being::Speech>(
+ mSpeechSlider->getValue());
+ mSpeechLabel->setCaption(speechModeToString(val));
+ mSpeechSlider->setValue(val);
+ config.setValue("speech", (int)val);
+ }
+ else if (id == "lognpc")
+ {
+ config.setValue("logNpcInGui", mNPCLogCheckBox->isSelected());
+ }
+ else if (id == "overlaydetailslider")
+ {
+ int val = static_cast<int>(mOverlayDetailSlider->getValue());
+ mOverlayDetailField->setCaption(overlayDetailToString(val));
+ config.setValue("OverlayDetail", val);
+ }
+ else if (id == "particledetailslider")
+ {
+ int val = static_cast<int>(mParticleDetailSlider->getValue());
+ mParticleDetailField->setCaption(particleDetailToString(val));
+ config.setValue("particleEmitterSkip", 3 - val);
+ Particle::emitterSkip = 4 - val;
+ }
+ else if (id == "fpslimitcheckbox" || id == "fpslimitslider")
+ {
+ int fps = static_cast<int>(mFpsSlider->getValue());
+ if (id == "fpslimitcheckbox" && !mFpsSlider->isEnabled())
+ fps = 60;
+ else
+ fps = fps > 0 ? fps : 60;
+ mFps = mFpsCheckBox->isSelected() ? fps : 0;
+ const std::string text = mFps > 0 ? toString(mFps) : _("None");
+
+ mFpsLabel->setCaption(text);
+ mFpsSlider->setValue(mFps);
+ mFpsSlider->setEnabled(mFps > 0);
+ }
+ else if (id == "altfpslimitslider")
+ {
+ int fps = static_cast<int>(mAltFpsSlider->getValue());
+ fps = fps > 0 ? fps : static_cast<int>(mAltFpsSlider->getScaleStart());
+ mAltFps = fps;
+ const std::string text = mAltFps > 0 ? toString(mAltFps) : _("None");
+
+ mAltFpsLabel->setCaption(_("Alt FPS limit: ") + text);
+ mAltFpsSlider->setValue(mAltFps);
+ mAltFpsSlider->setEnabled(mAltFps > 0);
+ }
+}
+
+void Setup_Video::externalUpdated()
+{
+ mShowJob = serverConfig.getBoolValue("showJob");
+ mShowJobCheckBox->setSelected(mShowJob);
+} \ No newline at end of file
diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h
new file mode 100644
index 000000000..c9a72666a
--- /dev/null
+++ b/src/gui/setup_video.h
@@ -0,0 +1,136 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_SETUP_VIDEO_H
+#define GUI_SETUP_VIDEO_H
+
+#include "being.h"
+#include "guichanfwd.h"
+
+#include "gui/widgets/setuptab.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+
+class FontSizeChoiceListModel;
+class ModeListModel;
+class OpenGLListModel;
+class TextDialog;
+
+class Setup_Video : public SetupTab, public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ Setup_Video();
+ ~Setup_Video();
+
+ void apply();
+ void cancel();
+
+ void action(const gcn::ActionEvent &event);
+
+ static const char *overlayDetailToString(int detail = -1);
+
+ static const char *particleDetailToString(int detail = -1);
+
+ virtual void externalUpdated();
+
+ private:
+ bool mFullScreenEnabled;
+ int mOpenGLEnabled;
+ bool mHwAccelEnabled;
+ bool mCustomCursorEnabled;
+ bool mVisibleNamesEnabled;
+ bool mParticleEffectsEnabled;
+ bool mNPCLogEnabled;
+ bool mPickupChatEnabled;
+ bool mPickupParticleEnabled;
+ double mOpacity;
+ int mFps;
+ int mAltFps;
+ bool mHideShieldSprite;
+ bool mLowTraffic;
+ bool mSyncPlayerMove;
+ bool mDrawHotKeys;
+ bool mDrawPath;
+ bool mShowJob;
+ bool mAlphaCache;
+ bool mShowBackground;
+ Being::Speech mSpeechMode;
+
+ ModeListModel *mModeListModel;
+ FontSizeChoiceListModel *mFontSizeListModel;
+
+ OpenGLListModel *mOpenGLListModel;
+
+ gcn::Label *speechLabel;
+ gcn::Label *alphaLabel;
+ gcn::Label *scrollRadiusLabel;
+ gcn::Label *scrollLazinessLabel;
+ gcn::Label *overlayDetailLabel;
+ gcn::Label *particleDetailLabel;
+ gcn::Label *fontSizeLabel;
+
+ gcn::ListBox *mModeList;
+ gcn::CheckBox *mFsCheckBox;
+ gcn::DropDown *mOpenGLDropDown;
+ gcn::CheckBox *mHwAccelCheckBox;
+ gcn::CheckBox *mCustomCursorCheckBox;
+ gcn::CheckBox *mVisibleNamesCheckBox;
+ gcn::CheckBox *mParticleEffectsCheckBox;
+ gcn::CheckBox *mNPCLogCheckBox;
+
+ gcn::Label *mPickupNotifyLabel;
+ gcn::CheckBox *mPickupChatCheckBox;
+ gcn::CheckBox *mPickupParticleCheckBox;
+
+ gcn::CheckBox *mHideShieldSpriteCheckBox;
+ gcn::CheckBox *mLowTrafficCheckBox;
+ gcn::CheckBox *mSyncPlayerMoveCheckBox;
+ gcn::CheckBox *mDrawHotKeysCheckBox;
+ gcn::CheckBox *mDrawPathCheckBox;
+ gcn::CheckBox *mShowJobCheckBox;
+ gcn::CheckBox *mAlphaCacheCheckBox;
+ gcn::CheckBox *mShowBackgroundCheckBox;
+ gcn::Slider *mSpeechSlider;
+ gcn::Label *mSpeechLabel;
+ gcn::Slider *mAlphaSlider;
+ gcn::CheckBox *mFpsCheckBox;
+ gcn::Slider *mFpsSlider;
+ gcn::Label *mFpsLabel;
+// gcn::CheckBox *mAltFpsCheckBox;
+ gcn::Slider *mAltFpsSlider;
+ gcn::Label *mAltFpsLabel;
+
+ int mOverlayDetail;
+ gcn::Slider *mOverlayDetailSlider;
+ gcn::Label *mOverlayDetailField;
+
+ int mParticleDetail;
+ gcn::Slider *mParticleDetailSlider;
+ gcn::Label *mParticleDetailField;
+
+ int mFontSize;
+ gcn::DropDown *mFontSizeDropDown;
+ TextDialog *mDialog;
+};
+
+#endif
diff --git a/src/gui/shopwindow.cpp b/src/gui/shopwindow.cpp
new file mode 100644
index 000000000..410e79dbb
--- /dev/null
+++ b/src/gui/shopwindow.cpp
@@ -0,0 +1,788 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/shopwindow.h"
+
+#include "gui/buy.h"
+#include "gui/itemamount.h"
+#include "gui/sell.h"
+#include "gui/setup.h"
+#include "gui/trade.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/shopitems.h"
+#include "gui/widgets/shoplistbox.h"
+#include "gui/widgets/slider.h"
+#include "gui/widgets/tradetab.h"
+
+#include "actorspritemanager.h"
+#include "configuration.h"
+#include "confirmdialog.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "playerrelations.h"
+#include "shopitem.h"
+#include "sound.h"
+#include "units.h"
+
+#include "net/net.h"
+#include "net/chathandler.h"
+#include "net/npchandler.h"
+#include "net/tradehandler.h"
+
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <sstream>
+
+#include <sys/stat.h>
+
+extern std::string tradePartnerName;
+ShopWindow::DialogList ShopWindow::instances;
+
+ShopWindow::ShopWindow():
+ Window(_("Personal Shop")),
+ mSelectedItem(-1),
+ mAnnonceTime(0),
+ mLastRequestTimeList(0),
+ mLastRequestTimeItem(0),
+ mRandCounter(0),
+ mAcceptPlayer(""),
+ mTradeItem(0),
+ mTradeNick(""),
+ mTradeMoney(0)
+{
+ setWindowName("Personal Shop");
+ setResizable(true);
+ setCloseButton(true);
+ setMinWidth(260);
+ setMinHeight(230);
+ setDefaultSize(380, 300, ImageRect::CENTER);
+
+ mBuyShopItems = new ShopItems;
+ mSellShopItems = new ShopItems;
+
+ mAnnounceCounter[BUY] = 0;
+ mAnnounceCounter[SELL] = 0;
+
+ loadList();
+
+ mBuyShopItemList = new ShopListBox(mBuyShopItems, mBuyShopItems);
+ mSellShopItemList = new ShopListBox(mSellShopItems, mSellShopItems);
+
+ mBuyShopItemList->setPriceCheck(false);
+ mSellShopItemList->setPriceCheck(false);
+
+ mBuyScrollArea = new ScrollArea(mBuyShopItemList);
+ mBuyScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mSellScrollArea = new ScrollArea(mSellShopItemList);
+ mSellScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mCloseButton = new Button(_("Close"), "close", this);
+
+ mBuyShopItemList->addSelectionListener(this);
+ mSellShopItemList->addSelectionListener(this);
+
+ mBuyLabel = new Label(_("Buy items"));
+ mSellLabel = new Label(_("Sell items"));
+
+ mBuyAddButton = new Button(_("Add"), "add buy", this);
+ mBuyDeleteButton = new Button(_("Delete"), "delete buy", this);
+ mBuyAnnounceButton = new Button(_("Announce"), "announce buy", this);
+ mSellAddButton = new Button(_("Add"), "add sell", this);
+ mSellDeleteButton = new Button(_("Delete"), "delete sell", this);
+ mSellAnnounceButton = new Button(_("Announce"), "announce sell", this);
+ mAnnounceLinks = new CheckBox(_("Show links in announce"), false,
+ this, "link announce");
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mBuyLabel, 8).setPadding(3);
+ place(8, 0, mSellLabel, 8).setPadding(3);
+ place(0, 1, mBuyScrollArea, 8, 5).setPadding(3);
+ place(8, 1, mSellScrollArea, 8, 5).setPadding(3);
+ place(0, 6, mBuyAddButton);
+ place(1, 6, mBuyDeleteButton);
+ place(3, 6, mBuyAnnounceButton);
+ place(8, 6, mSellAddButton);
+ place(9, 6, mSellDeleteButton);
+ place(11, 6, mSellAnnounceButton);
+ place(0, 7, mAnnounceLinks, 8);
+ place(15, 7, mCloseButton);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+
+ center();
+ loadWindowState();
+
+ instances.push_back(this);
+ setVisible(false);
+
+ updateButtonsAndLabels();
+}
+
+ShopWindow::~ShopWindow()
+{
+ saveList();
+
+ delete mBuyShopItems;
+ mBuyShopItems = 0;
+
+ delete mSellShopItems;
+ mSellShopItems = 0;
+
+ instances.remove(this);
+}
+
+void ShopWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "close")
+ {
+ close();
+ return;
+ }
+
+ if (event.getId() == "yes")
+ {
+ startTrade();
+ }
+ else if (event.getId() == "no")
+ {
+ mTradeNick = "";
+ }
+ else if (event.getId() == "ignore")
+ {
+ player_relations.ignoreTrade(mTradeNick);
+ mTradeNick = "";
+ }
+ else if (event.getId() == "delete buy" && mBuyShopItemList
+ && mBuyShopItemList->getSelected() >= 0)
+ {
+ mBuyShopItems->erase(mBuyShopItemList->getSelected());
+ }
+ else if (event.getId() == "delete sell" && mSellShopItemList
+ && mSellShopItemList->getSelected() >= 0)
+ {
+ mSellShopItems->erase(mSellShopItemList->getSelected());
+ }
+ else if (event.getId() == "announce buy" && mBuyShopItems
+ && mBuyShopItems->getNumberOfElements() > 0)
+ {
+ announce(mBuyShopItems, BUY);
+ }
+ else if (event.getId() == "announce sell" && mSellShopItems
+ && mSellShopItems->getNumberOfElements() > 0)
+ {
+ announce(mSellShopItems, SELL);
+ }
+
+ if (mSelectedItem < 1)
+ return;
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *item = inv->findItem(mSelectedItem);
+ if (item)
+ {
+ if (event.getId() == "add buy")
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ShopBuyAdd,
+ this, item, sumAmount(item));
+ }
+ else if (event.getId() == "add sell")
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ShopSellAdd,
+ this, item, sumAmount(item));
+ }
+ }
+
+}
+
+void ShopWindow::startTrade()
+{
+ if (!actorSpriteManager || !tradeWindow)
+ return;
+
+ Being *being = actorSpriteManager->findBeingByName(
+ mTradeNick, Being::PLAYER);
+ tradeWindow->clear();
+ if (mTradeMoney)
+ {
+ tradeWindow->addAutoMoney(mTradeNick, mTradeMoney);
+ }
+ else
+ {
+ tradeWindow->addAutoItem(mTradeNick, mTradeItem,
+ mTradeItem->getQuantity());
+ }
+ Net::getTradeHandler()->request(being);
+ tradePartnerName = mTradeNick;
+ mTradeNick = "";
+}
+
+void ShopWindow::valueChanged(const gcn::SelectionEvent &event _UNUSED_)
+{
+ updateButtonsAndLabels();
+}
+
+void ShopWindow::updateButtonsAndLabels()
+{
+ mBuyAddButton->setEnabled(mSelectedItem != -1);
+ mSellAddButton->setEnabled(mSelectedItem != -1);
+ mBuyDeleteButton->setEnabled(
+ mBuyShopItemList->getSelected() != -1
+ && mBuyShopItems->getNumberOfElements() > 0);
+ mSellDeleteButton->setEnabled(
+ mSellShopItemList->getSelected() != -1
+ && mSellShopItems->getNumberOfElements() > 0);
+}
+
+void ShopWindow::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+}
+
+void ShopWindow::addBuyItem(Item *item, int amount, int price)
+{
+ if (!mBuyShopItems || !item)
+ return;
+ mBuyShopItems->addItemNoDup(item->getId(), amount, price);
+ updateButtonsAndLabels();
+}
+
+void ShopWindow::addSellItem(Item *item, int amount, int price)
+{
+ if (!mBuyShopItems || !item)
+ return;
+ mSellShopItems->addItemNoDup(item->getId(), amount, price);
+ updateButtonsAndLabels();
+}
+
+void ShopWindow::loadList()
+{
+ if (!mBuyShopItems || !mSellShopItems)
+ return;
+
+ std::ifstream shopFile;
+ struct stat statbuf;
+
+ mBuyShopItems->clear();
+ mSellShopItems->clear();
+
+ std::string shopListName = Client::getServerConfigDirectory()
+ + "/shoplist.txt";
+
+ if (!stat(shopListName.c_str(), &statbuf) && S_ISREG(statbuf.st_mode))
+ {
+ shopFile.open(shopListName.c_str(), std::ios::in);
+ char line[101];
+ while (shopFile.getline(line, 100))
+ {
+ std::string buf;
+ std::string str = line;
+ if (!str.empty())
+ {
+ std::vector<int> tokens;
+
+ std::stringstream ss(str);
+
+ while (ss >> buf)
+ tokens.push_back(atoi(buf.c_str()));
+
+ if (tokens.size() == 5 && tokens[0])
+ {
+ if (tokens[1] && tokens[2] && mBuyShopItems)
+ {
+ mBuyShopItems->addItem(
+ tokens[0], tokens[1], tokens[2]);
+ }
+ if (tokens[3] && tokens[4] && mSellShopItems)
+ {
+ mSellShopItems->addItem(
+ tokens[0], tokens[3], tokens[4]);
+ }
+ }
+ }
+ }
+ shopFile.close();
+ }
+}
+
+void ShopWindow::saveList()
+{
+ if (!mBuyShopItems || !mSellShopItems)
+ return;
+
+ std::ofstream shopFile;
+ std::string shopListName = Client::getServerConfigDirectory()
+ + "/shoplist.txt";
+ std::list<int> procesList;
+ std::map<int, ShopItem*> mapItems;
+
+ shopFile.open(shopListName.c_str(), std::ios::binary);
+ if (!shopFile.is_open())
+ {
+ logger->log1("Unable to open shoplist.txt for writing");
+ return;
+ }
+
+ std::vector<ShopItem*> items = mBuyShopItems->items();
+ std::vector<ShopItem*>::iterator it;
+ for (it = items.begin(); it != items.end(); it++)
+ {
+ ShopItem *item = *(it);
+ if (item)
+ mapItems[item->getId()] = item;
+ }
+
+ items = mSellShopItems->items();
+ for (it = items.begin(); it != items.end(); it++)
+ {
+ ShopItem *sellItem = *(it);
+ ShopItem *buyItem = mapItems[sellItem->getId()];
+
+ shopFile << sellItem->getId();
+ if (buyItem)
+ {
+ shopFile << strprintf(" %d %d ", buyItem->getQuantity(),
+ buyItem->getPrice());
+ mapItems.erase(sellItem->getId());
+ }
+ else
+ {
+ shopFile << " 0 0 ";
+ }
+
+ if (sellItem)
+ {
+ shopFile << strprintf("%d %d", sellItem->getQuantity(),
+ sellItem->getPrice()) << std::endl;
+ }
+ }
+
+ std::map<int, ShopItem*>::iterator mapIt;
+ for (mapIt = mapItems.begin(); mapIt != mapItems.end(); mapIt++)
+ {
+ ShopItem *buyItem = (*mapIt).second;
+ if (buyItem)
+ {
+ shopFile << buyItem->getId();
+ shopFile << strprintf(" %d %d ", buyItem->getQuantity(),
+ buyItem->getPrice());
+ shopFile << "0 0" << std::endl;
+ }
+ }
+
+ shopFile.close();
+}
+
+void ShopWindow::announce(ShopItems *list, int mode)
+{
+ if (!list)
+ return;
+
+ std::string data = "\302\202";
+ if (mode == BUY)
+ data += "Buy ";
+ else
+ data += "Sell ";
+
+ if (mAnnonceTime && (mAnnonceTime + (2 * 60) > cur_time
+ || mAnnonceTime > cur_time))
+ {
+ return;
+ }
+
+ mAnnonceTime = cur_time;
+ if (mBuyAnnounceButton)
+ mBuyAnnounceButton->setEnabled(false);
+ if (mSellAnnounceButton)
+ mSellAnnounceButton->setEnabled(false);
+
+ std::vector<ShopItem*> items = list->items();
+ std::vector<ShopItem*>::iterator it;
+
+ for (it = items.begin(); it != items.end(); it++)
+ {
+ ShopItem *item = *(it);
+ if (item->getQuantity() > 1)
+ {
+ if (mAnnounceLinks->isSelected())
+ {
+ data += strprintf("[@@%d|%s@@] (%dGP) %d, ", item->getId(),
+ item->getInfo().getName().c_str(),
+ item->getPrice(), item->getQuantity());
+ }
+ else
+ {
+ data += strprintf("%s (%dGP) %d, ",
+ item->getInfo().getName().c_str(),
+ item->getPrice(), item->getQuantity());
+ }
+ }
+ else
+ {
+ if (mAnnounceLinks->isSelected())
+ {
+ data += strprintf("[@@%d|%s@@] (%dGP), ", item->getId(),
+ item->getInfo().getName().c_str(),
+ item->getPrice());
+ }
+ else
+ {
+ data += strprintf("%s (%dGP), ",
+ item->getInfo().getName().c_str(),
+ item->getPrice());
+ }
+ }
+ }
+
+ Net::getChatHandler()->talk(data);
+}
+
+void ShopWindow::giveList(const std::string &nick, int mode)
+{
+ if (!checkFloodCounter(mLastRequestTimeList))
+ return;
+
+ std::string data = "\302\202";
+
+ ShopItems *list;
+ if (mode == BUY)
+ {
+ list = mBuyShopItems;
+ data += "S1";
+ }
+ else
+ {
+ list = mSellShopItems;
+ data += "B1";
+ }
+ if (!list)
+ return;
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ std::vector<ShopItem*> items = list->items();
+ std::vector<ShopItem*>::iterator it;
+
+ for (it = items.begin(); it != items.end(); it++)
+ {
+ ShopItem *item = *(it);
+ if (!item)
+ continue;
+
+ if (mode == SELL)
+ {
+ Item *item2 = inv->findItem(item->getId());
+ if (item2)
+ {
+ int amount = item->getQuantity();
+ if (item2->getQuantity() < amount)
+ amount = item2->getQuantity();
+
+ if (amount)
+ {
+ data += strprintf("%s%s%s",
+ encodeStr(item->getId(), 2).c_str(),
+ encodeStr(item->getPrice(), 4).c_str(),
+ encodeStr(amount, 3).c_str());
+ }
+ }
+ }
+ else
+ {
+ int amount = item->getQuantity();
+ if (item->getPrice() * amount > PlayerInfo::getAttribute(MONEY))
+ amount = PlayerInfo::getAttribute(MONEY) / item->getPrice();
+
+ if (amount > 0)
+ {
+ data += strprintf("%s%s%s",
+ encodeStr(item->getId(), 2).c_str(),
+ encodeStr(item->getPrice(), 4).c_str(),
+ encodeStr(amount, 3).c_str());
+ }
+ }
+ }
+ sendMessage(nick, data, true);
+}
+
+void ShopWindow::sendMessage(const std::string &nick,
+ std::string data, bool random)
+{
+ if (!chatWindow)
+ return;
+
+ if (random)
+ {
+ mRandCounter ++;
+ if (mRandCounter > 200)
+ mRandCounter = 0;
+ data += encodeStr(mRandCounter, 2);
+ }
+
+ if (config.getBoolValue("hideShopMessages"))
+ Net::getChatHandler()->privateMessage(nick, data);
+ else if (chatWindow)
+ chatWindow->whisper(nick, data, BY_PLAYER);
+//here was true
+}
+
+void ShopWindow::showList(const std::string &nick, std::string data)
+{
+ BuyDialog *buyDialog = 0;
+ SellDialog *sellDialog = 0;
+ if (data.find("B1") == 0)
+ {
+ data = data.substr(2);
+ buyDialog = new BuyDialog(nick);
+ }
+ else if (data.find("S1") == 0)
+ {
+ data = data.substr(2);
+ sellDialog = new SellDialog(nick);
+ }
+ else
+ {
+ return;
+ }
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ if (buyDialog)
+ buyDialog->setMoney(PlayerInfo::getAttribute(MONEY));
+ if (sellDialog)
+ sellDialog->setMoney(PlayerInfo::getAttribute(MONEY));
+
+ for (unsigned f = 0; f < data.length(); f += 9)
+ {
+ if (f + 9 > data.length())
+ break;
+
+ int id = decodeStr(data.substr(f, 2));
+ int price = decodeStr(data.substr(f + 2, 4));
+ int amount = decodeStr(data.substr(f + 6, 3));
+ if (buyDialog && amount > 0)
+ buyDialog->addItem(id, amount, price);
+ if (sellDialog)
+ {
+ Item *item = inv->findItem(id);
+ if (item)
+ {
+ if (item->getQuantity() < amount)
+ amount = item->getQuantity();
+ if (amount > 0)
+ sellDialog->addItem(id, amount, price);
+ else
+ sellDialog->addItem(id, -1, price);
+ }
+ }
+ }
+}
+
+void ShopWindow::processRequest(std::string nick, std::string data, int mode)
+{
+ if (!player_node || !mTradeNick.empty() || PlayerInfo::isTrading()
+ || !actorSpriteManager
+ || !actorSpriteManager->findBeingByName(nick, Being::PLAYER))
+ {
+ return;
+ }
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ unsigned long idx = 0;
+
+ idx = data.find(" ");
+ if (idx == std::string::npos)
+ return;
+
+ if (!checkFloodCounter(mLastRequestTimeItem))
+ return;
+
+ if (!mTradeNick.empty())
+ {
+ sendMessage(nick, "error: player busy ", true);
+ return;
+ }
+
+ data = data.substr(idx + 1);
+
+ std::string part1;
+ std::string part2;
+ std::string part3;
+ std::stringstream ss(data);
+ std::string msg;
+ int id;
+ int price;
+ int amount;
+
+ if (!(ss >> part1))
+ return;
+
+ if (!(ss >> part2))
+ return;
+
+ if (!(ss >> part3))
+ return;
+
+ id = atoi(part1.c_str());
+ price = atoi(part2.c_str());
+ amount = atoi(part3.c_str());
+
+ delete mTradeItem;
+ mTradeItem = new ShopItem(-1, id, amount, price);
+
+ if (mode == BUY)
+ {
+ Item *item2 = inv->findItem(mTradeItem->getId());
+ if (!item2 || item2->getQuantity() < amount
+ || !findShopItem(mTradeItem, SELL))
+ {
+ sendMessage(nick, "error: Cant sell this item ", true);
+ return;
+ }
+ msg = "buy";
+ mTradeMoney = 0;
+ }
+ else
+ {
+ if (!findShopItem(mTradeItem, BUY))
+ {
+ sendMessage(nick, "error: Cant buy this item ", true);
+ return;
+ }
+ msg = "sell";
+ mTradeMoney = mTradeItem->getPrice() * mTradeItem->getQuantity();
+ }
+
+ mTradeNick = nick;
+
+ if (config.getBoolValue("autoShop"))
+ {
+ sound.playGuiSfx("system/newmessage.ogg");
+ startTrade();
+ }
+ else
+ {
+ ConfirmDialog *confirmDlg = new ConfirmDialog(_("Request for Trade"),
+ strprintf(_("%s wants to %s %s do you "
+ "accept?"), nick.c_str(), msg.c_str(),
+ mTradeItem->getInfo().getName().c_str()), true);
+ confirmDlg->addActionListener(this);
+ }
+}
+
+void ShopWindow::updateTimes()
+{
+ if (mAnnonceTime + (2 * 60) < cur_time
+ || mAnnonceTime > cur_time)
+ {
+ mBuyAnnounceButton->setEnabled(true);
+ mSellAnnounceButton->setEnabled(true);
+ }
+}
+
+bool ShopWindow::checkFloodCounter(int &counterTime)
+{
+ if (!counterTime || counterTime > cur_time)
+ counterTime = cur_time;
+ else if (counterTime + 10 > cur_time)
+ return false;
+
+ counterTime = cur_time;
+ return true;
+}
+
+bool ShopWindow::findShopItem(ShopItem *shopItem, int mode)
+{
+ if (!shopItem)
+ return false;
+
+ std::vector<ShopItem*> items;
+ std::vector<ShopItem*>::iterator it;
+ if (mode == SELL)
+ {
+ if (!mSellShopItems)
+ return false;
+ items = mSellShopItems->items();
+ }
+ else
+ {
+ if (!mBuyShopItems)
+ return false;
+ items = mBuyShopItems->items();
+ }
+
+ for (it = items.begin(); it != items.end(); it++)
+ {
+ ShopItem *item = *(it);
+ if (!item)
+ continue;
+
+ if (item && item->getId() == shopItem->getId()
+ && item->getPrice() == shopItem->getPrice()
+ && item->getQuantity() >= shopItem->getQuantity())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+int ShopWindow::sumAmount(Item *shopItem)
+{
+ if (!player_node || !shopItem)
+ return 0;
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return 0;
+ int sum = 0;
+
+ for (unsigned f = 0; f < inv->getSize(); f ++)
+ {
+ Item *item = inv->getItem(f);
+ if (item && item->getId() == shopItem->getId())
+ sum += item->getQuantity();
+ }
+ return sum;
+}
diff --git a/src/gui/shopwindow.h b/src/gui/shopwindow.h
new file mode 100644
index 000000000..6b31b67a5
--- /dev/null
+++ b/src/gui/shopwindow.h
@@ -0,0 +1,173 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SHOP_H
+#define SHOP_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class CheckBox;
+class Item;
+class ListBox;
+class ShopItem;
+class ShopItems;
+class ShopListBox;
+
+/**
+ * The buy dialog.
+ *
+ * \ingroup Interface
+ */
+class ShopWindow : public Window, public gcn::ActionListener,
+ public gcn::SelectionListener
+{
+ public:
+
+ enum ShopMode
+ {
+ BUY = 0,
+ SELL = 1
+ };
+
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ ShopWindow();
+
+ /**
+ * Destructor
+ */
+ ~ShopWindow();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Updates the labels according to the selected item.
+ */
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ /**
+ * Updates the state of buttons and labels.
+ */
+ void updateButtonsAndLabels();
+
+ /**
+ * Sets the visibility of this window.
+ */
+ void setVisible(bool visible);
+
+ /**
+ * Returns true if any instances exist.
+ */
+ static bool isActive()
+ { return instances.size() > 0; }
+
+ void setItemSelected(int id)
+ { mSelectedItem = id; updateButtonsAndLabels(); }
+
+ void addBuyItem(Item *item, int amount, int price);
+
+ void addSellItem(Item *item, int amount, int price);
+
+ void loadList();
+
+ void saveList();
+
+ void announce(ShopItems *list, int mode);
+
+ void giveList(const std::string &nick, int mode);
+
+ void setAcceptPlayer(std::string name)
+ { mAcceptPlayer = name; }
+
+ const std::string &getAcceptPlayer()
+ { return mAcceptPlayer; }
+
+ void sendMessage(const std::string &nick, std::string data,
+ bool random = false);
+
+ void showList(const std::string &nick, std::string data);
+
+ void processRequest(std::string nick, std::string data, int mode);
+
+ bool findShopItem(ShopItem *shopItem, int mode);
+
+ int sumAmount(Item *shopItem);
+
+ void updateTimes();
+
+ bool checkFloodCounter(int &counterTime);
+
+ private:
+ void startTrade();
+
+ typedef std::list<ShopWindow*> DialogList;
+ static DialogList instances;
+
+ gcn::Button *mCloseButton;
+ ShopListBox *mBuyShopItemList;
+ ShopListBox *mSellShopItemList;
+ gcn::ScrollArea *mBuyScrollArea;
+ gcn::ScrollArea *mSellScrollArea;
+ gcn::Label *mBuyLabel;
+ gcn::Label *mSellLabel;
+ gcn::Button *mBuyAddButton;
+ gcn::Button *mBuyDeleteButton;
+ gcn::Button *mBuyAnnounceButton;
+ gcn::Button *mSellAddButton;
+ gcn::Button *mSellDeleteButton;
+ gcn::Button *mSellAnnounceButton;
+ gcn::CheckBox *mAnnounceLinks;
+
+ ShopItems *mBuyShopItems;
+ ShopItems *mSellShopItems;
+
+ int mSelectedItem;
+ int mAnnonceTime;
+ int mLastRequestTimeList;
+ int mLastRequestTimeItem;
+ int mRandCounter;
+ std::string mAcceptPlayer;
+ ShopItem *mTradeItem;
+ std::string mTradeNick;
+ int mTradeMoney;
+ int mAnnounceCounter[2];
+};
+
+extern ShopWindow *shopWindow;
+
+#endif
diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp
new file mode 100644
index 000000000..c3aa8454f
--- /dev/null
+++ b/src/gui/shortcutwindow.cpp
@@ -0,0 +1,152 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/shortcutwindow.h"
+
+#include "configuration.h"
+
+#include "gui/setup.h"
+
+#include "gui/widgets/layout.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/shortcutcontainer.h"
+#include "gui/widgets/tab.h"
+#include "gui/widgets/tabbedarea.h"
+
+static const int SCROLL_PADDING = 0;
+
+int ShortcutWindow::mBoxesWidth = 0;
+
+class ShortcutTab : public Tab
+{
+ public:
+ ShortcutTab(std::string name, ShortcutContainer* content)
+ {
+ setCaption(name);
+ mContent = content;
+ }
+
+ ShortcutContainer* mContent;
+};
+
+ShortcutWindow::ShortcutWindow(const std::string &title,
+ ShortcutContainer *content,
+ int width, int height)
+{
+ setWindowName(title);
+ // no title presented, title bar is padding so window can be moved.
+ gcn::Window::setTitleBarHeight(gcn::Window::getPadding());
+ setShowTitle(false);
+ setResizable(true);
+ setDefaultVisible(false);
+ setSaveVisible(true);
+
+ setupWindow->registerWindowForReset(this);
+
+ mTabs = 0;
+ mItems = content;
+
+ const int border = SCROLL_PADDING * 2 + getPadding() * 2;
+ setMinWidth(mItems->getBoxWidth() + border);
+ setMinHeight(mItems->getBoxHeight() + border);
+ setMaxWidth(mItems->getBoxWidth() * mItems->getMaxItems() + border);
+ setMaxHeight(mItems->getBoxHeight() * mItems->getMaxItems() + border);
+
+ if (width == 0)
+ width = mItems->getBoxWidth() + border;
+ if (height == 0)
+ height = (mItems->getBoxHeight() * mItems->getMaxItems()) + border;
+
+ setDefaultSize(width, height, ImageRect::LOWER_RIGHT);
+
+ mBoxesWidth += mItems->getBoxWidth() + border;
+
+ mScrollArea = new ScrollArea(mItems);
+ mScrollArea->setPosition(SCROLL_PADDING, SCROLL_PADDING);
+ mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mScrollArea->setOpaque(false);
+
+ place(0, 0, mScrollArea, 5, 5).setPadding(0);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+ layout.setMargin(0);
+
+ loadWindowState();
+}
+
+ShortcutWindow::ShortcutWindow(const std::string &title, int width, int height)
+{
+ setWindowName(title);
+ // no title presented, title bar is padding so window can be moved.
+ gcn::Window::setTitleBarHeight(gcn::Window::getPadding());
+ setShowTitle(false);
+ setResizable(true);
+ setDefaultVisible(false);
+ setSaveVisible(true);
+
+ setupWindow->registerWindowForReset(this);
+
+ mTabs = new TabbedArea;
+
+ mItems = 0;
+
+ const int border = SCROLL_PADDING * 2 + getPadding() * 2;
+
+ if (width && height)
+ setDefaultSize(width, height, ImageRect::LOWER_RIGHT);
+
+ setMinWidth(32 + border);
+ setMinHeight(32 + border);
+
+ place(0, 0, mTabs, 5, 5);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+ layout.setMargin(0);
+
+ loadWindowState();
+}
+
+ShortcutWindow::~ShortcutWindow()
+{
+ delete mTabs;
+ mTabs = 0;
+ delete mItems;
+ mItems = 0;
+}
+
+void ShortcutWindow::addTab(std::string name, ShortcutContainer *content)
+{
+ ScrollArea *scroll = new ScrollArea(content);
+ scroll->setPosition(SCROLL_PADDING, SCROLL_PADDING);
+ scroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ scroll->setOpaque(false);
+ Tab *tab = new ShortcutTab(name, content);
+ mTabs->addTab(tab, scroll);
+}
+
+int ShortcutWindow::getTabIndex()
+{
+ if (!mTabs)
+ return 0;
+ return mTabs->getSelectedTabIndex();
+}
diff --git a/src/gui/shortcutwindow.h b/src/gui/shortcutwindow.h
new file mode 100644
index 000000000..bd3dedb61
--- /dev/null
+++ b/src/gui/shortcutwindow.h
@@ -0,0 +1,71 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SHORTCUTWINDOW_H
+#define SHORTCUTWINDOW_H
+
+#include "gui/widgets/window.h"
+
+class ScrollArea;
+class ShortcutContainer;
+class TabbedArea;
+
+/**
+ * A window around a ShortcutContainer.
+ *
+ * \ingroup Interface
+ */
+class ShortcutWindow : public Window
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ShortcutWindow(const std::string &title, ShortcutContainer *content,
+ int width = 0, int height = 0);
+
+ ShortcutWindow(const std::string &title,
+ int width = 0, int height = 0);
+
+ /**
+ * Destructor.
+ */
+ ~ShortcutWindow();
+
+ void addTab(std::string name, ShortcutContainer *content);
+
+ int getTabIndex();
+
+ private:
+ ShortcutWindow();
+ ShortcutContainer *mItems;
+
+ ScrollArea *mScrollArea;
+ TabbedArea *mTabs;
+
+ static int mBoxesWidth;
+};
+
+extern ShortcutWindow *itemShortcutWindow;
+extern ShortcutWindow *emoteShortcutWindow;
+extern ShortcutWindow *dropShortcutWindow;
+
+#endif
diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp
new file mode 100644
index 000000000..04222d6f5
--- /dev/null
+++ b/src/gui/skilldialog.cpp
@@ -0,0 +1,523 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/skilldialog.h"
+
+#include "log.h"
+#include "playerinfo.h"
+#include "configuration.h"
+
+#include "gui/setup.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/container.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/progressbar.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/tab.h"
+#include "gui/widgets/tabbedarea.h"
+#include "gui/widgets/windowcontainer.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <guichan/font.hpp>
+
+#include <set>
+#include <string>
+
+class SkillModel;
+class SkillEntry;
+
+
+struct SkillInfo
+{
+ unsigned short id;
+ std::string name;
+ Image *icon;
+ bool modifiable;
+ bool visible;
+ SkillModel *model;
+
+ std::string skillLevel;
+ int skillLevelWidth;
+
+ std::string skillExp;
+ float progress;
+ gcn::Color color;
+
+ SkillInfo() :
+ id(0), name(""), icon(0), modifiable(false), visible(false),
+ model(0), skillLevel(""), skillLevelWidth(0), skillExp(""),
+ progress(0.0f)
+ {
+ }
+
+ ~SkillInfo()
+ {
+ if (icon)
+ icon->decRef();
+ }
+
+ void setIcon(const std::string &iconPath)
+ {
+ ResourceManager *res = ResourceManager::getInstance();
+ if (!iconPath.empty())
+ {
+ icon = res->getImage(iconPath);
+ }
+
+ if (!icon)
+ {
+ icon = Theme::getImageFromTheme(
+ paths.getStringValue("unknownItemFile"));
+ }
+ }
+
+ void update();
+
+ void draw(Graphics *graphics, int y, int width);
+};
+
+
+typedef std::vector<SkillInfo*> SkillList;
+
+class SkillModel : public gcn::ListModel
+{
+public:
+ int getNumberOfElements()
+ { return static_cast<int>(mVisibleSkills.size()); }
+
+ SkillInfo *getSkillAt(int i) const
+ { return mVisibleSkills.at(i); }
+
+ std::string getElementAt(int i)
+ {
+ if (getSkillAt(i))
+ return getSkillAt(i)->name;
+ else
+ return "";
+ }
+
+ void updateVisibilities();
+
+ void addSkill(SkillInfo *info)
+ { mSkills.push_back(info); }
+
+private:
+ SkillList mSkills;
+ SkillList mVisibleSkills;
+};
+
+class SkillListBox : public ListBox
+{
+public:
+ SkillListBox(SkillModel *model):
+ ListBox(model)
+ {}
+
+ SkillInfo *getSelectedInfo()
+ {
+ const int selected = getSelected();
+ if (!mListModel || selected < 0
+ || selected > mListModel->getNumberOfElements())
+ {
+ return 0;
+ }
+
+ return static_cast<SkillModel*>(mListModel)->getSkillAt(selected);
+ }
+
+ void draw(gcn::Graphics *gcnGraphics)
+ {
+ if (!mListModel)
+ return;
+
+ SkillModel* model = static_cast<SkillModel*>(mListModel);
+
+ updateAlpha();
+
+ Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
+
+ graphics->setColor(Theme::getThemeColor(Theme::HIGHLIGHT,
+ static_cast<int>(mAlpha * 255.0f)));
+ graphics->setFont(getFont());
+
+ // Draw filled rectangle around the selected list element
+ if (mSelected >= 0)
+ {
+ graphics->fillRectangle(gcn::Rectangle(0, getRowHeight()
+ * mSelected, getWidth(), getRowHeight()));
+ }
+
+ // Draw the list elements
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ for (int i = 0, y = 1;
+ i < model->getNumberOfElements();
+ ++i, y += getRowHeight())
+ {
+ SkillInfo *e = model->getSkillAt(i);
+
+ if (e)
+ e->draw(graphics, y, getWidth());
+ }
+ }
+
+ unsigned int getRowHeight() const
+ { return 34; }
+};
+
+class SkillTab : public Tab
+{
+public:
+ SkillTab(const std::string &name, SkillListBox *listBox):
+ mListBox(listBox)
+ {
+ setCaption(name);
+ }
+
+ ~SkillTab()
+ {
+ delete mListBox;
+ mListBox = 0;
+ }
+
+ SkillInfo *getSelectedInfo()
+ {
+ if (mListBox)
+ return mListBox->getSelectedInfo();
+ else
+ return 0;
+ }
+
+private:
+ SkillListBox *mListBox;
+};
+
+SkillDialog::SkillDialog():
+ Window(_("Skills"))
+{
+ setWindowName("Skills");
+ setCloseButton(true);
+ setResizable(true);
+ setSaveVisible(true);
+ setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425);
+ setupWindow->registerWindowForReset(this);
+
+ mTabs = new TabbedArea();
+ mPointsLabel = new Label("0");
+ mIncreaseButton = new Button(_("Up"), "inc", this);
+
+ place(0, 0, mTabs, 5, 5);
+ place(0, 5, mPointsLabel, 4);
+ place(4, 5, mIncreaseButton);
+
+ setLocationRelativeTo(getParent());
+ loadWindowState();
+}
+
+SkillDialog::~SkillDialog()
+{
+ // Clear gui
+ loadSkills("");
+}
+
+void SkillDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "inc")
+ {
+ SkillTab *tab = static_cast<SkillTab*>(mTabs->getSelectedTab());
+ if (tab)
+ {
+ if (SkillInfo *info = tab->getSelectedInfo())
+ Net::getPlayerHandler()->increaseSkill(info->id);
+ }
+ }
+ else if (event.getId() == "close")
+ {
+ setVisible(false);
+ }
+}
+
+std::string SkillDialog::update(int id)
+{
+ SkillMap::iterator i = mSkills.find(id);
+
+ if (i != mSkills.end())
+ {
+ SkillInfo *info = i->second;
+ if (info)
+ {
+ info->update();
+ return info->name;
+ }
+ }
+
+ return std::string();
+}
+
+void SkillDialog::update()
+{
+ mPointsLabel->setCaption(strprintf(_("Skill points available: %d"),
+ PlayerInfo::getAttribute(SKILL_POINTS)));
+ mPointsLabel->adjustSize();
+
+ for (SkillMap::iterator it = mSkills.begin(); it != mSkills.end(); it++)
+ {
+ if ((*it).second && (*it).second->modifiable)
+ (*it).second->update();
+ }
+}
+
+void SkillDialog::loadSkills(const std::string &file)
+{
+ // Fixes issues with removing tabs
+ if (mTabs->getSelectedTabIndex() != -1)
+ {
+ mTabs->setSelectedTab(static_cast<unsigned int>(0));
+
+ while (mTabs->getSelectedTabIndex() != -1)
+ {
+ gcn::Tab *tab = mTabs->getSelectedTab();
+ if (tab)
+ mTabs->removeTabWithIndex(mTabs->getSelectedTabIndex());
+ delete tab;
+ }
+ }
+
+ delete_all(mSkills);
+ mSkills.clear();
+
+ if (file.length() == 0)
+ return;
+
+ XML::Document doc(file);
+ xmlNodePtr root = doc.rootNode();
+
+ int setCount = 0;
+ std::string setName;
+ ScrollArea *scroll;
+ SkillListBox *listbox;
+ SkillTab *tab;
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "skills"))
+ {
+ logger->log("Error loading skills file: %s", file.c_str());
+
+ if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+ SkillModel *model = new SkillModel();
+ SkillInfo *skill = new SkillInfo;
+ skill->id = 1;
+ skill->name = "basic";
+ skill->setIcon("");
+ skill->modifiable = true;
+ skill->visible = true;
+ skill->model = model;
+ skill->update();
+
+ model->addSkill(skill);
+ mSkills[1] = skill;
+
+ model->updateVisibilities();
+
+ listbox = new SkillListBox(model);
+ scroll = new ScrollArea(listbox);
+ scroll->setOpaque(false);
+ scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
+ scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS);
+
+ tab = new SkillTab("Skills", listbox);
+
+ mTabs->addTab(tab, scroll);
+
+ update();
+ }
+ return;
+ }
+
+ for_each_xml_child_node(set, root)
+ {
+ if (xmlStrEqual(set->name, BAD_CAST "set"))
+ {
+ setCount++;
+ setName = XML::getProperty(set, "name",
+ strprintf(_("Skill Set %d"), setCount));
+
+ SkillModel *model = new SkillModel();
+
+ for_each_xml_child_node(node, set)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "skill"))
+ {
+ int id = atoi(XML::getProperty(node, "id", "-1").c_str());
+ std::string name = XML::getProperty(node, "name",
+ strprintf(_("Skill %d"), id));
+ std::string icon = XML::getProperty(node, "icon", "");
+
+ SkillInfo *skill = new SkillInfo;
+ skill->id = static_cast<short unsigned>(id);
+ skill->name = name;
+ skill->setIcon(icon);
+ skill->modifiable = false;
+ skill->visible = false;
+ skill->model = model;
+ skill->update();
+
+ model->addSkill(skill);
+
+ mSkills[id] = skill;
+ }
+ }
+
+ model->updateVisibilities();
+
+ // possible leak listbox, scroll
+ listbox = new SkillListBox(model);
+ scroll = new ScrollArea(listbox);
+ scroll->setOpaque(false);
+ scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
+ scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS);
+
+ tab = new SkillTab(setName, listbox);
+
+ mTabs->addTab(tab, scroll);
+ }
+ }
+ update();
+}
+
+void SkillDialog::setModifiable(int id, bool modifiable)
+{
+ SkillMap::iterator it = mSkills.find(id);
+
+ if (it != mSkills.end())
+ {
+ SkillInfo *info = it->second;
+ if (info)
+ {
+ info->modifiable = modifiable;
+ info->update();
+ }
+ }
+}
+
+void SkillModel::updateVisibilities()
+{
+ mVisibleSkills.clear();
+
+ for (SkillList::iterator it = mSkills.begin(); it != mSkills.end(); it++)
+ {
+ if ((*it)->visible)
+ mVisibleSkills.push_back((*it));
+ }
+}
+
+void SkillInfo::update()
+{
+ int baseLevel = PlayerInfo::getStatBase(id);
+ int effLevel = PlayerInfo::getStatEffective(id);
+
+ std::pair<int, int> exp = PlayerInfo::getStatExperience(id);
+
+ if (!modifiable && baseLevel == 0 && effLevel == 0 && exp.second == 0)
+ {
+ if (visible)
+ {
+ visible = false;
+ if (model)
+ model->updateVisibilities();
+ }
+
+ return;
+ }
+
+ bool updateVisibility = !visible;
+ visible = true;
+
+ if (effLevel != baseLevel)
+ {
+ skillLevel = strprintf(_("Lvl: %d (%+d)"), baseLevel,
+ effLevel - baseLevel);
+ }
+ else
+ {
+ if (baseLevel == 0)
+ skillLevel.clear();
+ else
+ skillLevel = strprintf(_("Lvl: %d"), baseLevel);
+ }
+ skillLevelWidth = -1;
+
+ if (exp.second)
+ {
+ skillExp = strprintf("%d / %d", exp.first, exp.second);
+ progress = static_cast<float>(exp.first)
+ / static_cast<float>(exp.second);
+ }
+ else
+ {
+ skillExp.clear();
+ progress = 0.0f;
+ }
+
+ color = Theme::getProgressColor(Theme::PROG_EXP, progress);
+
+ if (updateVisibility && model)
+ model->updateVisibilities();
+}
+
+void SkillInfo::draw(Graphics *graphics, int y, int width)
+{
+ graphics->drawImage(icon, 1, y);
+ graphics->drawText(name, 34, y);
+
+ if (skillLevelWidth < 0)
+ {
+ // Add one for padding
+ skillLevelWidth = graphics->getFont()->getWidth(skillLevel) + 1;
+ }
+
+ graphics->drawText(skillLevel, width - skillLevelWidth, y);
+
+ if (!skillExp.empty())
+ {
+ gcn::Rectangle rect(33, y + 15, width - 33, 17);
+
+ ProgressBar::render(graphics, rect, color, progress, skillExp);
+ }
+}
+
+SkillInfo* SkillDialog::getSkill(int id)
+{
+ return mSkills[id];
+}
diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h
new file mode 100644
index 000000000..4ba4afe8e
--- /dev/null
+++ b/src/gui/skilldialog.h
@@ -0,0 +1,91 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SKILLDIALOG_H
+#define SKILLDIALOG_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+//include "resources/image.h"
+//include "resources/resourcemanager.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <map>
+
+class Button;
+//class Image;
+class Label;
+class ScrollArea;
+class Tab;
+class TabbedArea;
+
+struct SkillInfo;
+
+/**
+ * The skill dialog.
+ *
+ * \ingroup Interface
+ */
+class SkillDialog : public Window, public gcn::ActionListener
+{
+ public:
+ SkillDialog();
+
+ ~SkillDialog();
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Update the given skill's display
+ */
+ std::string update(int id);
+
+ /**
+ * Update other parts of the display
+ */
+ void update();
+
+ void loadSkills(const std::string &file);
+
+ void setModifiable(int id, bool modifiable);
+
+ SkillInfo* getSkill(int id);
+
+ bool hasSkills()
+ { return !mSkills.empty(); }
+
+ private:
+ typedef std::map<int, SkillInfo*> SkillMap;
+ SkillMap mSkills;
+ TabbedArea *mTabs;
+ Label *mPointsLabel;
+ Button *mIncreaseButton;
+};
+
+extern SkillDialog *skillDialog;
+
+#endif
diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp
new file mode 100644
index 000000000..7e86e4d9c
--- /dev/null
+++ b/src/gui/socialwindow.cpp
@@ -0,0 +1,1306 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/socialwindow.h"
+
+#include "actorspritemanager.h"
+#include "guild.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "log.h"
+#include "map.h"
+#include "party.h"
+
+#include "gui/confirmdialog.h"
+#include "gui/okdialog.h"
+#include "gui/outfitwindow.h"
+#include "gui/setup.h"
+#include "gui/textdialog.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/avatarlistbox.h"
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/container.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/linkhandler.h"
+#include "gui/widgets/popup.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/tab.h"
+#include "gui/widgets/tabbedarea.h"
+
+#include "net/net.h"
+#include "net/guildhandler.h"
+#include "net/partyhandler.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+class SocialTab : public Tab
+{
+protected:
+ friend class SocialWindow;
+
+ SocialTab():
+ mInviteDialog(0),
+ mConfirmDialog(0),
+ mScroll(0),
+ mList(0)
+ {}
+
+ virtual ~SocialTab()
+ {
+ // Cleanup dialogs
+ if (mInviteDialog)
+ {
+ mInviteDialog->close();
+ mInviteDialog->scheduleDelete();
+ mInviteDialog = NULL;
+ }
+
+ if (mConfirmDialog)
+ {
+ mConfirmDialog->close();
+ mConfirmDialog->scheduleDelete();
+ mConfirmDialog = NULL;
+ }
+ }
+
+ virtual void invite() = 0;
+
+ virtual void leave() = 0;
+
+ virtual void updateList() = 0;
+
+ virtual void updateAvatar(std::string name) = 0;
+
+ virtual void resetDamage(std::string name) = 0;
+
+ virtual void selectIndex(unsigned num _UNUSED_)
+ { }
+
+ TextDialog *mInviteDialog;
+ ConfirmDialog *mConfirmDialog;
+ ScrollArea *mScroll;
+ AvatarListBox *mList;
+};
+
+class GuildTab : public SocialTab, public gcn::ActionListener
+{
+public:
+ GuildTab(Guild *guild):
+ mGuild(guild)
+ {
+ setCaption(_("Guild"));
+
+ setTabColor(&Theme::getThemeColor(Theme::GUILD_SOCIAL_TAB));
+
+ mList = new AvatarListBox(guild);
+ mScroll = new ScrollArea(mList);
+
+ mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO);
+ mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
+ }
+
+ ~GuildTab()
+ {
+ delete mList;
+ mList = 0;
+ delete mScroll;
+ mScroll = 0;
+ }
+
+ void action(const gcn::ActionEvent &event)
+ {
+ if (event.getId() == "do invite")
+ {
+ std::string name = mInviteDialog->getText();
+ Net::getGuildHandler()->invite(mGuild->getId(), name);
+
+ if (localChatTab)
+ {
+ localChatTab->chatLog(strprintf(
+ _("Invited user %s to guild %s."),
+ name.c_str(), mGuild->getName().c_str()), BY_SERVER);
+ }
+ mInviteDialog = 0;
+ }
+ else if (event.getId() == "~do invite")
+ {
+ mInviteDialog = 0;
+ }
+ else if (event.getId() == "yes")
+ {
+ Net::getGuildHandler()->leave(mGuild->getId());
+ if (localChatTab)
+ {
+ localChatTab->chatLog(strprintf(_("Guild %s quit requested."),
+ mGuild->getName().c_str()), BY_SERVER);
+ }
+ mConfirmDialog = 0;
+ }
+ else if (event.getId() == "~yes")
+ {
+ mConfirmDialog = 0;
+ }
+ }
+
+ void updateList()
+ {
+ }
+
+ void updateAvatar(std::string name _UNUSED_)
+ {
+ }
+
+ void resetDamage(std::string name _UNUSED_)
+ {
+ }
+
+protected:
+ void invite()
+ {
+ // TODO - Give feedback on whether the invite succeeded
+ mInviteDialog = new TextDialog(_("Member Invite to Guild"),
+ strprintf(_("Who would you like to invite to guild %s?"),
+ mGuild->getName().c_str()),
+ socialWindow);
+ mInviteDialog->setActionEventId("do invite");
+ mInviteDialog->addActionListener(this);
+ }
+
+ void leave()
+ {
+ mConfirmDialog = new ConfirmDialog(_("Leave Guild?"),
+ strprintf(_("Are you sure you want to leave guild %s?"),
+ mGuild->getName().c_str()),
+ socialWindow);
+
+ mConfirmDialog->addActionListener(this);
+ }
+
+private:
+ Guild *mGuild;
+};
+
+class PartyTab : public SocialTab, public gcn::ActionListener
+{
+public:
+ PartyTab(Party *party):
+ mParty(party)
+ {
+ setCaption(_("Party"));
+
+ setTabColor(&Theme::getThemeColor(Theme::PARTY_SOCIAL_TAB));
+
+ mList = new AvatarListBox(party);
+ mScroll = new ScrollArea(mList);
+
+ mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO);
+ mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
+ }
+
+ ~PartyTab()
+ {
+ delete mList;
+ mList = 0;
+ delete mScroll;
+ mScroll = 0;
+ }
+
+ void action(const gcn::ActionEvent &event)
+ {
+ if (event.getId() == "do invite")
+ {
+ std::string name = mInviteDialog->getText();
+ Net::getPartyHandler()->invite(name);
+
+ if (localChatTab)
+ {
+ localChatTab->chatLog(strprintf(_("Invited user %s to party."),
+ name.c_str()), BY_SERVER);
+ }
+ mInviteDialog = NULL;
+ }
+ else if (event.getId() == "~do invite")
+ {
+ mInviteDialog = NULL;
+ }
+ else if (event.getId() == "yes")
+ {
+ Net::getPartyHandler()->leave();
+ if (localChatTab)
+ {
+ localChatTab->chatLog(strprintf(_("Party %s quit requested."),
+ mParty->getName().c_str()), BY_SERVER);
+ }
+ mConfirmDialog = NULL;
+ }
+ else if (event.getId() == "~yes")
+ {
+ mConfirmDialog = NULL;
+ }
+ }
+
+ void updateList()
+ {
+ }
+
+ void updateAvatar(std::string name _UNUSED_)
+ {
+ }
+
+ void resetDamage(std::string name _UNUSED_)
+ {
+ }
+
+protected:
+ void invite()
+ {
+ // TODO - Give feedback on whether the invite succeeded
+ mInviteDialog = new TextDialog(_("Member Invite to Party"),
+ strprintf(_("Who would you like to invite to party %s?"),
+ mParty->getName().c_str()),
+ socialWindow);
+ mInviteDialog->setActionEventId("do invite");
+ mInviteDialog->addActionListener(this);
+ }
+
+ void leave()
+ {
+ mConfirmDialog = new ConfirmDialog(_("Leave Party?"),
+ strprintf(_("Are you sure you want to leave party %s?"),
+ mParty->getName().c_str()),
+ socialWindow);
+
+ mConfirmDialog->addActionListener(this);
+ }
+
+private:
+ Party *mParty;
+};
+
+/*class BuddyTab : public SocialTab
+{
+ // TODO?
+};*/
+
+
+class BeingsListModal : public AvatarListModel
+{
+public:
+ BeingsListModal()
+ {
+ }
+
+ ~BeingsListModal()
+ {
+ delete_all(mMembers);
+ mMembers.clear();
+ }
+
+ std::vector<Avatar*> *getMembers()
+ {
+ return &mMembers;
+ }
+
+ virtual Avatar *getAvatarAt(int index)
+ {
+ return mMembers[index];
+ }
+
+ int getNumberOfElements()
+ {
+ return static_cast<int>(mMembers.size());
+ }
+
+ std::vector<Avatar*> mMembers;
+};
+
+class PlayersTab : public SocialTab
+{
+public:
+ PlayersTab(std::string name)
+ {
+ mBeings = new BeingsListModal();
+
+ mList = new AvatarListBox(mBeings);
+ mScroll = new ScrollArea(mList);
+
+ mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO);
+ mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
+
+// mBeings->getMembers().push_back(new Avatar("test"));
+ updateList();
+ setCaption(name);
+ }
+
+ ~PlayersTab()
+ {
+ delete mList;
+ mList = 0;
+ delete mScroll;
+ mScroll = 0;
+ delete mBeings;
+ mBeings = 0;
+ }
+
+ void updateList()
+ {
+ getPlayersAvatars();
+ }
+
+ void updateAvatar(std::string name)
+ {
+ if (!actorSpriteManager)
+ return;
+
+ Avatar *avatar = findAvatarbyName(name);
+ if (!avatar)
+ return;
+ if (Party::getParty(1))
+ {
+ PartyMember *pm = Party::getParty(1)->getMember(name);
+ if (pm && pm->getMaxHp() > 0)
+ {
+ avatar->setMaxHp(pm->getMaxHp());
+ avatar->setHp(pm->getHp());
+ }
+ }
+ Being* being = actorSpriteManager->findBeingByName(
+ name, Being::PLAYER);
+ if (being)
+ {
+ avatar->setDamageHp(being->getDamageTaken());
+ avatar->setLevel(being->getLevel());
+ avatar->setGender(being->getGender());
+ avatar->setIp(being->getIp());
+ }
+ }
+
+ void resetDamage(std::string name)
+ {
+ if (!actorSpriteManager)
+ return;
+
+ Avatar *avatar = findAvatarbyName(name);
+ if (!avatar)
+ return;
+ avatar->setDamageHp(0);
+ Being* being = actorSpriteManager->findBeingByName(
+ name, Being::PLAYER);
+
+ if (being)
+ being->setDamageTaken(0);
+ }
+
+ Avatar* findAvatarbyName(std::string name)
+ {
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+ if (!avatars)
+ return 0;
+
+ Avatar *ava = 0;
+ std::vector<Avatar*>::iterator i = avatars->begin();
+ while (i != avatars->end())
+ {
+ ava = (*i);
+ if (ava && ava->getName() == name)
+ return ava;
+ ++i;
+ }
+ ava = new Avatar(name);
+ ava->setOnline(true);
+ avatars->push_back(ava);
+ return ava;
+ }
+
+ void getPlayersAvatars()
+ {
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+ if (!avatars)
+ return;
+
+ if (actorSpriteManager)
+ {
+// std::list<Being*> beings = actorSpriteManager->getAll();
+ std::vector<std::string> names;
+ actorSpriteManager->getPlayerNames(names, false);
+
+ std::vector<Avatar*>::iterator ai = avatars->begin();
+ while (ai != avatars->end())
+ {
+ bool finded = false;
+ Avatar *ava = (*ai);
+ if (!ava)
+ break;
+
+ std::vector<std::string>::iterator i = names.begin();
+ while (i != names.end())
+ {
+ if (ava->getName() == (*i) && (*i) != "")
+ {
+ finded = true;
+ break;
+ }
+ ++i;
+ }
+
+ if (!finded)
+ avatars->erase(ai);
+ else
+ ++ai;
+ }
+
+ std::vector<std::string>::iterator i = names.begin();
+
+ while (i != names.end())
+ {
+ if ((*i) != "")
+ updateAvatar(*i);
+ ++i;
+ }
+ }
+ }
+
+protected:
+ void invite()
+ {
+ }
+
+ void leave()
+ {
+ }
+
+private:
+ BeingsListModal *mBeings;
+};
+
+
+class NavigationTab : public SocialTab
+{
+
+public:
+ NavigationTab()
+ {
+ mBeings = new BeingsListModal();
+
+ mList = new AvatarListBox(mBeings);
+ mScroll = new ScrollArea(mList);
+
+ mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO);
+ mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
+
+ setCaption(_("Nav"));
+
+ }
+
+ ~NavigationTab()
+ {
+ delete mList;
+ mList = 0;
+ delete mScroll;
+ mScroll = 0;
+ delete mBeings;
+ mBeings = 0;
+ }
+
+ void invite()
+ {
+ }
+
+ void leave()
+ {
+ }
+
+ void updateList()
+ {
+ if (!socialWindow || !player_node)
+ return;
+
+ Map* map = socialWindow->getMap();
+ if (!map)
+ return;
+
+ if (socialWindow->getProcessedPortals())
+ return;
+
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+ std::list<MapItem*> portals = map->getPortals();
+
+ std::list<MapItem*>::iterator i = portals.begin();
+ SpecialLayer *specialLayer = map->getSpecialLayer();
+
+ avatars->clear();
+
+ int idx = 0;
+ while (i != portals.end())
+ {
+ MapItem *portal = *i;
+ if (!portal)
+ continue;
+
+ int x = portal->getX();
+ int y = portal->getY();
+
+ std::string name = strprintf("%s [%d %d]",
+ portal->getComment().c_str(), x, y);
+
+ Avatar *ava = new Avatar(name);
+ if (player_node)
+ ava->setOnline(player_node->isReachable(x, y, 0));
+ else
+ ava->setOnline(false);
+ ava->setLevel(-1);
+ ava->setType(portal->getType());
+ ava->setX(x);
+ ava->setY(y);
+ avatars->push_back(ava);
+
+ if (config.getBoolValue("drawHotKeys") && idx < 80 && outfitWindow)
+ {
+ Being *being = actorSpriteManager->findPortalByTile(x, y);
+ if (being)
+ {
+ being->setName(keyboard.getKeyShortString(
+ outfitWindow->keyName(idx)));
+ }
+
+ if (specialLayer)
+ {
+ portal = specialLayer->getTile(ava->getX(), ava->getY());
+ if (portal)
+ {
+ portal->setName(keyboard.getKeyShortString(
+ outfitWindow->keyName(idx)));
+ }
+ }
+ }
+
+ i++;
+ idx ++;
+ }
+ if (socialWindow)
+ socialWindow->setProcessedPortals(true);
+ }
+
+
+ virtual void selectIndex(unsigned num)
+ {
+ if (!player_node)
+ return;
+
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+ if (!avatars || avatars->size() <= num)
+ return;
+
+ Avatar *ava = avatars->at(num);
+ if (ava && player_node)
+ player_node->navigateTo(ava->getX(), ava->getY());
+ }
+
+ void updateNames()
+ {
+ if (!socialWindow)
+ return;
+
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+ if (!avatars)
+ return;
+
+ Map *map = socialWindow->getMap();
+ if (!map)
+ return;
+
+ Avatar *ava = 0;
+ std::vector<Avatar*>::iterator i = avatars->begin();
+ while (i != avatars->end())
+ {
+ ava = (*i);
+ if (!ava)
+ break;
+
+ MapItem *item = map->findPortalXY(ava->getX(), ava->getY());
+ if (item)
+ {
+ std::string name = strprintf("%s [%d %d]",
+ item->getComment().c_str(), item->getX(), item->getY());
+ ava->setName(name);
+ ava->setOriginalName(name);
+ }
+
+ ++i;
+ }
+ }
+
+ int getPortalIndex(int x, int y)
+ {
+ if (!socialWindow)
+ return -1;
+
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+ if (!avatars)
+ return -1;
+
+ Map *map = socialWindow->getMap();
+ if (!map)
+ return 01;
+
+ Avatar *ava = 0;
+ std::vector<Avatar*>::iterator i = avatars->begin();
+ unsigned num = 0;
+ while (i != avatars->end())
+ {
+ ava = (*i);
+
+ if (!ava)
+ break;
+
+ if (ava->getX() == x && ava->getY() == y)
+ return num;
+
+ ++i;
+ num ++;
+ }
+ return -1;
+ }
+
+ void addPortal(int x, int y)
+ {
+ if (!socialWindow || !player_node)
+ return;
+
+ Map* map = socialWindow->getMap();
+ if (!map)
+ return;
+
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+
+ if (!avatars)
+ return;
+
+ MapItem *portal = map->findPortalXY(x, y);
+ if (!portal)
+ return;
+
+ std::string name = strprintf("%s [%d %d]",
+ portal->getComment().c_str(), x, y);
+
+ Avatar *ava = new Avatar(name);
+ if (player_node)
+ ava->setOnline(player_node->isReachable(x, y, 0));
+ else
+ ava->setOnline(false);
+ ava->setLevel(-1);
+ ava->setType(portal->getType());
+ ava->setX(x);
+ ava->setY(y);
+ avatars->push_back(ava);
+ }
+
+ void removePortal(int x, int y)
+ {
+ if (!socialWindow || !player_node)
+ return;
+
+ Map* map = socialWindow->getMap();
+ if (!map)
+ return;
+
+ std::vector<Avatar*> *avatars = mBeings->getMembers();
+
+ std::vector<Avatar*>::iterator i = avatars->begin();
+
+ if (!avatars)
+ return;
+
+ while (i != avatars->end())
+ {
+ Avatar *ava = (*i);
+
+ if (!ava)
+ break;
+
+ if (ava && ava->getX() == x && ava->getY() == y)
+ {
+ avatars->erase(i);
+ return;
+ }
+
+ ++ i;
+ }
+ }
+
+ void updateAvatar(std::string)
+ {
+ }
+
+ void resetDamage(std::string)
+ {
+ }
+
+private:
+ BeingsListModal *mBeings;
+
+protected:
+// friend class SocialWindow;
+};
+
+
+class CreatePopup : public Popup, public LinkHandler
+{
+public:
+ CreatePopup():
+ Popup("SocialCreatePopup")
+ {
+ mBrowserBox = new BrowserBox;
+ mBrowserBox->setPosition(4, 4);
+ mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
+ mBrowserBox->setOpaque(false);
+ mBrowserBox->setLinkHandler(this);
+
+ if (Net::getGuildHandler()->isSupported())
+ mBrowserBox->addRow(strprintf("@@guild|%s@@", _("Create Guild")));
+ mBrowserBox->addRow(strprintf("@@party|%s@@", _("Create Party")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ add(mBrowserBox);
+
+ setContentSize(mBrowserBox->getWidth() + 8,
+ mBrowserBox->getHeight() + 8);
+ }
+
+ void handleLink(const std::string &link, gcn::MouseEvent *event _UNUSED_)
+ {
+ if (link == "guild" && socialWindow)
+ {
+ socialWindow->showGuildCreate();
+ }
+ else if (link == "party" && socialWindow)
+ {
+ socialWindow->showPartyCreate();
+ }
+
+ setVisible(false);
+ }
+
+ void show(gcn::Widget *parent)
+ {
+ if (!parent)
+ return;
+
+ int x, y;
+ parent->getAbsolutePosition(x, y);
+ y += parent->getHeight();
+ setPosition(x, y);
+ setVisible(true);
+ requestMoveToTop();
+ }
+
+private:
+ BrowserBox* mBrowserBox;
+};
+
+SocialWindow::SocialWindow() :
+ Window(_("Social")),
+ mGuildInvited(0),
+ mGuildAcceptDialog(0),
+ mPartyAcceptDialog(0),
+ mMap(0),
+ mLastUpdateTime(0),
+ mNeedUpdate(false),
+ mProcessedPortals(false)
+{
+ setWindowName("Social");
+ setVisible(false);
+ setSaveVisible(true);
+ setResizable(true);
+ setSaveVisible(true);
+ setCloseButton(true);
+ setMinWidth(120);
+ setMinHeight(55);
+ setDefaultSize(590, 200, 150, 120);
+ setupWindow->registerWindowForReset(this);
+
+ mCreateButton = new Button(_("Create"), "create", this);
+ mInviteButton = new Button(_("Invite"), "invite", this);
+ mLeaveButton = new Button(_("Leave"), "leave", this);
+ mTabs = new TabbedArea;
+
+ place(0, 0, mCreateButton);
+ place(1, 0, mInviteButton);
+ place(2, 0, mLeaveButton);
+ place(0, 1, mTabs, 4, 4);
+
+ widgetResized(NULL);
+
+ mCreatePopup = new CreatePopup();
+
+ loadWindowState();
+
+ mPlayers = new PlayersTab("P");
+ mTabs->addTab(mPlayers, mPlayers->mScroll);
+
+ mNavigation = new NavigationTab();
+ mTabs->addTab(mNavigation, mNavigation->mScroll);
+
+ if (player_node && player_node->getParty())
+ addTab(player_node->getParty());
+
+ if (player_node && player_node->getGuild())
+ addTab(player_node->getGuild());
+
+ updateButtons();
+}
+
+SocialWindow::~SocialWindow()
+{
+ // Cleanup invites
+ if (mGuildAcceptDialog)
+ {
+ mGuildAcceptDialog->close();
+ mGuildAcceptDialog->scheduleDelete();
+ mGuildAcceptDialog = NULL;
+
+ mGuildInvited = 0;
+ }
+
+ if (mPartyAcceptDialog)
+ {
+ mPartyAcceptDialog->close();
+ mPartyAcceptDialog->scheduleDelete();
+ mPartyAcceptDialog = NULL;
+
+ mPartyInviter = "";
+ }
+ delete mCreatePopup;
+ mCreatePopup = 0;
+ delete mPlayers;
+ mPlayers = 0;
+}
+
+bool SocialWindow::addTab(Guild *guild)
+{
+ if (mGuilds.find(guild) != mGuilds.end())
+ return false;
+
+ GuildTab *tab = new GuildTab(guild);
+ mGuilds[guild] = tab;
+
+ mTabs->addTab(tab, tab->mScroll);
+
+ updateButtons();
+
+ return true;
+}
+
+bool SocialWindow::removeTab(Guild *guild)
+{
+ GuildMap::iterator it = mGuilds.find(guild);
+ if (it == mGuilds.end())
+ return false;
+
+ mTabs->removeTab(it->second);
+ delete it->second;
+ mGuilds.erase(it);
+
+ updateButtons();
+
+ return true;
+}
+
+bool SocialWindow::addTab(Party *party)
+{
+ if (mParties.find(party) != mParties.end())
+ return false;
+
+ PartyTab *tab = new PartyTab(party);
+ mParties[party] = tab;
+
+ mTabs->addTab(tab, tab->mScroll);
+
+ updateButtons();
+
+ return true;
+}
+
+bool SocialWindow::removeTab(Party *party)
+{
+ PartyMap::iterator it = mParties.find(party);
+ if (it == mParties.end())
+ return false;
+
+ mTabs->removeTab(it->second);
+ delete it->second;
+ mParties.erase(it);
+
+ updateButtons();
+
+ return true;
+}
+
+void SocialWindow::action(const gcn::ActionEvent &event)
+{
+ const std::string &eventId = event.getId();
+
+ if (event.getSource() == mPartyAcceptDialog)
+ {
+ // check if they accepted the invite
+ if (eventId == "yes")
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(
+ strprintf(_("Accepted party invite from %s."),
+ mPartyInviter.c_str()));
+ }
+ Net::getPartyHandler()->inviteResponse(mPartyInviter, true);
+ }
+ else if (eventId == "no")
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(
+ strprintf(_("Rejected party invite from %s."),
+ mPartyInviter.c_str()));
+ }
+ Net::getPartyHandler()->inviteResponse(mPartyInviter, false);
+ }
+
+ mPartyInviter = "";
+ mPartyAcceptDialog = NULL;
+ }
+ else if (event.getSource() == mGuildAcceptDialog)
+ {
+ // check if they accepted the invite
+ if (eventId == "yes")
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(
+ strprintf(_("Accepted guild invite from %s."),
+ mPartyInviter.c_str()));
+ }
+ Net::getGuildHandler()->inviteResponse(mGuildInvited, true);
+ }
+ else if (eventId == "no")
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(
+ strprintf(_("Rejected guild invite from %s."),
+ mPartyInviter.c_str()));
+ }
+ Net::getGuildHandler()->inviteResponse(mGuildInvited, false);
+ }
+
+ mGuildInvited = 0;
+ mGuildAcceptDialog = NULL;
+ }
+ else if (event.getId() == "create")
+ {
+ if (Net::getGuildHandler()->isSupported())
+ {
+ if (mCreatePopup)
+ mCreatePopup->show(mCreateButton);
+ }
+ else
+ {
+ showPartyCreate();
+ }
+ }
+ else if (event.getId() == "invite" && mTabs->getSelectedTabIndex() > -1)
+ {
+ if (mTabs->getSelectedTab())
+ static_cast<SocialTab*>(mTabs->getSelectedTab())->invite();
+ }
+ else if (event.getId() == "leave" && mTabs->getSelectedTabIndex() > -1)
+ {
+ if (mTabs->getSelectedTab())
+ static_cast<SocialTab*>(mTabs->getSelectedTab())->leave();
+ }
+ else if (event.getId() == "create guild")
+ {
+ std::string name = mGuildCreateDialog->getText();
+
+ if (name.size() > 16)
+ {
+ // TODO : State too many characters in input.
+ return;
+ }
+
+ Net::getGuildHandler()->create(name);
+ if (localChatTab)
+ {
+ localChatTab->chatLog(strprintf(_("Creating guild called %s."),
+ name.c_str()), BY_SERVER);
+ }
+
+ mGuildCreateDialog = NULL;
+ }
+ else if (event.getId() == "~create guild")
+ {
+ mGuildCreateDialog = NULL;
+ }
+ else if (event.getId() == "create party")
+ {
+ std::string name = mPartyCreateDialog->getText();
+
+ if (name.size() > 16)
+ {
+ // TODO : State too many characters in input.
+ return;
+ }
+
+ Net::getPartyHandler()->create(name);
+ if (localChatTab)
+ {
+ localChatTab->chatLog(strprintf(_("Creating party called %s."),
+ name.c_str()), BY_SERVER);
+ }
+
+ mPartyCreateDialog = NULL;
+ }
+ else if (event.getId() == "~create party")
+ {
+ mPartyCreateDialog = NULL;
+ }
+}
+
+void SocialWindow::showGuildCreate()
+{
+ mGuildCreateDialog = new TextDialog(_("Guild Name"),
+ _("Choose your guild's name."), this);
+ mGuildCreateDialog->setActionEventId("create guild");
+ mGuildCreateDialog->addActionListener(this);
+}
+
+void SocialWindow::showGuildInvite(const std::string &guildName,
+ const int guildId,
+ const std::string &inviterName)
+{
+ // check there isnt already an invite showing
+ if (mGuildInvited != 0)
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(_("Received guild request, but one already "
+ "exists."), BY_SERVER);
+ }
+ return;
+ }
+
+ std::string msg = strprintf(_("%s has invited you to join the guild %s."),
+ inviterName.c_str(), guildName.c_str());
+ if (localChatTab)
+ localChatTab->chatLog(msg, BY_SERVER);
+
+ // show invite
+ mGuildAcceptDialog = new ConfirmDialog(_("Accept Guild Invite"),
+ msg, false, false, this);
+ mGuildAcceptDialog->addActionListener(this);
+
+ mGuildInvited = guildId;
+}
+
+void SocialWindow::showPartyInvite(const std::string &partyName,
+ const std::string &inviter)
+{
+ // check there isnt already an invite showing
+ if (mPartyInviter != "")
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(_("Received party request, but one already "
+ "exists."), BY_SERVER);
+ }
+ return;
+ }
+
+ std::string msg;
+ if (inviter.empty())
+ {
+ if (partyName.empty())
+ {
+ msg = _("You have been invited you to join a party.");
+ }
+ else
+ {
+ msg = strprintf(_("You have been invited to join the %s party."),
+ partyName.c_str());
+ }
+ }
+ else
+ {
+ if (partyName.empty())
+ {
+ msg = strprintf(_("%s has invited you to join their party."),
+ inviter.c_str());
+ }
+ else
+ {
+ msg = strprintf(_("%s has invited you to join the %s party."),
+ inviter.c_str(), partyName.c_str());
+ }
+ }
+
+ if (localChatTab)
+ localChatTab->chatLog(msg, BY_SERVER);
+
+ // show invite
+ mPartyAcceptDialog = new ConfirmDialog(_("Accept Party Invite"),
+ msg, false, false, this);
+ mPartyAcceptDialog->addActionListener(this);
+
+ mPartyInviter = inviter;
+}
+
+void SocialWindow::showPartyCreate()
+{
+ if (!player_node)
+ return;
+
+ if (player_node->getParty())
+ {
+ new OkDialog(_("Create Party"),
+ _("Cannot create party. You are already in a party"),
+ this);
+ return;
+ }
+
+ mPartyCreateDialog = new TextDialog(_("Party Name"),
+ _("Choose your party's name."), this);
+ mPartyCreateDialog->setActionEventId("create party");
+ mPartyCreateDialog->addActionListener(this);
+}
+
+void SocialWindow::updateActiveList()
+{
+ mNeedUpdate = true;
+}
+
+void SocialWindow::logic()
+{
+ unsigned int nowTime = cur_time;
+ if (nowTime - mLastUpdateTime > 1 && mNeedUpdate)
+ {
+ mPlayers->updateList();
+ mNeedUpdate = false;
+ mLastUpdateTime = nowTime;
+ }
+ else if (nowTime - mLastUpdateTime > 5)
+ {
+ mPlayers->updateList();
+ mNeedUpdate = false;
+ mLastUpdateTime = nowTime;
+ }
+
+ Window::logic();
+}
+
+void SocialWindow::updateAvatar(std::string name)
+{
+ mPlayers->updateAvatar(name);
+}
+
+void SocialWindow::resetDamage(std::string name)
+{
+ mPlayers->resetDamage(name);
+}
+
+void SocialWindow::updateButtons()
+{
+ if (!mTabs)
+ return;
+
+ bool hasTabs = mTabs->getNumberOfTabs() > 0;
+ mInviteButton->setEnabled(hasTabs);
+ mLeaveButton->setEnabled(hasTabs);
+}
+
+void SocialWindow::updatePortals()
+{
+ if (mNavigation)
+ mNavigation->updateList();
+}
+
+void SocialWindow::updatePortalNames()
+{
+ if (mNavigation)
+ static_cast<NavigationTab*>(mNavigation)->updateNames();
+}
+
+void SocialWindow::selectPortal(unsigned num)
+{
+ if (mNavigation)
+ mNavigation->selectIndex(num);
+}
+
+int SocialWindow::getPortalIndex(int x, int y)
+{
+ if (mNavigation)
+ return static_cast<NavigationTab*>(mNavigation)->getPortalIndex(x, y);
+ else
+ return -1;
+}
+
+void SocialWindow::addPortal(int x, int y)
+{
+ if (mNavigation)
+ static_cast<NavigationTab*>(mNavigation)->addPortal(x, y);
+}
+
+void SocialWindow::removePortal(int x, int y)
+{
+ if (mNavigation)
+ static_cast<NavigationTab*>(mNavigation)->removePortal(x, y);
+}
+
+void SocialWindow::nextTab()
+{
+ if (!mTabs)
+ return;
+
+ int tab = mTabs->getSelectedTabIndex();
+
+ tab++;
+ if (tab == mTabs->getNumberOfTabs())
+ tab = 0;
+
+ mTabs->setSelectedTab(tab);
+}
+
+void SocialWindow::prevTab()
+{
+ if (!mTabs)
+ return;
+
+ int tab = mTabs->getSelectedTabIndex();
+
+ if (tab == 0)
+ tab = mTabs->getNumberOfTabs();
+ tab--;
+
+ mTabs->setSelectedTab(tab);
+} \ No newline at end of file
diff --git a/src/gui/socialwindow.h b/src/gui/socialwindow.h
new file mode 100644
index 000000000..6e654c4c6
--- /dev/null
+++ b/src/gui/socialwindow.h
@@ -0,0 +1,159 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SOCIALWINDOW_H
+#define SOCIALWINDOW_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionevent.hpp>
+#include <guichan/actionlistener.hpp>
+
+#include <string>
+#include <map>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Button;
+class ConfirmDialog;
+class CreatePopup;
+class Guild;
+class Map;
+class NavigateTab;
+class Party;
+class SocialTab;
+class Tab;
+class TabbedArea;
+class TextDialog;
+class PlayersTab;
+
+/**
+ * Party window.
+ *
+ * \ingroup Interface
+ */
+class SocialWindow : public Window, gcn::ActionListener
+{
+public:
+ SocialWindow();
+
+ ~SocialWindow();
+
+ bool addTab(Guild *guild);
+
+ bool removeTab(Guild *guild);
+
+ bool addTab(Party *party);
+
+ bool removeTab(Party *party);
+
+ /**
+ * Handle events.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ void showGuildInvite(const std::string &guildName, const int guildId,
+ const std::string &inviterName);
+
+ void showGuildCreate();
+
+ void showPartyInvite(const std::string &partyName,
+ const std::string &inviter = "");
+
+ void showPartyCreate();
+
+ void updateActiveList();
+
+ void updateAvatar(std::string name);
+
+ void resetDamage(std::string name);
+
+ void logic();
+
+ void updatePortals();
+
+ void updatePortalNames();
+
+ int getPortalIndex(int x, int y);
+
+ void addPortal(int x, int y);
+
+ void removePortal(int x, int y);
+
+ void nextTab();
+
+ void prevTab();
+
+ Map* getMap()
+ { return mMap; }
+
+ void setMap(Map *map)
+ { mMap = map; mProcessedPortals = false; }
+
+ bool getProcessedPortals()
+ { return mProcessedPortals; }
+
+ void setProcessedPortals(int n)
+ { mProcessedPortals = n; }
+
+ void selectPortal(unsigned num);
+
+protected:
+ friend class SocialTab;
+
+ void updateButtons();
+
+ int mGuildInvited;
+ ConfirmDialog *mGuildAcceptDialog;
+ TextDialog *mGuildCreateDialog;
+
+ std::string mPartyInviter;
+ ConfirmDialog *mPartyAcceptDialog;
+ TextDialog *mPartyCreateDialog;
+
+ typedef std::map<Guild*, SocialTab*> GuildMap;
+ GuildMap mGuilds;
+
+ typedef std::map<Party*, SocialTab*> PartyMap;
+ PartyMap mParties;
+
+ SocialTab *mPlayers;
+ SocialTab *mNavigation;
+
+ CreatePopup *mCreatePopup;
+
+ Button *mCreateButton;
+ Button *mInviteButton;
+ Button *mLeaveButton;
+ TabbedArea *mTabs;
+ Map *mMap;
+
+ int mLastUpdateTime;
+ bool mNeedUpdate;
+ bool mProcessedPortals;
+};
+
+extern SocialWindow *socialWindow;
+
+#endif // SOCIALWINDOW_H
diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp
new file mode 100644
index 000000000..bd968191d
--- /dev/null
+++ b/src/gui/specialswindow.cpp
@@ -0,0 +1,257 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/specialswindow.h"
+
+#include "log.h"
+
+#include "gui/setup.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/container.h"
+#include "gui/widgets/icon.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/progressbar.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/tab.h"
+#include "gui/widgets/tabbedarea.h"
+#include "gui/widgets/flowcontainer.h"
+#include "gui/widgets/windowcontainer.h"
+
+#include "net/net.h"
+#include "net/specialhandler.h"
+
+#include "resources/specialdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <string>
+
+#define SPECIALS_WIDTH 200
+#define SPECIALS_HEIGHT 32
+
+class SpecialEntry;
+
+
+class SpecialEntry : public Container
+{
+ public:
+ SpecialEntry(SpecialInfo *info);
+
+ void update(int current, int needed);
+
+ protected:
+ friend class SpecialsWindow;
+ SpecialInfo *mInfo;
+
+ private:
+ Icon *mIcon; // icon to display
+ Label *mNameLabel; // name to display
+ Label *mLevelLabel; // level number label (only shown when applicable)
+ Button *mUse; // use button (only shown when applicable)
+ ProgressBar *mRechargeBar; // recharge bar (only shown when applicable)
+};
+
+SpecialsWindow::SpecialsWindow():
+ Window(_("Specials"))
+{
+ setWindowName("Specials");
+ setCloseButton(true);
+ setResizable(true);
+ setSaveVisible(true);
+ setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425);
+ setupWindow->registerWindowForReset(this);
+
+ mTabs = new TabbedArea();
+
+ place(0, 0, mTabs, 5, 5);
+
+ setLocationRelativeTo(getParent());
+ loadWindowState();
+}
+
+SpecialsWindow::~SpecialsWindow()
+{
+ // Clear gui
+}
+
+void SpecialsWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "use")
+ {
+ if (!event.getSource())
+ return;
+
+ SpecialEntry *disp = dynamic_cast<SpecialEntry*>(
+ event.getSource()->getParent());
+
+ if (disp)
+ {
+ /*Being *target = player_node->getTarget();
+
+ if (target)
+ Net::getSpecialHandler()->use(disp->mInfo->id,
+ 1, target->getId());
+ else*/
+ Net::getSpecialHandler()->use(disp->mInfo->id);
+ }
+ }
+ else if (event.getId() == "close")
+ {
+ setVisible(false);
+ }
+}
+
+void SpecialsWindow::draw(gcn::Graphics *graphics)
+{
+ // update the progress bars
+ std::map<int, Special> specialData = PlayerInfo::getSpecialStatus();
+ bool foundNew = false;
+ unsigned int found = 0; // number of entries in specialData
+ // which match mEntries
+
+ for (std::map<int, Special>::iterator i = specialData.begin();
+ i != specialData.end(); i++)
+ {
+ std::map<int, SpecialEntry *>::iterator e = mEntries.find(i->first);
+ if (e == mEntries.end())
+ {
+ // found a new special - abort update and rebuild from scratch
+ foundNew = true;
+ break;
+ }
+ else
+ {
+ // update progress bar of special
+ if (e->second)
+ e->second->update(i->second.currentMana, i->second.neededMana);
+ found++;
+ }
+ }
+ // a rebuild is needed when a) the number of specials changed or b)
+ // an existing entry isn't found anymore
+ if (foundNew || found != mEntries.size())
+ rebuild(specialData);
+
+ Window::draw(graphics);
+}
+
+void SpecialsWindow::rebuild(const std::map<int, Special> &specialData)
+{
+ make_dtor(mEntries);
+ mEntries.clear();
+ int vPos = 0; //vertical position of next placed element
+
+ for (std::map<int, Special>::const_iterator i = specialData.begin();
+ i != specialData.end();
+ i++)
+ {
+ logger->log("Updating special GUI for %d", i->first);
+
+ SpecialInfo* info = SpecialDB::get(i->first);
+ if (info)
+ {
+ info->rechargeCurrent = i->second.currentMana;
+ info->rechargeNeeded = i->second.neededMana;
+ SpecialEntry* entry = new SpecialEntry(info);
+ entry->setPosition(0, vPos);
+ vPos += entry->getHeight();
+ add(entry);
+ mEntries[i->first] = entry;
+ }
+ else
+ {
+ logger->log("Warning: No info available of special %d", i->first);
+ }
+ }
+}
+
+
+SpecialEntry::SpecialEntry(SpecialInfo *info) :
+ mInfo(info),
+ mIcon(NULL),
+ mLevelLabel(NULL),
+ mUse(NULL),
+ mRechargeBar(NULL)
+{
+ setFrameSize(1);
+ setOpaque(false);
+ setSize(SPECIALS_WIDTH, SPECIALS_HEIGHT);
+
+ if (info && !info->icon.empty())
+ mIcon = new Icon(info->icon);
+ else
+ mIcon = new Icon(Theme::resolveThemePath("unknown-item.png"));
+
+ mIcon->setPosition(1, 0);
+ add(mIcon);
+
+ if (info)
+ mNameLabel = new Label(info->name);
+ else
+ mNameLabel = new Label("");
+
+ mNameLabel->setPosition(35, 0);
+ add(mNameLabel);
+
+ if (info && info->hasLevel)
+ {
+ mLevelLabel = new Label(toString(info->level));
+ mLevelLabel->setPosition(getWidth() - mLevelLabel->getWidth(), 0);
+ add(mLevelLabel);
+ }
+
+ if (info && info->isActive)
+ {
+ mUse = new Button("Use", "use", specialsWindow);
+ mUse->setPosition(getWidth() - mUse->getWidth(), 13);
+ add(mUse);
+ }
+
+ if (info->hasRechargeBar)
+ {
+ float progress = 0;
+ if (info->rechargeNeeded)
+ {
+ progress = (float)info->rechargeCurrent
+ / (float)info->rechargeNeeded;
+ }
+ mRechargeBar = new ProgressBar(progress, 100, 10, Theme::PROG_MP);
+ mRechargeBar->setSmoothProgress(false);
+ mRechargeBar->setPosition(0, 13);
+ add(mRechargeBar);
+ }
+
+}
+
+void SpecialEntry::update(int current, int needed)
+{
+ if (mRechargeBar && needed)
+ {
+ float progress = (float)current / (float)needed;
+ mRechargeBar->setProgress(progress);
+ }
+}
diff --git a/src/gui/specialswindow.h b/src/gui/specialswindow.h
new file mode 100644
index 000000000..66ef5e375
--- /dev/null
+++ b/src/gui/specialswindow.h
@@ -0,0 +1,73 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SPECIALSWINDOW_H
+#define SPECIALSWINDOW_H
+
+#include <vector>
+
+#include "guichanfwd.h"
+
+#include "playerinfo.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <map>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Label;
+class ScrollArea;
+class Tab;
+class TabbedArea;
+
+struct SpecialEntry;
+
+class SpecialsWindow : public Window, public gcn::ActionListener
+{
+ public:
+ SpecialsWindow();
+
+ ~SpecialsWindow();
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &actionEvent);
+
+ void draw(gcn::Graphics *graphics);
+
+ private:
+ // (re)constructs the list of specials
+ void rebuild(const std::map<int, Special> &specialData);
+
+ TabbedArea *mTabs;
+ std::map<int, SpecialEntry *> mEntries;
+};
+
+extern SpecialsWindow *specialsWindow;
+
+#endif // SPECIALSWINDOW_H
diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp
new file mode 100644
index 000000000..08d000380
--- /dev/null
+++ b/src/gui/speechbubble.cpp
@@ -0,0 +1,91 @@
+/*
+ * Speech bubbles
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/speechbubble.h"
+
+#include "graphics.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/textbox.h"
+
+#include <guichan/font.hpp>
+
+#include <guichan/widgets/label.hpp>
+
+SpeechBubble::SpeechBubble():
+ Popup("Speech", "speechbubble.xml")
+{
+ setContentSize(140, 46);
+ setMinWidth(29);
+ setMinHeight(29);
+
+ mCaption = new gcn::Label;
+ mCaption->setFont(boldFont);
+
+ mSpeechBox = new TextBox;
+ mSpeechBox->setEditable(false);
+ mSpeechBox->setOpaque(false);
+ mSpeechBox->setTextColor(&Theme::getThemeColor(Theme::CHAT));
+
+ add(mCaption);
+ add(mSpeechBox);
+}
+
+void SpeechBubble::setCaption(const std::string &name, const gcn::Color *color)
+{
+ mCaption->setCaption(name);
+ mCaption->adjustSize();
+ mCaption->setForegroundColor(*color);
+}
+
+void SpeechBubble::setText(const std::string &text, bool showName)
+{
+ if (text == mText && (mCaption->getWidth() <= mSpeechBox->getMinWidth()))
+ return;
+
+ mSpeechBox->setTextColor(&Theme::getThemeColor(Theme::TEXT));
+
+ int width = mCaption->getWidth() + 2 * getPadding();
+ mSpeechBox->setTextWrapped(text, 130 > width ? 130 : width);
+ const int speechWidth = mSpeechBox->getMinWidth() + 2 * getPadding();
+
+ const int fontHeight = getFont()->getHeight();
+ const int nameHeight = showName ? mCaption->getHeight() +
+ (getPadding() / 2) : 0;
+ const int numRows = mSpeechBox->getNumberOfRows();
+ const int height = (numRows * fontHeight) + nameHeight + getPadding();
+
+ if (width < speechWidth)
+ width = speechWidth;
+
+ width += 2 * getPadding();
+
+ setContentSize(width, height);
+
+ const int xPos = ((getWidth() - width) / 2);
+ const int yPos = ((getHeight() - height) / 2) + nameHeight;
+
+ mCaption->setPosition(xPos, getPadding());
+ mSpeechBox->setPosition(xPos, yPos);
+}
diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h
new file mode 100644
index 000000000..8682ab7e9
--- /dev/null
+++ b/src/gui/speechbubble.h
@@ -0,0 +1,58 @@
+/*
+ * Speech bubbles
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SPEECHBUBBLE_H
+#define SPEECHBUBBLE_H
+
+#include "gui/theme.h"
+
+#include "gui/widgets/popup.h"
+
+class TextBox;
+
+class SpeechBubble : public Popup
+{
+ public:
+ /**
+ * Constructor. Initializes the speech bubble.
+ */
+ SpeechBubble();
+
+ /**
+ * Sets the name displayed for the speech bubble, and in what color.
+ */
+ void setCaption(const std::string &name,
+ const gcn::Color *color =
+ &Theme::getThemeColor(Theme::TEXT));
+
+ /**
+ * Sets the text to be displayed.
+ */
+ void setText(const std::string &text, bool showName = true);
+
+ private:
+ std::string mText;
+ gcn::Label *mCaption;
+ TextBox *mSpeechBox;
+};
+
+#endif
diff --git a/src/gui/spellpopup.cpp b/src/gui/spellpopup.cpp
new file mode 100644
index 000000000..80fa9f378
--- /dev/null
+++ b/src/gui/spellpopup.cpp
@@ -0,0 +1,105 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/spellpopup.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+
+#include "textcommand.h"
+
+#include "graphics.h"
+#include "units.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+#include <guichan/widgets/label.hpp>
+
+SpellPopup::SpellPopup():
+ Popup("SpellPopup")
+{
+ // Item Name
+ mItemName = new gcn::Label;
+ mItemName->setFont(boldFont);
+ mItemName->setPosition(getPadding(), getPadding());
+
+ add(mItemName);
+ addMouseListener(this);
+}
+
+SpellPopup::~SpellPopup()
+{
+}
+
+void SpellPopup::setItem(TextCommand *spell)
+{
+ if (spell)
+ mItemName->setCaption(spell->getName());
+ else
+ mItemName->setCaption("?");
+
+ mItemName->adjustSize();
+ int minWidth = mItemName->getWidth();
+
+ minWidth += 8;
+ setWidth(minWidth);
+
+ setContentSize(minWidth, getPadding() + getFont()->getHeight());
+}
+
+void SpellPopup::view(int x, int y)
+{
+ const int distance = 20;
+
+ int posX = std::max(0, x - getWidth() / 2);
+ int posY = y + distance;
+
+ if (posX + getWidth() > graphics->getWidth())
+ {
+ if (graphics->getWidth() > getWidth())
+ posX = graphics->getWidth() - getWidth();
+ else
+ posX = 0;
+ }
+ if (posY + getHeight() > graphics->getHeight())
+ {
+ if (y > getHeight() + distance)
+ posY = y - getHeight() - distance;
+ else
+ y = 0;
+ }
+
+ setPosition(posX, posY);
+ setVisible(true);
+ requestMoveToTop();
+}
+
+void SpellPopup::mouseMoved(gcn::MouseEvent &event)
+{
+ Popup::mouseMoved(event);
+
+ // When the mouse moved on top of the popup, hide it
+ setVisible(false);
+}
diff --git a/src/gui/spellpopup.h b/src/gui/spellpopup.h
new file mode 100644
index 000000000..1b14e0e4c
--- /dev/null
+++ b/src/gui/spellpopup.h
@@ -0,0 +1,67 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SPELLPOPUP_H
+#define SPELLPOPUP_H
+
+#include "gui/widgets/popup.h"
+
+#include "textcommand.h"
+
+#include <guichan/mouselistener.hpp>
+
+class TextBox;
+
+/**
+ * A popup that displays information about an item.
+ */
+class SpellPopup : public Popup
+{
+ public:
+ /**
+ * Constructor. Initializes the item popup.
+ */
+ SpellPopup();
+
+ /**
+ * Destructor. Cleans up the item popup on deletion.
+ */
+ ~SpellPopup();
+
+ /**
+ * Sets the info to be displayed given a particular item.
+ */
+ void setItem(TextCommand *spell);
+
+ /**
+ * Sets the location to display the item popup.
+ */
+ void view(int x, int y);
+
+ void mouseMoved(gcn::MouseEvent &mouseEvent);
+
+ private:
+ gcn::Label *mItemName;
+};
+
+#endif // SPELLPOPUP_H
diff --git a/src/gui/statuspopup.cpp b/src/gui/statuspopup.cpp
new file mode 100644
index 000000000..4d2c48fa7
--- /dev/null
+++ b/src/gui/statuspopup.cpp
@@ -0,0 +1,543 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/statuspopup.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+
+#include "gui/widgets/layout.h"
+#include "gui/widgets/textbox.h"
+
+#include "graphics.h"
+#include "localplayer.h"
+#include "units.h"
+#include "viewport.h"
+#include "keyboardconfig.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+#include <guichan/widgets/label.hpp>
+
+StatusPopup::StatusPopup():
+ Popup("StatusPopup")
+{
+
+ const int fontHeight = getFont()->getHeight();
+
+ mMoveType = new gcn::Label;
+ mMoveType->setPosition(getPadding(), getPadding());
+
+ mCrazyMoveType = new gcn::Label;
+ mCrazyMoveType->setPosition(getPadding(), fontHeight + getPadding());
+
+ mMoveToTargetType = new gcn::Label;
+ mMoveToTargetType->setPosition(getPadding(),
+ 2 * fontHeight + getPadding());
+
+ mFollowMode = new gcn::Label;
+ mFollowMode->setPosition(getPadding(), 3 * fontHeight + getPadding());
+
+ mAttackWeaponType = new gcn::Label;
+ mAttackWeaponType->setPosition(getPadding(),
+ 4 + 4 * fontHeight + getPadding());
+
+ mAttackType = new gcn::Label;
+ mAttackType->setPosition(getPadding(), 4 + 5 * fontHeight + getPadding());
+
+ mMagicAttackType = new gcn::Label;
+ mMagicAttackType->setPosition(getPadding(),
+ 4 + 6 * fontHeight + getPadding());
+
+ mDropCounter = new gcn::Label;
+ mDropCounter->setPosition(getPadding(), 8 + 7 * fontHeight + getPadding());
+
+ mPickUpType = new gcn::Label;
+ mPickUpType->setPosition(getPadding(), 8 + 8 * fontHeight + getPadding());
+
+ mMapType = new gcn::Label;
+ mMapType->setPosition(getPadding(), 12 + 9 * fontHeight + getPadding());
+
+ mImitationMode = new gcn::Label;
+ mImitationMode->setPosition(getPadding(),
+ 16 + 10 * fontHeight + getPadding());
+
+ mAwayMode = new gcn::Label;
+ mAwayMode->setPosition(getPadding(), 16 + 11 * fontHeight + getPadding());
+
+ mCameraMode = new gcn::Label;
+ mCameraMode->setPosition(getPadding(),
+ 16 + 12 * fontHeight + getPadding());
+
+ mDisableGameModifiers = new gcn::Label;
+ mDisableGameModifiers->setPosition(getPadding(),
+ 20 + 13 * fontHeight + getPadding());
+
+ add(mMoveType);
+ add(mCrazyMoveType);
+ add(mMoveToTargetType);
+ add(mFollowMode);
+ add(mAttackWeaponType);
+ add(mAttackType);
+ add(mDropCounter);
+ add(mPickUpType);
+ add(mMapType);
+ add(mMagicAttackType);
+ add(mDisableGameModifiers);
+ add(mImitationMode);
+ add(mAwayMode);
+ add(mCameraMode);
+
+// addMouseListener(this);
+}
+
+StatusPopup::~StatusPopup()
+{
+}
+
+void StatusPopup::update()
+{
+ updateLabels();
+
+ int minWidth = mMoveType->getWidth();
+
+ if (mMoveToTargetType->getWidth() > minWidth)
+ minWidth = mMoveToTargetType->getWidth();
+ if (mFollowMode->getWidth() > minWidth)
+ minWidth = mFollowMode->getWidth();
+ if (mCrazyMoveType->getWidth() > minWidth)
+ minWidth = mCrazyMoveType->getWidth();
+ if (mAttackWeaponType->getWidth() > minWidth)
+ minWidth = mAttackWeaponType->getWidth();
+ if (mAttackType->getWidth() > minWidth)
+ minWidth = mAttackType->getWidth();
+ if (mDropCounter->getWidth() > minWidth)
+ minWidth = mDropCounter->getWidth();
+ if (mPickUpType->getWidth() > minWidth)
+ minWidth = mPickUpType->getWidth();
+ if (mMapType->getWidth() > minWidth)
+ minWidth = mMapType->getWidth();
+ if (mMagicAttackType->getWidth() > minWidth)
+ minWidth = mMagicAttackType->getWidth();
+ if (mDisableGameModifiers->getWidth() > minWidth)
+ minWidth = mDisableGameModifiers->getWidth();
+ if (mAwayMode->getWidth() > minWidth)
+ minWidth = mAwayMode->getWidth();
+ if (mCameraMode->getWidth() > minWidth)
+ minWidth = mCameraMode->getWidth();
+ if (mImitationMode->getWidth() > minWidth)
+ minWidth = mImitationMode->getWidth();
+
+ minWidth += 16 + 2 * getPadding();
+ setWidth(minWidth);
+
+ const int fontHeight = getFont()->getHeight();
+
+ setHeight(24 + 8 + 14 * fontHeight + getPadding());
+}
+
+void StatusPopup::view(int x, int y)
+{
+ const int distance = 20;
+
+ int posX = std::max(0, x - getWidth() / 2);
+ int posY = y + distance;
+
+ if (posX + getWidth() > graphics->getWidth())
+ posX = graphics->getWidth() - getWidth();
+ if (posY + getHeight() > graphics->getHeight())
+ posY = y - getHeight() - distance;
+
+ update();
+
+ setPosition(posX, posY);
+ setVisible(true);
+ requestMoveToTop();
+}
+
+void StatusPopup::updateLabels()
+{
+ if (!player_node || !viewport)
+ return;
+
+ switch (player_node->getInvertDirection())
+ {
+ case 0:
+ mMoveType->setCaption("(D) default moves "
+ + keyboard.getKeyValueString(keyboard.KEY_INVERT_DIRECTION));
+ break;
+
+ case 1:
+ mMoveType->setCaption("(I) invert moves "
+ + keyboard.getKeyValueString(keyboard.KEY_INVERT_DIRECTION));
+ break;
+
+ case 2:
+ mMoveType->setCaption("(c) moves with some crazy moves "
+ + keyboard.getKeyValueString(keyboard.KEY_INVERT_DIRECTION));
+
+ case 3:
+ mMoveType->setCaption("(C) moves with crazy moves "
+ + keyboard.getKeyValueString(keyboard.KEY_INVERT_DIRECTION));
+ break;
+
+ case 4:
+ mMoveType->setCaption("(d) double normal + crazy "
+ + keyboard.getKeyValueString(keyboard.KEY_INVERT_DIRECTION));
+ break;
+
+ default:
+ mMoveType->setCaption("(?) move "
+ + keyboard.getKeyValueString(keyboard.KEY_INVERT_DIRECTION));
+ break;
+ }
+ mMoveType->adjustSize();
+
+ if (player_node->getCrazyMoveType() < 10)
+ {
+ mCrazyMoveType->setCaption(strprintf("(%d) crazy move number %d ",
+ player_node->getCrazyMoveType(), player_node->getCrazyMoveType())
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_CRAZY_MOVES_TYPE));
+ }
+ else
+ {
+ switch (player_node->getCrazyMoveType())
+ {
+ case 10:
+ mCrazyMoveType->setCaption("(a) custom crazy move "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_CRAZY_MOVES_TYPE));
+ break;
+ default:
+ mCrazyMoveType->setCaption("(?) crazy move "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_CRAZY_MOVES_TYPE));
+ break;
+ }
+ }
+ mCrazyMoveType->adjustSize();
+
+ switch (player_node->getMoveToTargetType())
+ {
+ case 0:
+ mMoveToTargetType->setCaption("(0) default moves to target "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ case 1:
+ mMoveToTargetType->setCaption("(1) moves to target in distance 1 "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ case 2:
+ mMoveToTargetType->setCaption("(2) moves to target in distance 3 "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ case 3:
+ mMoveToTargetType->setCaption("(3) moves to target in distance 3 "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ case 4:
+ mMoveToTargetType->setCaption("(5) moves to target in distance 5 "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ case 5:
+ mMoveToTargetType->setCaption("(7) moves to target in distance 7 "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ case 6:
+ mMoveToTargetType->setCaption(
+ "(A) moves to target in attack range "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ default:
+ mMoveToTargetType->setCaption("(?) move to target "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_MOVE_TO_TARGET));
+ break;
+ }
+ mMoveToTargetType->adjustSize();
+
+ switch (player_node->getFollowMode())
+ {
+ case 0:
+ mFollowMode->setCaption("(D) default follow "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_FOLLOW_MODE));
+ break;
+ case 1:
+ mFollowMode->setCaption("(R) relative follow "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_FOLLOW_MODE));
+ break;
+ case 2:
+ mFollowMode->setCaption("(M) mirror follow "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_FOLLOW_MODE));
+ break;
+ case 3:
+ mFollowMode->setCaption("(P) pet follow "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_FOLLOW_MODE));
+ break;
+ default:
+ mFollowMode->setCaption("(?) unknown follow "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_FOLLOW_MODE));
+ break;
+ }
+ mFollowMode->adjustSize();
+
+ switch (player_node->getAttackWeaponType())
+ {
+ case 1:
+ mAttackWeaponType->setCaption("(D) default attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_ATTACK_WEAPON_TYPE));
+ break;
+ case 2:
+ mAttackWeaponType->setCaption("(s) switch attack without shield "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_ATTACK_WEAPON_TYPE));
+ break;
+ case 3:
+ mAttackWeaponType->setCaption("(S) switch attack with shield "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_ATTACK_WEAPON_TYPE));
+ break;
+ default:
+ mAttackWeaponType->setCaption("(?) attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_ATTACK_WEAPON_TYPE));
+ break;
+ }
+ mAttackWeaponType->adjustSize();
+
+ switch (player_node->getAttackType())
+ {
+ case 0:
+ mAttackType->setCaption("(D) default attack "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_ATTACK_TYPE));
+ break;
+ case 1:
+ mAttackType->setCaption("(G) go and attack "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_ATTACK_TYPE));
+ break;
+ case 2:
+ mAttackType->setCaption("(A) go, attack, pickup "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_ATTACK_TYPE));
+ break;
+ case 3:
+ mAttackType->setCaption("(d) without auto attack "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_ATTACK_TYPE));
+ break;
+ default:
+ mAttackType->setCaption("(?) attack "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_ATTACK_TYPE));
+ break;
+ }
+ mAttackType->adjustSize();
+
+ mDropCounter->setCaption(strprintf("(%d) drop counter %d ",
+ player_node->getQuickDropCounter(), player_node->getQuickDropCounter())
+ + keyboard.getKeyValueString(keyboard.KEY_SWITCH_QUICK_DROP));
+ mDropCounter->adjustSize();
+
+ switch (player_node->getPickUpType())
+ {
+ case 0:
+ mPickUpType->setCaption("(S) small pick up 1x1 cells "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ case 1:
+ mPickUpType->setCaption("(D) default pick up 2x1 cells "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ case 2:
+ mPickUpType->setCaption("(F) forward pick up 2x3 cells "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ case 3:
+ mPickUpType->setCaption("(3) pick up 3x3 cells "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ case 4:
+ mPickUpType->setCaption("(g) go and pick up in distance 4 "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ case 5:
+ mPickUpType->setCaption("(G) go and pick up in distance 8 "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ case 6:
+ mPickUpType->setCaption("(A) go and pick up in max distance "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ default:
+ mPickUpType->setCaption("(?) pick up "
+ + keyboard.getKeyValueString(keyboard.KEY_CHANGE_PICKUP_TYPE));
+ break;
+ }
+ mPickUpType->adjustSize();
+
+ switch (viewport->getDebugPath())
+ {
+ case 0:
+ mMapType->setCaption("(N) normal map view "
+ + keyboard.getKeyValueString(keyboard.KEY_PATHFIND));
+ break;
+ case 1:
+ mMapType->setCaption("(D) debug map view "
+ + keyboard.getKeyValueString(keyboard.KEY_PATHFIND));
+ break;
+ case 2:
+ mMapType->setCaption("(u) ultra map view "
+ + keyboard.getKeyValueString(keyboard.KEY_PATHFIND));
+ break;
+ case 3:
+ mMapType->setCaption("(U) ultra map view 2 "
+ + keyboard.getKeyValueString(keyboard.KEY_PATHFIND));
+ break;
+ case 4:
+ mMapType->setCaption("(e) empty map view "
+ + keyboard.getKeyValueString(keyboard.KEY_PATHFIND));
+ break;
+ case 5:
+ mMapType->setCaption("(b) black & white map view "
+ + keyboard.getKeyValueString(keyboard.KEY_PATHFIND));
+ break;
+ default:
+ mMapType->setCaption("(?) map view "
+ + keyboard.getKeyValueString(keyboard.KEY_PATHFIND));
+ break;
+ }
+ mMapType->adjustSize();
+
+ switch (player_node->getMagicAttackType())
+ {
+ case 0:
+ mMagicAttackType->setCaption("(f) use #flar for magic attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_SWITCH_MAGIC_ATTACK));
+ break;
+ case 1:
+ mMagicAttackType->setCaption("(c) use #chiza for magic attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_SWITCH_MAGIC_ATTACK));
+ break;
+ case 2:
+ mMagicAttackType->setCaption("(I) use #ingrav for magic attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_SWITCH_MAGIC_ATTACK));
+ break;
+ case 3:
+ mMagicAttackType->setCaption("(F) use #frillyar for magic attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_SWITCH_MAGIC_ATTACK));
+ break;
+ case 4:
+ mMagicAttackType->setCaption("(U) use #upmarmu for magic attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_SWITCH_MAGIC_ATTACK));
+ break;
+ default:
+ mMagicAttackType->setCaption("(?) magic attack "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_SWITCH_MAGIC_ATTACK));
+ break;
+ }
+ mMagicAttackType->adjustSize();
+
+ switch (player_node->getImitationMode())
+ {
+ case 0:
+ mImitationMode->setCaption("(D) default imitation "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_IMITATION_MODE));
+ break;
+ case 1:
+ mImitationMode->setCaption("(O) outfits imitation "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_IMITATION_MODE));
+ break;
+ default:
+ mImitationMode->setCaption("(?) imitation "
+ + keyboard.getKeyValueString(
+ keyboard.KEY_CHANGE_IMITATION_MODE));
+ break;
+ }
+ mImitationMode->adjustSize();
+
+ switch (player_node->getAwayMode())
+ {
+ case 0:
+ mAwayMode->setCaption("(O) on keyboard "
+ + keyboard.getKeyValueString(keyboard.KEY_AWAY));
+ break;
+ case 1:
+ mAwayMode->setCaption("(A) away "
+ + keyboard.getKeyValueString(keyboard.KEY_AWAY));
+ break;
+ default:
+ mAwayMode->setCaption("(?) away "
+ + keyboard.getKeyValueString(keyboard.KEY_AWAY));
+ break;
+ }
+ mAwayMode->adjustSize();
+
+ switch (viewport->getCameraMode())
+ {
+ case 0:
+ mCameraMode->setCaption("(G) game camera mode "
+ + keyboard.getKeyValueString(keyboard.KEY_CAMERA));
+ break;
+ case 1:
+ mCameraMode->setCaption("(F) free camera mode "
+ + keyboard.getKeyValueString(keyboard.KEY_CAMERA));
+ break;
+ case 2:
+ mCameraMode->setCaption("(D) design camera mode "
+ + keyboard.getKeyValueString(keyboard.KEY_CAMERA));
+ break;
+ default:
+ mCameraMode->setCaption("(?) away "
+ + keyboard.getKeyValueString(keyboard.KEY_CAMERA));
+ break;
+ }
+ mCameraMode->adjustSize();
+
+ if (player_node->getDisableGameModifiers())
+ {
+ mDisableGameModifiers->setCaption("Game modifiers are disabled "
+ + keyboard.getKeyValueString(keyboard.KEY_DISABLE_GAME_MODIFIERS));
+ }
+ else
+ {
+ mDisableGameModifiers->setCaption("Game modifiers are enabled "
+ + keyboard.getKeyValueString(keyboard.KEY_DISABLE_GAME_MODIFIERS));
+ }
+ mDisableGameModifiers->adjustSize();
+}
diff --git a/src/gui/statuspopup.h b/src/gui/statuspopup.h
new file mode 100644
index 000000000..62d952384
--- /dev/null
+++ b/src/gui/statuspopup.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef StatusPopup_H
+#define StatusPopup_H
+
+#include "gui/widgets/popup.h"
+
+#include "resources/iteminfo.h"
+
+#include <guichan/mouselistener.hpp>
+
+class TextBox;
+
+/**
+ * A popup that displays information about an item.
+ */
+class StatusPopup : public Popup
+{
+ public:
+ /**
+ * Constructor. Initializes the item popup.
+ */
+ StatusPopup();
+
+ /**
+ * Destructor. Cleans up the item popup on deletion.
+ */
+ ~StatusPopup();
+
+ /**
+ * Sets the location to display the item popup.
+ */
+ void view(int x, int y);
+
+// void mouseMoved(gcn::MouseEvent &mouseEvent);
+
+ void update();
+
+ private:
+ void updateLabels();
+ gcn::Label *mMoveType;
+ gcn::Label *mCrazyMoveType;
+ gcn::Label *mMoveToTargetType;
+ gcn::Label *mFollowMode;
+ gcn::Label *mAttackType;
+ gcn::Label *mAttackWeaponType;
+ gcn::Label *mDropCounter;
+ gcn::Label *mPickUpType;
+ gcn::Label *mMapType;
+ gcn::Label *mMagicAttackType;
+ gcn::Label *mDisableGameModifiers;
+ gcn::Label *mImitationMode;
+ gcn::Label *mAwayMode;
+ gcn::Label *mCameraMode;
+};
+
+#endif // StatusPopup_H
diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp
new file mode 100644
index 000000000..349893bfa
--- /dev/null
+++ b/src/gui/statuswindow.cpp
@@ -0,0 +1,880 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/statuswindow.h"
+
+#include "configuration.h"
+#include "event.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "units.h"
+#include "viewport.h"
+
+#include "gui/setup.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/progressbar.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/vertcontainer.h"
+#include "gui/widgets/windowcontainer.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+#include "net/gamehandler.h"
+
+#include "utils/gettext.h"
+#include "utils/mathutils.h"
+#include "utils/stringutils.h"
+
+class AttrDisplay : public Container
+{
+ public:
+ enum Type
+ {
+ DERIVED = 0,
+ CHANGEABLE,
+ UNKNOWN
+ };
+
+ ~AttrDisplay();
+
+ virtual std::string update();
+
+ virtual Type getType()
+ { return UNKNOWN; }
+
+ protected:
+ AttrDisplay(int id, const std::string &name);
+
+ const int mId;
+ const std::string mName;
+
+ LayoutHelper *mLayout;
+ Label *mLabel;
+ Label *mValue;
+};
+
+class DerDisplay : public AttrDisplay
+{
+ public:
+ DerDisplay(int id, const std::string &name);
+
+ virtual Type getType()
+ { return DERIVED; }
+};
+
+class ChangeDisplay : public AttrDisplay, gcn::ActionListener
+{
+ public:
+ ChangeDisplay(int id, const std::string &name);
+
+ std::string update();
+
+ virtual Type getType()
+ { return CHANGEABLE; }
+
+ void setPointsNeeded(int needed);
+
+ private:
+ void action(const gcn::ActionEvent &event);
+
+ int mNeeded;
+
+ Label *mPoints;
+ Button *mDec;
+ Button *mInc;
+};
+
+StatusWindow::StatusWindow():
+ Window(player_node ? player_node->getName() : "?")
+{
+ listen(CHANNEL_ATTRIBUTES);
+
+ setWindowName("Status");
+ setupWindow->registerWindowForReset(this);
+ setResizable(true);
+ setCloseButton(true);
+ setSaveVisible(true);
+ setDefaultSize((windowContainer->getWidth() - 365) / 2,
+ (windowContainer->getHeight() - 255) / 2, 365, 275);
+
+ // ----------------------
+ // Status Part
+ // ----------------------
+
+ mLvlLabel = new Label(strprintf(_("Level: %d"), 0));
+ mMoneyLabel = new Label(strprintf(_("Money: %s"), ""));
+
+ int max = PlayerInfo::getAttribute(MAX_HP);
+ if (!max)
+ max = 1;
+
+ mHpLabel = new Label(_("HP:"));
+ mHpBar = new ProgressBar(max ?
+ static_cast<float>(PlayerInfo::getAttribute(HP))
+ / static_cast<float>(max):
+ static_cast<float>(0), 80, 15, Theme::PROG_HP);
+
+ max = PlayerInfo::getAttribute(EXP_NEEDED);
+ mXpLabel = new Label(_("Exp:"));
+ mXpBar = new ProgressBar(max ?
+ static_cast<float>(PlayerInfo::getAttribute(EXP))
+ / static_cast<float>(max):
+ static_cast<float>(0), 80, 15, Theme::PROG_EXP);
+
+ bool magicBar = Net::getGameHandler()->canUseMagicBar();
+
+ int job = Net::getPlayerHandler()->getJobLocation()
+ && serverConfig.getValueBool("showJob", false);
+
+ if (magicBar)
+ {
+ max = PlayerInfo::getAttribute(MAX_MP);
+ mMpLabel = new Label(_("MP:"));
+ mMpBar = new ProgressBar(max ?
+ static_cast<float>(PlayerInfo::getAttribute(MAX_MP))
+ / static_cast<float>(max) : static_cast<float>(0),
+ 80, 15, Net::getPlayerHandler()->canUseMagic() ?
+ Theme::PROG_MP : Theme::PROG_NO_MP);
+ }
+ else
+ {
+ mMpLabel = 0;
+ mMpBar = 0;
+ }
+
+ place(0, 0, mLvlLabel, 3);
+ // 5, 0 Job Level
+ place(8, 0, mMoneyLabel, 3);
+ place(0, 1, mHpLabel).setPadding(3);
+ place(1, 1, mHpBar, 4);
+ place(5, 1, mXpLabel).setPadding(3);
+ place(6, 1, mXpBar, 5);
+ if (magicBar)
+ {
+ place(0, 2, mMpLabel).setPadding(3);
+ // 5, 2 and 6, 2 Job Progress Bar
+ if (job)
+ place(1, 2, mMpBar, 4);
+ else
+ place(1, 2, mMpBar, 10);
+ }
+
+ if (job)
+ {
+ mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0));
+ mJobLabel = new Label(_("Job:"));
+ mJobBar = new ProgressBar(0.0f, 80, 15, Theme::PROG_JOB);
+
+ place(5, 0, mJobLvlLabel, 3);
+ place(5, 2, mJobLabel).setPadding(3);
+ place(6, 2, mJobBar, 5);
+ }
+ else
+ {
+ mJobLvlLabel = 0;
+ mJobLabel = 0;
+ mJobBar = 0;
+ }
+
+ // ----------------------
+ // Stats Part
+ // ----------------------
+
+ mAttrCont = new VertContainer(32);
+ mAttrScroll = new ScrollArea(mAttrCont);
+ mAttrScroll->setOpaque(false);
+ mAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
+ mAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO);
+ place(0, 3, mAttrScroll, 5, 3);
+
+ mDAttrCont = new VertContainer(32);
+ mDAttrScroll = new ScrollArea(mDAttrCont);
+ mDAttrScroll->setOpaque(false);
+ mDAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
+ mDAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO);
+ place(6, 3, mDAttrScroll, 5, 3);
+
+ getLayout().setRowHeight(3, Layout::AUTO_SET);
+
+ mCharacterPointsLabel = new Label("C");
+ place(0, 6, mCharacterPointsLabel, 5);
+
+ if (Net::getPlayerHandler()->canCorrectAttributes())
+ {
+ mCorrectionPointsLabel = new Label("C");
+ place(0, 7, mCorrectionPointsLabel, 5);
+ }
+
+ loadWindowState();
+
+ // Update bars
+ updateHPBar(mHpBar, true);
+ if (magicBar)
+ updateMPBar(mMpBar, true);
+ updateXPBar(mXpBar, false);
+
+ mMoneyLabel->setCaption(strprintf(_("Money: %s"),
+ Units::formatCurrency(PlayerInfo::getAttribute(MONEY)).c_str()));
+ mMoneyLabel->adjustSize();
+ mCharacterPointsLabel->setCaption(strprintf(_("Character points: %d"),
+ PlayerInfo::getAttribute(CHAR_POINTS)));
+ mCharacterPointsLabel->adjustSize();
+
+ if (player_node && player_node->isGM())
+ {
+ mLvlLabel->setCaption(strprintf(_("Level: %d (GM %d)"),
+ PlayerInfo::getAttribute(LEVEL), player_node->getGMLevel()));
+ }
+ else
+ {
+ mLvlLabel->setCaption(strprintf(_("Level: %d"),
+ PlayerInfo::getAttribute(LEVEL)));
+ }
+ mLvlLabel->adjustSize();
+}
+
+void StatusWindow::event(Channels channel _UNUSED_,
+ const Mana::Event &event)
+{
+ if (event.getName() == EVENT_UPDATEATTRIBUTE)
+ {
+ switch(event.getInt("id"))
+ {
+ case HP: case MAX_HP:
+ updateHPBar(mHpBar, true);
+ break;
+
+ case MP: case MAX_MP:
+ updateMPBar(mMpBar, true);
+ break;
+
+ case EXP: case EXP_NEEDED:
+ updateXPBar(mXpBar, false);
+ break;
+
+ case MONEY:
+ mMoneyLabel->setCaption(strprintf(_("Money: %s"),
+ Units::formatCurrency(event.getInt("newValue")).c_str()));
+ mMoneyLabel->adjustSize();
+ break;
+
+ case CHAR_POINTS:
+ mCharacterPointsLabel->setCaption(strprintf(
+ _("Character points: %d"), event.getInt("newValue")));
+
+ mCharacterPointsLabel->adjustSize();
+ // Update all attributes
+ for (Attrs::iterator it = mAttrs.begin();
+ it != mAttrs.end(); it++)
+ {
+ if (it->second)
+ it->second->update();
+ }
+ break;
+
+ case CORR_POINTS:
+ mCorrectionPointsLabel->setCaption(strprintf(
+ _("Correction points: %d"), event.getInt("newValue")));
+ mCorrectionPointsLabel->adjustSize();
+ // Update all attributes
+ for (Attrs::iterator it = mAttrs.begin();
+ it != mAttrs.end(); it++)
+ {
+ if (it->second)
+ it->second->update();
+ }
+ break;
+
+ case LEVEL:
+ mLvlLabel->setCaption(strprintf(_("Level: %d"),
+ event.getInt("newValue")));
+ mLvlLabel->adjustSize();
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (event.getName() == EVENT_UPDATESTAT)
+ {
+ int id = event.getInt("id");
+ if (id == Net::getPlayerHandler()->getJobLocation())
+ {
+ if (mJobLvlLabel)
+ {
+ mJobLvlLabel->setCaption(strprintf(_("Job: %d"),
+ PlayerInfo::getStatBase(id)));
+ mJobLvlLabel->adjustSize();
+
+ updateProgressBar(mJobBar, id, false);
+ }
+ }
+ else
+ {
+ updateMPBar(mMpBar, true);
+ Attrs::iterator it = mAttrs.find(id);
+ if (it != mAttrs.end() && it->second)
+ {
+ if (it->second)
+ it->second->update();
+ }
+ }
+ }
+}
+
+void StatusWindow::setPointsNeeded(int id, int needed)
+{
+ Attrs::iterator it = mAttrs.find(id);
+
+ if (it != mAttrs.end())
+ {
+ AttrDisplay *disp = it->second;
+ if (disp && disp->getType() == AttrDisplay::CHANGEABLE)
+ static_cast<ChangeDisplay*>(disp)->setPointsNeeded(needed);
+ }
+}
+
+void StatusWindow::addAttribute(int id, const std::string &name,
+ bool modifiable,
+ const std::string &description _UNUSED_)
+{
+ AttrDisplay *disp;
+
+ if (modifiable)
+ {
+ disp = new ChangeDisplay(id, name);
+ mAttrCont->add(disp);
+ }
+ else
+ {
+ disp = new DerDisplay(id, name);
+ mDAttrCont->add(disp);
+ }
+
+ mAttrs[id] = disp;
+}
+
+void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
+{
+ if (!bar)
+ return;
+
+ if (showMax)
+ bar->setText(toString(PlayerInfo::getAttribute(HP)) +
+ "/" + toString(PlayerInfo::getAttribute(MAX_HP)));
+ else
+ bar->setText(toString(PlayerInfo::getAttribute(HP)));
+
+ float prog = 1.0;
+
+ if (PlayerInfo::getAttribute(MAX_HP) > 0)
+ {
+ prog = static_cast<float>(PlayerInfo::getAttribute(HP))
+ / static_cast<float>(PlayerInfo::getAttribute(MAX_HP));
+ }
+ bar->setProgress(prog);
+}
+
+void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax)
+{
+ if (!bar)
+ return;
+
+ if (showMax)
+ {
+ bar->setText(toString(PlayerInfo::getAttribute(MP)) +
+ "/" + toString(PlayerInfo::getAttribute(MAX_MP)));
+ }
+ else
+ {
+ bar->setText(toString(PlayerInfo::getAttribute(MP)));
+ }
+
+ float prog = 1.0f;
+
+ if (PlayerInfo::getAttribute(MAX_MP) > 0)
+ {
+ if (PlayerInfo::getAttribute(MAX_MP))
+ {
+ prog = static_cast<float>(PlayerInfo::getAttribute(MP))
+ / static_cast<float>(PlayerInfo::getAttribute(MAX_MP));
+ }
+ else
+ {
+ prog = static_cast<float>(PlayerInfo::getAttribute(MP));
+ }
+ }
+
+ if (Net::getPlayerHandler()->canUseMagic())
+ bar->setProgressPalette(Theme::PROG_MP);
+ else
+ bar->setProgressPalette(Theme::PROG_NO_MP);
+
+ bar->setProgress(prog);
+}
+
+void StatusWindow::updateProgressBar(ProgressBar *bar, int value, int max,
+ bool percent)
+{
+ if (!bar)
+ return;
+
+ if (max == 0)
+ {
+ bar->setText(_("Max"));
+ bar->setProgress(1.0);
+ }
+ else
+ {
+ float progress = static_cast<float>(value)
+ / static_cast<float>(max);
+
+ if (percent)
+ bar->setText(strprintf("%2.5f", 100 * progress) + "%");
+ else
+ bar->setText(toString(value) + "/" + toString(max));
+
+ bar->setProgress(progress);
+ }
+}
+
+void StatusWindow::updateXPBar(ProgressBar *bar, bool percent)
+{
+ if (!bar)
+ return;
+
+ updateProgressBar(bar, PlayerInfo::getAttribute(EXP),
+ PlayerInfo::getAttribute(EXP_NEEDED), percent);
+}
+
+void StatusWindow::updateProgressBar(ProgressBar *bar, int id, bool percent)
+{
+ std::pair<int, int> exp = PlayerInfo::getStatExperience(id);
+ updateProgressBar(bar, exp.first, exp.second, percent);
+}
+
+void StatusWindow::updateStatusBar(ProgressBar *bar, bool percent _UNUSED_)
+{
+ if (!player_node || !viewport)
+ return;
+
+ std::string str;
+
+ switch (player_node->getInvertDirection())
+ {
+ case 0:
+ str = "D";
+ break;
+ case 1:
+ str = "I";
+ break;
+ case 2:
+ str = "c";
+ break;
+ case 3:
+ str = "C";
+ break;
+ case 4:
+ str = "d";
+ break;
+ default:
+ str = "?";
+ break;
+ }
+
+ if (player_node->getCrazyMoveType() < 10)
+ str += toString(player_node->getCrazyMoveType());
+ else
+ {
+ switch (player_node->getCrazyMoveType())
+ {
+ case 10:
+ str += "a";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+ }
+
+ switch (player_node->getMoveToTargetType())
+ {
+ case 0:
+ str += "0";
+ break;
+ case 1:
+ str += "1";
+ break;
+ case 2:
+ str += "2";
+ break;
+ case 3:
+ str += "3";
+ break;
+ case 4:
+ str += "5";
+ break;
+ case 5:
+ str += "7";
+ break;
+ case 6:
+ str += "A";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ switch (player_node->getFollowMode())
+ {
+ case 0:
+ str += "D";
+ break;
+ case 1:
+ str += "R";
+ break;
+ case 2:
+ str += "M";
+ break;
+ case 3:
+ str += "P";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ str += " ";
+ switch (player_node->getAttackWeaponType())
+ {
+ case 1:
+ str += "D";
+ break;
+ case 2:
+ str += "s";
+ break;
+ case 3:
+ str += "S";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ switch (player_node->getAttackType())
+ {
+ case 0:
+ str += "D";
+ break;
+ case 1:
+ str += "G";
+ break;
+ case 2:
+ str += "A";
+ break;
+ case 3:
+ str += "d";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ switch (player_node->getMagicAttackType())
+ {
+ case 0:
+ str += "f";
+ break;
+ case 1:
+ str += "c";
+ break;
+ case 2:
+ str += "I";
+ break;
+ case 3:
+ str += "F";
+ break;
+ case 4:
+ str += "U";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ str += " " + toString(player_node->getQuickDropCounter());
+
+ switch (player_node->getPickUpType())
+ {
+ case 0:
+ str += "S";
+ break;
+ case 1:
+ str += "D";
+ break;
+ case 2:
+ str += "F";
+ break;
+ case 3:
+ str += "3";
+ break;
+ case 4:
+ str += "g";
+ break;
+ case 5:
+ str += "G";
+ break;
+ case 6:
+ str += "A";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ switch (viewport->getDebugPath())
+ {
+ case 0:
+ str += " N";
+ break;
+ case 1:
+ str += " D";
+ break;
+ case 2:
+ str += " u";
+ break;
+ case 3:
+ str += " U";
+ break;
+ case 4:
+ str += " e";
+ break;
+ case 5:
+ str += " b";
+ break;
+ default:
+ str += " ?";
+ break;
+ }
+
+ switch (player_node->getImitationMode())
+ {
+ case 0:
+ str += " D";
+ break;
+ case 1:
+ str += " O";
+ break;
+ default:
+ str += " ?";
+ break;
+ }
+
+ switch (viewport->getCameraMode())
+ {
+ case 0:
+ str += "G";
+ break;
+ case 1:
+ str += "F";
+ break;
+ case 2:
+ str += "D";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ switch (player_node->getAwayMode())
+ {
+ case 0:
+ str += "O";
+ break;
+ case 1:
+ str += "A";
+ break;
+ default:
+ str += "?";
+ break;
+ }
+
+ bar->setText(str);
+ bar->setProgress(50);
+ if (player_node->getDisableGameModifiers())
+ {
+ gcn::Color col;
+ col.r = 100;
+ col.g = 100;
+ col.b = 100;
+// bar->setColor(new gcn::Color(100, 100, 100));
+ bar->setColor(col);
+ }
+ else
+ {
+ gcn::Color col;
+ col.r = 255;
+ col.g = 255;
+ col.b = 0;
+// bar->setColor(new gcn::Color(255, 255, 0));
+ bar->setColor(col);
+ }
+}
+
+AttrDisplay::AttrDisplay(int id, const std::string &name):
+ mId(id),
+ mName(name)
+{
+ setSize(100, 32);
+ mLabel = new Label(name);
+ mValue = new Label("1 ");
+
+ mLabel->setAlignment(Graphics::CENTER);
+ mValue->setAlignment(Graphics::CENTER);
+
+ mLayout = new LayoutHelper(this);
+}
+
+AttrDisplay::~AttrDisplay()
+{
+ delete mLayout;
+}
+
+std::string AttrDisplay::update()
+{
+ int base = PlayerInfo::getStatBase(mId);
+ int bonus = PlayerInfo::getStatMod(mId);
+ std::string value = toString(base + bonus);
+ if (bonus)
+ value += strprintf("=%d%+d", base, bonus);
+ mValue->setCaption(value);
+ return mName;
+}
+
+DerDisplay::DerDisplay(int id, const std::string &name):
+ AttrDisplay(id, name)
+{
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = mLayout->getPlacer(0, 0);
+
+ place(0, 0, mLabel, 3);
+ place(3, 0, mValue, 2);
+
+ update();
+}
+
+ChangeDisplay::ChangeDisplay(int id, const std::string &name):
+ AttrDisplay(id, name), mNeeded(1)
+{
+ mPoints = new Label(_("Max"));
+ mInc = new Button(_("+"), "inc", this);
+
+ // Do the layout
+ ContainerPlacer place = mLayout->getPlacer(0, 0);
+
+ place(0, 0, mLabel, 3);
+ place(4, 0, mValue, 2);
+ place(6, 0, mInc);
+ place(7, 0, mPoints);
+
+ if (Net::getPlayerHandler()->canCorrectAttributes())
+ {
+ mDec = new Button(_("-"), "dec", this);
+ mDec->setWidth(mInc->getWidth());
+
+ place(3, 0, mDec);
+ }
+ else
+ {
+ mDec = 0;
+ }
+
+ update();
+}
+
+std::string ChangeDisplay::update()
+{
+ if (mNeeded > 0)
+ mPoints->setCaption(toString(mNeeded));
+ else
+ mPoints->setCaption(_("Max"));
+
+ if (mDec)
+ mDec->setEnabled(PlayerInfo::getAttribute(CORR_POINTS));
+
+ mInc->setEnabled(PlayerInfo::getAttribute(CHAR_POINTS) >= mNeeded &&
+ mNeeded > 0);
+
+ return AttrDisplay::update();
+}
+
+void ChangeDisplay::setPointsNeeded(int needed)
+{
+ mNeeded = needed;
+
+ update();
+}
+
+void ChangeDisplay::action(const gcn::ActionEvent &event)
+{
+ if (Net::getPlayerHandler()->canCorrectAttributes() &&
+ event.getSource() == mDec)
+ {
+ int newcorpoints = PlayerInfo::getAttribute(CORR_POINTS) - 1;
+ PlayerInfo::setAttribute(CORR_POINTS, newcorpoints);
+
+ int newpoints = PlayerInfo::getAttribute(CHAR_POINTS) + 1;
+ PlayerInfo::setAttribute(CHAR_POINTS, newpoints);
+
+ int newbase = PlayerInfo::getStatBase(mId) - 1;
+ PlayerInfo::setStatBase(mId, newbase);
+
+ Net::getPlayerHandler()->decreaseAttribute(mId);
+ }
+ else if (event.getSource() == mInc)
+ {
+ int cnt = 1;
+ if (config.getBoolValue("quickStats"))
+ {
+ cnt = mInc->getClickCount();
+ if (cnt > 10)
+ cnt = 10;
+ }
+
+ int newpoints = PlayerInfo::getAttribute(CHAR_POINTS) - cnt;
+ PlayerInfo::setAttribute(CHAR_POINTS, newpoints);
+
+ int newbase = PlayerInfo::getStatBase(mId) + cnt;
+ PlayerInfo::setStatBase(mId, newbase);
+
+ for (unsigned f = 0; f < mInc->getClickCount(); f ++)
+ {
+ Net::getPlayerHandler()->increaseAttribute(mId);
+ if (cnt != 1)
+ SDL_Delay(100);
+ }
+ }
+}
diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h
new file mode 100644
index 000000000..4b324073e
--- /dev/null
+++ b/src/gui/statuswindow.h
@@ -0,0 +1,99 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef STATUS_H
+#define STATUS_H
+
+#include "guichanfwd.h"
+#include "listener.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <map>
+
+class AttrDisplay;
+class ProgressBar;
+class ScrollArea;
+class VertContainer;
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+/**
+ * The player status dialog.
+ *
+ * \ingroup Interface
+ */
+class StatusWindow : public Window, public Mana::Listener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ StatusWindow();
+
+ void event(Channels channel, const Mana::Event &event);
+
+ void setPointsNeeded(int id, int needed);
+
+ void addAttribute(int id, const std::string &name, bool modifiable,
+ const std::string &description);
+
+ static void updateHPBar(ProgressBar *bar, bool showMax = false);
+ static void updateMPBar(ProgressBar *bar, bool showMax = false);
+ static void updateXPBar(ProgressBar *bar, bool percent = true);
+ static void updateStatusBar(ProgressBar *bar, bool percent = true);
+ static void updateProgressBar(ProgressBar *bar, int value, int max,
+ bool percent);
+ void updateProgressBar(ProgressBar *bar, int id,
+ bool percent = true);
+
+ private:
+ /**
+ * Status Part
+ */
+ gcn::Label *mLvlLabel, *mMoneyLabel;
+ gcn::Label *mHpLabel, *mMpLabel, *mXpLabel;
+ ProgressBar *mHpBar, *mMpBar, *mXpBar;
+
+ gcn::Label *mJobLvlLabel, *mJobLabel;
+ ProgressBar *mJobBar;
+
+ VertContainer *mAttrCont;
+ ScrollArea *mAttrScroll;
+ VertContainer *mDAttrCont;
+ ScrollArea *mDAttrScroll;
+
+ gcn::Label *mCharacterPointsLabel;
+ gcn::Label *mCorrectionPointsLabel;
+
+ typedef std::map<int, AttrDisplay*> Attrs;
+ Attrs mAttrs;
+};
+
+extern StatusWindow *statusWindow;
+
+#endif
diff --git a/src/gui/textcommandeditor.cpp b/src/gui/textcommandeditor.cpp
new file mode 100644
index 000000000..2300033a5
--- /dev/null
+++ b/src/gui/textcommandeditor.cpp
@@ -0,0 +1,390 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/textcommandeditor.h"
+
+#include <SDL.h>
+#include <SDL_thread.h>
+#include <vector>
+#include <algorithm>
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/dropdown.h"
+#include "gui/widgets/inttextfield.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/radiobutton.h"
+#include "gui/widgets/table.h"
+#include "gui/widgets/textfield.h"
+
+#include "chat.h"
+#include "configuration.h"
+#include "item.h"
+#include "localplayer.h"
+#include "main.h"
+#include "keyboardconfig.h"
+#include "spellmanager.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
+
+class IconsModal : public gcn::ListModel
+{
+public:
+ IconsModal()
+ {
+ std::map<int, ItemInfo*> info = ItemDB::getItemInfos();
+ std::list<std::string> tempStrings;
+
+ for (std::map<int, ItemInfo*>::const_iterator
+ i = info.begin(), i_end = info.end();
+ i != i_end; ++i)
+ {
+ if (i->first < 0)
+ continue;
+
+ ItemInfo info = (*i->second);
+ std::string name = info.getName();
+ if (name != "unnamed" && !info.getName().empty()
+ && info.getName() != "unnamed")
+ {
+ tempStrings.push_back(name);
+ }
+ }
+ tempStrings.sort();
+ mStrings.push_back("");
+ for (std::list<std::string>::const_iterator i = tempStrings.begin(),
+ i_end = tempStrings.end(); i != i_end; ++i)
+ {
+ mStrings.push_back(*i);
+ }
+ }
+
+ virtual ~IconsModal()
+ {}
+
+ virtual int getNumberOfElements()
+ {
+ return static_cast<int>(mStrings.size());
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i < 0 || i >= getNumberOfElements())
+ return _("???");
+
+ return mStrings.at(i);
+ }
+private:
+ std::vector<std::string> mStrings;
+};
+
+
+const char *TARGET_TYPE_TEXT[3] =
+{
+ N_("No Target"),
+ N_("Allow Target"),
+ N_("Need Target"),
+};
+
+const char *MAGIC_SCHOOL_TEXT[6] =
+{
+ N_("General Magic"),
+ N_("Life Magic"),
+ N_("War Magic"),
+ N_("Transmute Magic"),
+ N_("Nature Magic"),
+ N_("Astral Magic")
+};
+
+class TargetTypeModel : public gcn::ListModel
+{
+public:
+ virtual ~TargetTypeModel() { }
+
+ virtual int getNumberOfElements()
+ {
+ return 3;
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return TARGET_TYPE_TEXT[i];
+ }
+};
+
+class MagicSchoolModel : public gcn::ListModel
+{
+public:
+ virtual ~MagicSchoolModel() { }
+
+ virtual int getNumberOfElements()
+ {
+ return 6;
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return MAGIC_SCHOOL_TEXT[i];
+ }
+};
+
+
+TextCommandEditor::TextCommandEditor(TextCommand *command):
+ Window(_("Command Editor"))
+{
+ int w = 350;
+ int h = 350;
+
+ mEnabledKeyboard = keyboard.isEnabled();
+ keyboard.setEnabled(false);
+
+ setWindowName("TextCommandEditor");
+ //setCloseButton(true);
+ setDefaultSize(w, h, ImageRect::CENTER);
+
+ mAdvanced = false;
+ mCommand = command;
+
+ mIsMagicCommand = (command->getCommandType() == TEXT_COMMAND_MAGIC);
+
+ mIsMagic = new RadioButton(_("magic"), "magic", mIsMagicCommand);
+ mIsMagic->setActionEventId("magic");
+ mIsMagic->addActionListener(this);
+
+ mIsOther = new RadioButton(_("other"), "magic", !mIsMagicCommand);
+ mIsOther->setActionEventId("other");
+ mIsOther->addActionListener(this);
+
+
+ mSymbolLabel = new Label(_("Symbol:"));
+ mSymbolTextField = new TextField();
+
+ mCommandLabel = new Label(_("Command:"));
+ mCommandTextField = new TextField();
+
+ mManaLabel = new Label(_("Mana:"));
+ mManaField = new IntTextField(0);
+ mManaField->setRange(0, 500);
+ mManaField->setWidth(20);
+
+ mTypeLabel = new Label(_("Target Type:"));
+ mTypeDropDown = new DropDown(new TargetTypeModel);
+ mTypeDropDown->setActionEventId("type");
+ mTypeDropDown->addActionListener(this);
+
+ mIconLabel = new Label(_("Icon:"));
+ mIconDropDown = new DropDown(new IconsModal);
+ mIconDropDown->setActionEventId("icon");
+ mIconDropDown->addActionListener(this);
+ mIconDropDown->setSelectedString(mCommand->getIcon());
+
+ mMagicLvlLabel = new Label(_("Magic level:"));
+ mMagicLvlField = new IntTextField(0);
+ mMagicLvlField->setRange(0, 5);
+ mMagicLvlField->setWidth(20);
+
+ mSchoolLabel = new Label(_("Magic School:"));
+ mSchoolDropDown = new DropDown(new MagicSchoolModel);
+ mSchoolDropDown->setActionEventId("school");
+ mSchoolDropDown->addActionListener(this);
+ mSchoolDropDown->setSelected(0);
+
+ mSchoolLvlLabel = new Label(_("School level:"));
+ mSchoolLvlField = new IntTextField(0);
+ mSchoolLvlField->setRange(0, 5);
+ mSchoolLvlField->setWidth(20);
+
+ mSaveButton = new Button(_("Save"), "save", this);
+ mSaveButton->adjustSize();
+
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mCancelButton->adjustSize();
+
+ mDeleteButton = new Button(_("Delete"), "delete", this);
+ mDeleteButton->adjustSize();
+
+ if (command->getCommandType() == TEXT_COMMAND_MAGIC)
+ showControls(true);
+ else
+ showControls(false);
+
+ mSymbolTextField->setText(command->getSymbol());
+ mCommandTextField->setText(command->getCommand());
+ mManaField->setValue(command->getMana());
+ mTypeDropDown->setSelected(command->getTargetType());
+ mMagicLvlField->setValue(command->getBaseLvl());
+ mSchoolDropDown->setSelected(command->getSchool() - MAGIC_START_ID);
+ mSchoolLvlField->setValue(command->getSchoolLvl());
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mIsMagic, 1);
+ place(2, 0, mIsOther, 1);
+ place(0, 1, mSymbolLabel, 2).setPadding(3);
+ place(2, 1, mSymbolTextField, 3).setPadding(3);
+ place(0, 2, mCommandLabel, 2).setPadding(3);
+ place(2, 2, mCommandTextField, 4).setPadding(3);
+ place(0, 3, mTypeLabel, 2).setPadding(3);
+ place(2, 3, mTypeDropDown, 3).setPadding(3);
+
+ place(0, 4, mIconLabel, 2).setPadding(3);
+ place(2, 4, mIconDropDown, 3).setPadding(3);
+
+ place(0, 5, mManaLabel, 2).setPadding(3);
+ place(2, 5, mManaField, 3).setPadding(3);
+ place(0, 6, mMagicLvlLabel, 2).setPadding(3);
+ place(2, 6, mMagicLvlField, 3).setPadding(3);
+
+ place(0, 7, mSchoolLabel, 2).setPadding(3);
+ place(2, 7, mSchoolDropDown, 3).setPadding(3);
+ place(0, 8, mSchoolLvlLabel, 2).setPadding(3);
+ place(2, 8, mSchoolLvlField, 3).setPadding(3);
+
+ place(0, 9, mSaveButton, 2).setPadding(3);
+ place(2, 9, mCancelButton, 2).setPadding(3);
+ place(4, 9, mDeleteButton, 2).setPadding(3);
+
+ setWidth(w);
+ setHeight(h);
+
+ center();
+
+ setVisible(true);
+}
+
+TextCommandEditor::~TextCommandEditor()
+{
+}
+
+void TextCommandEditor::action(const gcn::ActionEvent &event)
+{
+ const std::string &eventId = event.getId();
+
+ if (eventId == "magic")
+ {
+ mIsMagicCommand = true;
+ showControls(true);
+ }
+ else if (eventId == "other")
+ {
+ mIsMagicCommand = false;
+ showControls(false);
+ }
+ else if (eventId == "save")
+ {
+ save();
+ scheduleDelete();
+ }
+ else if (eventId == "cancel")
+ {
+ scheduleDelete();
+ }
+ else if (eventId == "delete")
+ {
+ deleteCommand();
+ scheduleDelete();
+ }
+}
+
+void TextCommandEditor::update()
+{
+}
+
+void TextCommandEditor::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+}
+
+void TextCommandEditor::updateList()
+{
+}
+
+void TextCommandEditor::reset()
+{
+}
+
+void TextCommandEditor::showControls(bool show)
+{
+ mManaField->setVisible(show);
+ mManaLabel->setVisible(show);
+ mMagicLvlLabel->setVisible(show);
+ mMagicLvlField->setVisible(show);
+ mSchoolLabel->setVisible(show);
+ mSchoolDropDown->setVisible(show);
+ mSchoolLvlLabel->setVisible(show);
+ mSchoolLvlField->setVisible(show);
+}
+
+void TextCommandEditor::scheduleDelete()
+{
+ keyboard.setEnabled(mEnabledKeyboard);
+ Window::scheduleDelete();
+}
+
+void TextCommandEditor::save()
+{
+ if (mIsMagicCommand)
+ mCommand->setCommandType(TEXT_COMMAND_MAGIC);
+ else
+ mCommand->setCommandType(TEXT_COMMAND_TEXT);
+
+ mCommand->setSymbol(mSymbolTextField->getText());
+ mCommand->setCommand(mCommandTextField->getText());
+ mCommand->setMana(mManaField->getValue());
+ mCommand->setTargetType(
+ static_cast<SpellTarget>(mTypeDropDown->getSelected()));
+ mCommand->setIcon(mIconDropDown->getSelectedString());
+ mCommand->setBaseLvl(mMagicLvlField->getValue());
+ mCommand->setSchool(static_cast<MagicSchool>(
+ mSchoolDropDown->getSelected() + MAGIC_START_ID));
+ mCommand->setSchoolLvl(mSchoolLvlField->getValue());
+ if (spellManager)
+ spellManager->save();
+}
+
+void TextCommandEditor::deleteCommand()
+{
+ mCommand->setCommandType(TEXT_COMMAND_TEXT);
+ mCommand->setSymbol("");
+ mCommand->setCommand("");
+ mCommand->setMana(0);
+ mCommand->setTargetType(NOTARGET);
+ mCommand->setIcon("");
+ mCommand->setBaseLvl(0);
+ mCommand->setSchool(SKILL_MAGIC);
+ mCommand->setSchoolLvl(0);
+ if (spellManager)
+ spellManager->save();
+}
diff --git a/src/gui/textcommandeditor.h b/src/gui/textcommandeditor.h
new file mode 100644
index 000000000..9f8c0ad51
--- /dev/null
+++ b/src/gui/textcommandeditor.h
@@ -0,0 +1,105 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TEXTCOMMANDEDITOR_H
+#define TEXTCOMMANDEDITOR_H
+
+#include "gui/widgets/window.h"
+
+#include "textcommand.h"
+
+#include <guichan/actionlistener.hpp>
+
+class RadioButton;
+class Label;
+class TextBox;
+class TextField;
+class DropDown;
+class ListModel;
+class Button;
+class TextCommand;
+class IntTextField;
+
+class TextCommandEditor : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ TextCommandEditor(TextCommand *command);
+
+ /**
+ * Destructor.
+ */
+ ~TextCommandEditor();
+
+ void action(const gcn::ActionEvent &event);
+
+ void update();
+
+ void widgetResized(const gcn::Event &event);
+
+ void updateList();
+
+ void reset();
+
+ void scheduleDelete();
+
+ private:
+ void showControls(bool show);
+
+ void save();
+
+ void deleteCommand();
+
+ TextCommand *mCommand;
+ bool mAdvanced;
+
+ RadioButton *mIsMagic;
+ RadioButton *mIsOther;
+ Label *mSymbolLabel;
+ TextField *mSymbolTextField;
+ Label *mCommandLabel;
+ TextField *mCommandTextField;
+ Label *mTypeLabel;
+ DropDown *mTypeDropDown;
+ Label *mIconLabel;
+ DropDown *mIconDropDown;
+ Label *mManaLabel;
+ IntTextField *mManaField;
+ Label *mMagicLvlLabel;
+ IntTextField *mMagicLvlField;
+ Label *mSchoolLabel;
+ DropDown *mSchoolDropDown;
+ Label *mSchoolLvlLabel;
+ IntTextField *mSchoolLvlField;
+
+ //Button *mAdvancedButton;
+ Button *mCancelButton;
+ Button *mSaveButton;
+ Button *mDeleteButton;
+
+ bool mEnabledKeyboard;
+ bool mIsMagicCommand;
+};
+
+#endif
diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp
new file mode 100644
index 000000000..c47e028c4
--- /dev/null
+++ b/src/gui/textdialog.cpp
@@ -0,0 +1,94 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/textdialog.h"
+
+#include "keyboardconfig.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/textfield.h"
+
+#include "utils/gettext.h"
+
+int TextDialog::instances = 0;
+
+TextDialog::TextDialog(const std::string &title, const std::string &msg,
+ Window *parent):
+ Window(title, true, parent),
+ mTextField(new TextField)
+{
+ mEnabledKeyboard = keyboard.isEnabled();
+ keyboard.setEnabled(false);
+
+ gcn::Label *textLabel = new Label(msg);
+ mOkButton = new Button(_("OK"), "OK", this);
+ gcn::Button *cancelButton = new Button(_("Cancel"), "CANCEL", this);
+
+ place(0, 0, textLabel, 4);
+ place(0, 1, mTextField, 4);
+ place(2, 2, mOkButton);
+ place(3, 2, cancelButton);
+
+ reflowLayout(static_cast<short>(textLabel->getWidth() + 20));
+
+ if (getParent())
+ {
+ setLocationRelativeTo(getParent());
+ getParent()->moveToTop(this);
+ }
+ setVisible(true);
+ requestModalFocus();
+ mTextField->requestFocus();
+
+ instances++;
+}
+
+TextDialog::~TextDialog()
+{
+ instances--;
+}
+
+void TextDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "CANCEL")
+ setActionEventId("~" + getActionEventId());
+
+ distributeActionEvent();
+ close();
+}
+
+const std::string &TextDialog::getText() const
+{
+ return mTextField->getText();
+}
+
+void TextDialog::setText(std::string text)
+{
+ if (mTextField)
+ mTextField->setText(text);
+}
+
+void TextDialog::close()
+{
+ keyboard.setEnabled(mEnabledKeyboard);
+ scheduleDelete();
+} \ No newline at end of file
diff --git a/src/gui/textdialog.h b/src/gui/textdialog.h
new file mode 100644
index 000000000..9c7e8d312
--- /dev/null
+++ b/src/gui/textdialog.h
@@ -0,0 +1,74 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_GUILD_DIALOG_H
+#define GUI_GUILD_DIALOG_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class TextField;
+
+/**
+* An option dialog.
+ *
+ * \ingroup GUI
+ */
+class TextDialog : public Window, public gcn::ActionListener
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ TextDialog(const std::string &title, const std::string &msg,
+ Window *parent = 0);
+
+ ~TextDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Get the text in the textfield
+ */
+ const std::string &getText() const;
+
+ void setText(std::string text);
+
+ static bool isActive()
+ { return instances; }
+
+ void close();
+
+private:
+ static int instances;
+
+ TextField *mTextField;
+ gcn::Button *mOkButton;
+ bool mEnabledKeyboard;
+};
+
+#endif
diff --git a/src/gui/textpopup.cpp b/src/gui/textpopup.cpp
new file mode 100644
index 000000000..270b0f759
--- /dev/null
+++ b/src/gui/textpopup.cpp
@@ -0,0 +1,99 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/textpopup.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+
+#include "graphics.h"
+#include "units.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+#include <guichan/widgets/label.hpp>
+
+TextPopup::TextPopup():
+ Popup("TextPopup")
+{
+ const int fontHeight = getFont()->getHeight();
+
+ mText1 = new gcn::Label;
+ mText1->setPosition(getPadding(), getPadding());
+
+ mText2 = new gcn::Label;
+ mText2->setPosition(getPadding(), fontHeight + 2 * getPadding());
+
+ add(mText1);
+ add(mText2);
+ addMouseListener(this);
+}
+
+TextPopup::~TextPopup()
+{
+}
+
+void TextPopup::show(int x, int y, const std::string &str1,
+ const std::string &str2)
+{
+ mText1->setCaption(str1);
+ mText1->adjustSize();
+ mText2->setCaption(str2);
+ mText2->adjustSize();
+
+ int minWidth = mText1->getWidth();
+ if (mText2->getWidth() > minWidth)
+ minWidth = mText2->getWidth();
+
+ minWidth += 4 * getPadding();
+ setWidth(minWidth);
+
+ if (!str2.empty())
+ setHeight((2 * getPadding() + mText1->getFont()->getHeight()) * 2);
+ else
+ setHeight(2 * getPadding() + mText1->getFont()->getHeight());
+
+ const int distance = 20;
+
+ int posX = std::max(0, x - getWidth() / 2);
+ int posY = y + distance;
+
+ if (posX + getWidth() > graphics->getWidth())
+ posX = graphics->getWidth() - getWidth();
+ if (posY + getHeight() > graphics->getHeight())
+ posY = y - getHeight() - distance;
+
+ setPosition(posX, posY);
+ setVisible(true);
+ requestMoveToTop();
+}
+
+void TextPopup::mouseMoved(gcn::MouseEvent &event)
+{
+ Popup::mouseMoved(event);
+
+ // When the mouse moved on top of the popup, hide it
+ setVisible(false);
+}
diff --git a/src/gui/textpopup.h b/src/gui/textpopup.h
new file mode 100644
index 000000000..3b4158f6e
--- /dev/null
+++ b/src/gui/textpopup.h
@@ -0,0 +1,68 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TEXTPOPUP_H
+#define TEXTPOPUP_H
+
+#include "gui/widgets/popup.h"
+
+#include <guichan/mouselistener.hpp>
+
+class TextBox;
+
+/**
+ * A popup that displays information about an item.
+ */
+class TextPopup : public Popup
+{
+ public:
+ /**
+ * Constructor. Initializes the item popup.
+ */
+ TextPopup();
+
+ /**
+ * Destructor. Cleans up the item popup on deletion.
+ */
+ ~TextPopup();
+
+ /**
+ * Sets the text to be displayed.
+ */
+ void show(int x, int y, const std::string &str1)
+ { show(x, y, str1, static_cast<const char*>("")); };
+
+ /**
+ * Sets the text to be displayed.
+ */
+ void show(int x, int y, const std::string &str1,
+ const std::string &str2);
+
+ void mouseMoved(gcn::MouseEvent &mouseEvent);
+
+ private:
+ gcn::Label *mText1;
+ gcn::Label *mText2;
+};
+
+#endif // TEXTPOPUP_H
diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp
new file mode 100644
index 000000000..b45cef5b0
--- /dev/null
+++ b/src/gui/theme.cpp
@@ -0,0 +1,791 @@
+/*
+ * Gui Skinning
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2009 Aethyra Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/theme.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "log.h"
+
+#include "resources/dye.h"
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/dtor.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <physfs.h>
+
+#include <algorithm>
+#include <physfs.h>
+
+static std::string defaultThemePath;
+
+std::string Theme::mThemePath;
+std::string Theme::mThemeName;
+Theme *Theme::mInstance = 0;
+
+// Set the theme path...
+static void initDefaultThemePath()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ defaultThemePath = branding.getStringValue("guiThemePath");
+
+ logger->log("defaultThemePath: " + defaultThemePath);
+ if (!defaultThemePath.empty() && resman->isDirectory(defaultThemePath))
+ return;
+ else
+ defaultThemePath = "themes/";
+}
+
+Skin::Skin(ImageRect skin, Image *close, Image *stickyUp, Image *stickyDown,
+ const std::string &filePath,
+ const std::string &name):
+ instances(0),
+ mFilePath(filePath),
+ mName(name),
+ mBorder(skin),
+ mCloseImage(close),
+ mStickyImageUp(stickyUp),
+ mStickyImageDown(stickyDown)
+{}
+
+Skin::~Skin()
+{
+ // Clean up static resources
+ for (int i = 0; i < 9; i++)
+ {
+ delete mBorder.grid[i];
+ mBorder.grid[i] = 0;
+ }
+
+ if (mCloseImage)
+ {
+ mCloseImage->decRef();
+ mCloseImage = 0;
+ }
+ delete mStickyImageUp;
+ mStickyImageUp = 0;
+ delete mStickyImageDown;
+ mStickyImageDown = 0;
+}
+
+void Skin::updateAlpha(float minimumOpacityAllowed)
+{
+ const float alpha = static_cast<float>(
+ std::max(static_cast<double>(minimumOpacityAllowed),
+ static_cast<double>(Client::getGuiAlpha())));
+
+ for_each(mBorder.grid, mBorder.grid + 9,
+ std::bind2nd(std::mem_fun(&Image::setAlpha), alpha));
+
+ if (mCloseImage)
+ mCloseImage->setAlpha(alpha);
+ if (mStickyImageUp)
+ mStickyImageUp->setAlpha(alpha);
+ if (mStickyImageDown)
+ mStickyImageDown->setAlpha(alpha);
+}
+
+int Skin::getMinWidth() const
+{
+ if (!mBorder.grid[ImageRect::UPPER_LEFT]
+ || !mBorder.grid[ImageRect::UPPER_RIGHT])
+ {
+ return 1;
+ }
+
+ return mBorder.grid[ImageRect::UPPER_LEFT]->getWidth() +
+ mBorder.grid[ImageRect::UPPER_RIGHT]->getWidth();
+}
+
+int Skin::getMinHeight() const
+{
+ if (!mBorder.grid[ImageRect::UPPER_LEFT]
+ || !mBorder.grid[ImageRect::LOWER_LEFT])
+ {
+ return 1;
+ }
+
+ return mBorder.grid[ImageRect::UPPER_LEFT]->getHeight() +
+ mBorder.grid[ImageRect::LOWER_LEFT]->getHeight();
+}
+
+Theme::Theme():
+ Palette(THEME_COLORS_END),
+ mMinimumOpacity(-1.0f),
+ mProgressColors(ProgressColors(THEME_PROG_END))
+{
+ initDefaultThemePath();
+
+ config.addListener("guialpha", this);
+ loadColors();
+
+ mColors[HIGHLIGHT].ch = 'H';
+ mColors[CHAT].ch = 'C';
+ mColors[GM].ch = 'G';
+ mColors[PLAYER].ch = 'Y';
+ mColors[WHISPER].ch = 'W';
+ mColors[WHISPER_OFFLINE].ch = 'w';
+ mColors[IS].ch = 'I';
+ mColors[PARTY_CHAT_TAB].ch = 'P';
+ mColors[GUILD_CHAT_TAB].ch = 'U';
+ mColors[SERVER].ch = 'S';
+ mColors[LOGGER].ch = 'L';
+ mColors[HYPERLINK].ch = '<';
+}
+
+Theme::~Theme()
+{
+ delete_all(mSkins);
+ config.removeListener("guialpha", this);
+ delete_all(mProgressColors);
+}
+
+Theme *Theme::instance()
+{
+ if (!mInstance)
+ mInstance = new Theme;
+
+ return mInstance;
+}
+
+void Theme::deleteInstance()
+{
+ delete mInstance;
+ mInstance = 0;
+}
+
+gcn::Color Theme::getProgressColor(int type, float progress)
+{
+ int color[3] = {0, 0, 0};
+
+ if (mInstance)
+ {
+ DyePalette *dye = mInstance->mProgressColors[type];
+
+ if (dye)
+ dye->getColor(progress, color);
+ else
+ logger->log("color not found: " + toString(type));
+ }
+
+ return gcn::Color(color[0], color[1], color[2]);
+}
+
+Skin *Theme::load(const std::string &filename, const std::string &defaultPath)
+{
+ // Check if this skin was already loaded
+
+ SkinIterator skinIterator = mSkins.find(filename);
+ if (mSkins.end() != skinIterator)
+ {
+ if (skinIterator->second)
+ skinIterator->second->instances++;
+ return skinIterator->second;
+ }
+
+ Skin *skin = readSkin(filename);
+
+ if (!skin)
+ {
+ // Try falling back on the defaultPath if this makes sense
+ if (filename != defaultPath)
+ {
+ logger->log("Error loading skin '%s', falling back on default.",
+ filename.c_str());
+
+ skin = readSkin(defaultPath);
+ }
+
+ if (!skin)
+ {
+ logger->log(strprintf("Error: Loading default skin '%s' failed. "
+ "Make sure the skin file is valid.",
+ defaultPath.c_str()));
+ }
+ }
+
+ // Add the skin to the loaded skins
+ mSkins[filename] = skin;
+
+ return skin;
+}
+
+void Theme::setMinimumOpacity(float minimumOpacity)
+{
+ if (minimumOpacity > 1.0f)
+ return;
+
+ mMinimumOpacity = minimumOpacity;
+ updateAlpha();
+}
+
+void Theme::updateAlpha()
+{
+ for (SkinIterator iter = mSkins.begin(); iter != mSkins.end(); ++iter)
+ {
+ if (iter->second)
+ iter->second->updateAlpha(mMinimumOpacity);
+ }
+}
+
+void Theme::optionChanged(const std::string &)
+{
+ updateAlpha();
+}
+
+Skin *Theme::readSkin(const std::string &filename)
+{
+ if (filename.empty())
+ return 0;
+
+// std::string filename = filename0;
+// ResourceManager *resman = ResourceManager::getInstance();
+ logger->log("Loading skin '%s'.", filename.c_str());
+// filename = resman->mapPathToSkin(filename0);
+
+ XML::Document doc(resolveThemePath(filename));
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
+ return 0;
+
+ const std::string skinSetImage = XML::getProperty(rootNode, "image", "");
+
+ if (skinSetImage.empty())
+ {
+ logger->log1("Theme::readSkin(): Skinset does not define an image!");
+ return 0;
+ }
+
+ logger->log("Theme::load(): <skinset> defines '%s' as a skin image.",
+ skinSetImage.c_str());
+
+ Image *dBorders = Theme::getImageFromTheme(skinSetImage);
+ ImageRect border;
+ memset(&border, 0, sizeof(ImageRect));
+
+ // iterate <widget>'s
+ for_each_xml_child_node(widgetNode, rootNode)
+ {
+ if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget"))
+ continue;
+
+ const std::string widgetType =
+ XML::getProperty(widgetNode, "type", "unknown");
+ if (widgetType == "Window")
+ {
+ // Iterate through <part>'s
+ // LEEOR / TODO:
+ // We need to make provisions to load in a CloseButton image. For
+ // now it can just be hard-coded.
+ for_each_xml_child_node(partNode, widgetNode)
+ {
+ if (!xmlStrEqual(partNode->name, BAD_CAST "part"))
+ continue;
+
+ const std::string partType =
+ XML::getProperty(partNode, "type", "unknown");
+ // TOP ROW
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ if (partType == "top-left-corner")
+ {
+ if (dBorders)
+ {
+ border.grid[0] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[0] = 0;
+ }
+ }
+ else if (partType == "top-edge")
+ {
+ if (dBorders)
+ {
+ border.grid[1] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[1] = 0;
+ }
+ }
+ else if (partType == "top-right-corner")
+ {
+ if (dBorders)
+ {
+ border.grid[2] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[2] = 0;
+ }
+ }
+
+ // MIDDLE ROW
+ else if (partType == "left-edge")
+ {
+ if (dBorders)
+ {
+ border.grid[3] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[3] = 0;
+ }
+ }
+ else if (partType == "bg-quad")
+ {
+ if (dBorders)
+ {
+ border.grid[4] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[4] = 0;
+ }
+ }
+ else if (partType == "right-edge")
+ {
+ if (dBorders)
+ {
+ border.grid[5] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[5] = 0;
+ }
+ }
+
+ // BOTTOM ROW
+ else if (partType == "bottom-left-corner")
+ {
+ if (dBorders)
+ {
+ border.grid[6] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[6] = 0;
+ }
+ }
+ else if (partType == "bottom-edge")
+ {
+ if (dBorders)
+ {
+ border.grid[7] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[7] = 0;
+ }
+ }
+ else if (partType == "bottom-right-corner")
+ {
+ if (dBorders)
+ {
+ border.grid[8] = dBorders->getSubImage(
+ xPos, yPos, width, height);
+ }
+ else
+ {
+ border.grid[8] = 0;
+ }
+ }
+
+ else
+ {
+ logger->log("Theme::readSkin(): Unknown part type '%s'",
+ partType.c_str());
+ }
+ }
+ }
+ else
+ {
+ logger->log("Theme::readSkin(): Unknown widget type '%s'",
+ widgetType.c_str());
+ }
+ }
+
+ if (dBorders)
+ dBorders->decRef();
+
+ logger->log1("Finished loading skin.");
+
+ // Hard-coded for now until we update the above code
+ // to look for window buttons
+ Image *closeImage = Theme::getImageFromTheme("close_button.png");
+ Image *sticky = Theme::getImageFromTheme("sticky_button.png");
+ Image *stickyImageUp = 0;
+ Image *stickyImageDown = 0;
+ if (sticky)
+ {
+ stickyImageUp = sticky->getSubImage(0, 0, 15, 15);
+ stickyImageDown = sticky->getSubImage(15, 0, 15, 15);
+ sticky->decRef();
+ }
+
+ Skin *skin = new Skin(border, closeImage, stickyImageUp, stickyImageDown,
+ filename);
+ skin->updateAlpha(mMinimumOpacity);
+ return skin;
+}
+
+bool Theme::tryThemePath(std::string themeName)
+{
+ if (!themeName.empty())
+ {
+ std::string path = defaultThemePath + themeName;
+ if (PHYSFS_exists(path.c_str()))
+ {
+ mThemePath = path;
+ mThemeName = themeName;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void Theme::fillSkinsList(std::vector<std::string> &list)
+{
+ char **skins = PHYSFS_enumerateFiles(
+ branding.getStringValue("guiThemePath").c_str());
+
+ for (char **i = skins; *i != 0; i++)
+ {
+ if (PHYSFS_isDirectory((
+ branding.getStringValue("guiThemePath") + *i).c_str()))
+ {
+ list.push_back(*i);
+ }
+ }
+
+ PHYSFS_freeList(skins);
+}
+
+void Theme::fillFontsList(std::vector<std::string> &list)
+{
+ PHYSFS_permitSymbolicLinks(1);
+ char **fonts = PHYSFS_enumerateFiles(
+ branding.getStringValue("fontsPath").c_str());
+
+ for (char **i = fonts; *i != 0; i++)
+ {
+ if (!PHYSFS_isDirectory((
+ branding.getStringValue("fontsPath") + *i).c_str()))
+ {
+ list.push_back(*i);
+ }
+ }
+
+ PHYSFS_freeList(fonts);
+ PHYSFS_permitSymbolicLinks(0);
+}
+
+void Theme::selectSkin()
+{
+ prepareThemePath();
+}
+
+void Theme::prepareThemePath()
+{
+ initDefaultThemePath();
+
+ mThemePath = "";
+ mThemeName = "";
+
+ // Try theme from settings
+ if (tryThemePath(config.getValue("selectedSkin", "")))
+ return;
+
+ // Try theme from settings
+ if (tryThemePath(config.getValue("theme", "")))
+ return;
+
+ // Try theme from branding
+ if (tryThemePath(branding.getValue("theme", "")))
+ return;
+
+ if (mThemePath.empty())
+ mThemePath = "graphics/gui";
+
+ instance()->loadColors(mThemePath);
+
+ logger->log("Selected Theme: " + mThemePath);
+}
+
+std::string Theme::resolveThemePath(const std::string &path)
+{
+ // Need to strip off any dye info for the existence tests
+ int pos = static_cast<int>(path.find('|'));
+ std::string file;
+ if (pos > 0)
+ file = path.substr(0, pos);
+ else
+ file = path;
+
+ // Might be a valid path already
+ if (PHYSFS_exists(file.c_str()))
+ return path;
+
+ // Try the theme
+ file = getThemePath() + "/" + file;
+ if (PHYSFS_exists(file.c_str()))
+ return getThemePath() + "/" + path;
+
+ // Backup
+ return branding.getStringValue("guiPath") + path;
+}
+
+Image *Theme::getImageFromTheme(const std::string &path)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ return resman->getImage(resolveThemePath(path));
+}
+
+ImageSet *Theme::getImageSetFromTheme(const std::string &path,
+ int w, int h)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ return resman->getImageSet(resolveThemePath(path), w, h);
+}
+
+static int readColorType(const std::string &type)
+{
+ static std::string colors[] =
+ {
+ "TEXT",
+ "SHADOW",
+ "OUTLINE",
+ "PROGRESS_BAR",
+ "BUTTON",
+ "BUTTON_DISABLED",
+ "TAB",
+ "PARTY_CHAT_TAB",
+ "PARTY_SOCIAL_TAB",
+ "GUILD_CHAT_TAB",
+ "GUILD_SOCIAL_TAB",
+ "BACKGROUND",
+ "HIGHLIGHT",
+ "TAB_FLASH",
+ "TAB_PLAYER_FLASH",
+ "SHOP_WARNING",
+ "ITEM_EQUIPPED",
+ "CHAT",
+ "GM",
+ "PLAYER",
+ "WHISPER",
+ "WHISPER_OFFLINE",
+ "IS",
+ "SERVER",
+ "LOGGER",
+ "HYPERLINK",
+ "UNKNOWN_ITEM",
+ "GENERIC",
+ "HEAD",
+ "USABLE",
+ "TORSO",
+ "ONEHAND",
+ "LEGS",
+ "FEET",
+ "TWOHAND",
+ "SHIELD",
+ "RING",
+ "NECKLACE",
+ "ARMS",
+ "AMMO",
+ "SERVER_VERSION_NOT_SUPPORTED",
+ "WARNING"
+ };
+
+ if (type.empty())
+ return -1;
+
+ for (int i = 0; i < Theme::THEME_COLORS_END; i++)
+ {
+ if (compareStrI(type, colors[i]) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+static gcn::Color readColor(const std::string &description)
+{
+ int size = static_cast<int>(description.length());
+ if (size < 7 || description[0] != '#')
+ {
+ logger->log("Error, invalid theme color palette: %s",
+ description.c_str());
+ return Palette::BLACK;
+ }
+
+ int v = 0;
+ for (int i = 1; i < 7; ++i)
+ {
+ char c = description[i];
+ int n;
+
+ if ('0' <= c && c <= '9')
+ {
+ n = c - '0';
+ }
+ else if ('A' <= c && c <= 'F')
+ {
+ n = c - 'A' + 10;
+ }
+ else if ('a' <= c && c <= 'f')
+ {
+ n = c - 'a' + 10;
+ }
+ else
+ {
+ logger->log("Error, invalid theme color palette: %s",
+ description.c_str());
+ return Palette::BLACK;
+ }
+
+ v = (v << 4) | n;
+ }
+
+ return gcn::Color(v);
+}
+
+static Palette::GradientType readColorGradient(const std::string &grad)
+{
+ static std::string grads[] =
+ {
+ "STATIC",
+ "PULSE",
+ "SPECTRUM",
+ "RAINBOW"
+ };
+
+ if (grad.empty())
+ return Palette::STATIC;
+
+ for (int i = 0; i < 4; i++)
+ {
+ if (compareStrI(grad, grads[i]))
+ return static_cast<Palette::GradientType>(i);
+ }
+
+ return Palette::STATIC;
+}
+
+static int readProgressType(const std::string &type)
+{
+ static std::string colors[] =
+ {
+ "DEFAULT",
+ "HP",
+ "MP",
+ "NO_MP",
+ "EXP",
+ "INVY_SLOTS",
+ "WEIGHT",
+ "JOB"
+ };
+
+ if (type.empty())
+ return -1;
+
+ for (int i = 0; i < Theme::THEME_PROG_END; i++)
+ {
+ if (compareStrI(type, colors[i]) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+void Theme::loadColors(std::string file)
+{
+// if (file == mThemePath)
+// return; // No need to reload
+
+ if (file == "")
+ file = "colors.xml";
+ else
+ file += "/colors.xml";
+
+ XML::Document doc(resolveThemePath(file));
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
+ {
+ logger->log("Error loading colors file: %s", file.c_str());
+ return;
+ }
+
+ logger->log("Loading colors file: %s", file.c_str());
+
+ int type;
+ std::string temp;
+ gcn::Color color;
+ GradientType grad;
+
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "color"))
+ {
+ type = readColorType(XML::getProperty(node, "id", ""));
+ if (type < 0) // invalid or no type given
+ continue;
+
+ temp = XML::getProperty(node, "color", "");
+ if (temp.empty()) // no color set, so move on
+ continue;
+
+ color = readColor(temp);
+ grad = readColorGradient(XML::getProperty(node, "effect", ""));
+
+ mColors[type].set(type, color, grad, 10);
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "progressbar"))
+ {
+ type = readProgressType(XML::getProperty(node, "id", ""));
+ if (type < 0) // invalid or no type given
+ continue;
+
+ mProgressColors[type] = new DyePalette(XML::getProperty(node,
+ "color", ""));
+ }
+ }
+}
diff --git a/src/gui/theme.h b/src/gui/theme.h
new file mode 100644
index 000000000..bb7a66f85
--- /dev/null
+++ b/src/gui/theme.h
@@ -0,0 +1,273 @@
+/*
+ * Gui Skinning
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2009 Aethyra Development Team
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SKIN_H
+#define SKIN_H
+
+#include "configlistener.h"
+#include "graphics.h"
+
+#include "gui/palette.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class DyePalette;
+class Image;
+class ImageSet;
+class ProgressBar;
+
+class Skin
+{
+ public:
+ Skin(ImageRect skin, Image *close, Image *stickyUp, Image *stickyDown,
+ const std::string &filePath,
+ const std::string &name = "");
+
+ ~Skin();
+
+ /**
+ * Returns the skin's name. Useful for giving a human friendly skin
+ * name if a dialog for skin selection for a specific window type is
+ * done.
+ */
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Returns the skin's xml file path.
+ */
+ const std::string &getFilePath() const
+ { return mFilePath; }
+
+ /**
+ * Returns the background skin.
+ */
+ const ImageRect &getBorder() const
+ { return mBorder; }
+
+ /**
+ * Returns the image used by a close button for this skin.
+ */
+ Image *getCloseImage() const
+ { return mCloseImage; }
+
+ /**
+ * Returns the image used by a sticky button for this skin.
+ */
+ Image *getStickyImage(bool state) const
+ { return state ? mStickyImageDown : mStickyImageUp; }
+
+ /**
+ * Returns the minimum width which can be used with this skin.
+ */
+ int getMinWidth() const;
+
+ /**
+ * Returns the minimum height which can be used with this skin.
+ */
+ int getMinHeight() const;
+
+ /**
+ * Updates the alpha value of the skin
+ */
+ void updateAlpha(float minimumOpacityAllowed = 0.0f);
+
+ int instances;
+
+ private:
+ std::string mFilePath; /**< File name path for the skin */
+ std::string mName; /**< Name of the skin to use */
+ ImageRect mBorder; /**< The window border and background */
+ Image *mCloseImage; /**< Close Button Image */
+ Image *mStickyImageUp; /**< Sticky Button Image */
+ Image *mStickyImageDown; /**< Sticky Button Image */
+};
+
+class Theme : public Palette, public ConfigListener
+{
+ public:
+ static Theme *instance();
+
+ static void deleteInstance();
+
+ static void prepareThemePath();
+
+ static void selectSkin();
+
+ static std::string getThemePath()
+ { return mThemePath; }
+
+ static std::string getThemeName()
+ { return mThemeName; }
+
+ static void fillSkinsList(std::vector<std::string> &list);
+
+ static void fillFontsList(std::vector<std::string> &list);
+
+ /**
+ * Returns the patch to the given gui resource relative to the theme
+ * or, if it isn't in the theme, relative to 'graphics/gui'.
+ */
+ static std::string resolveThemePath(const std::string &path);
+
+ static Image *getImageFromTheme(const std::string &path);
+
+ static ImageSet *getImageSetFromTheme(const std::string &path,
+ int w, int h);
+
+ enum ThemePalette
+ {
+ TEXT = 0,
+ SHADOW,
+ OUTLINE,
+ PROGRESS_BAR,
+ BUTTON,
+ BUTTON_DISABLED,
+ TAB,
+ PARTY_CHAT_TAB,
+ PARTY_SOCIAL_TAB,
+ GUILD_CHAT_TAB,
+ GUILD_SOCIAL_TAB,
+ BACKGROUND,
+ HIGHLIGHT,
+ TAB_FLASH,
+ TAB_PLAYER_FLASH,
+ SHOP_WARNING,
+ ITEM_EQUIPPED,
+ CHAT,
+ GM,
+ PLAYER,
+ WHISPER,
+ WHISPER_OFFLINE,
+ IS,
+ SERVER,
+ LOGGER,
+ HYPERLINK,
+ UNKNOWN_ITEM,
+ GENERIC,
+ HEAD,
+ USABLE,
+ TORSO,
+ ONEHAND,
+ LEGS,
+ FEET,
+ TWOHAND,
+ SHIELD,
+ RING,
+ NECKLACE,
+ ARMS,
+ AMMO,
+ SERVER_VERSION_NOT_SUPPORTED,
+ WARNING,
+ THEME_COLORS_END
+ };
+
+ enum ProgressPalette
+ {
+ PROG_DEFAULT = 0,
+ PROG_HP,
+ PROG_MP,
+ PROG_NO_MP,
+ PROG_EXP,
+ PROG_INVY_SLOTS,
+ PROG_WEIGHT,
+ PROG_JOB,
+ THEME_PROG_END
+ };
+
+ /**
+ * Gets the color associated with the type. Sets the alpha channel
+ * before returning.
+ *
+ * @param type the color type requested
+ * @param alpha alpha channel to use
+ *
+ * @return the requested color
+ */
+ inline static const gcn::Color &getThemeColor(int type,
+ int alpha = 255)
+ { return mInstance->getColor(type, alpha); }
+
+ const static gcn::Color &getThemeColor(char c, bool &valid)
+ { return mInstance->getColor(c, valid); }
+
+ static gcn::Color getProgressColor(int type, float progress);
+
+ /**
+ * Loads a skin.
+ */
+ Skin *load(const std::string &filename,
+ const std::string &defaultPath = getThemePath());
+
+ /**
+ * Updates the alpha values of all of the skins.
+ */
+ void updateAlpha();
+
+ /**
+ * Get the minimum opacity allowed to skins.
+ */
+ float getMinimumOpacity()
+ { return mMinimumOpacity; }
+
+ /**
+ * Set the minimum opacity allowed to skins.
+ * Set a negative value to free the minimum allowed.
+ */
+ void setMinimumOpacity(float minimumOpacity);
+
+ void optionChanged(const std::string &);
+
+ private:
+ Theme();
+ ~Theme();
+
+ Skin *readSkin(const std::string &filename0);
+
+ // Map containing all window skins
+ typedef std::map<std::string, Skin*> Skins;
+ typedef Skins::iterator SkinIterator;
+
+ Skins mSkins;
+
+ static std::string mThemePath;
+ static std::string mThemeName;
+ static Theme *mInstance;
+
+ static bool tryThemePath(std::string themePath);
+
+ void loadColors(std::string file = "");
+
+ /**
+ * Tells if the current skins opacity
+ * should not get less than the given value
+ */
+ float mMinimumOpacity;
+
+ typedef std::vector<DyePalette*> ProgressColors;
+ ProgressColors mProgressColors;
+};
+
+#endif
diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp
new file mode 100644
index 000000000..ee67dc6da
--- /dev/null
+++ b/src/gui/trade.cpp
@@ -0,0 +1,420 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/trade.h"
+
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "units.h"
+
+#include "gui/inventorywindow.h"
+#include "gui/itemamount.h"
+#include "gui/setup.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/itemcontainer.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/textfield.h"
+#include "gui/widgets/layout.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+#include "net/tradehandler.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+
+#include <sstream>
+
+#define CAPTION_PROPOSE _("Propose trade")
+#define CAPTION_CONFIRMED _("Confirmed. Waiting...")
+#define CAPTION_ACCEPT _("Agree trade")
+#define CAPTION_ACCEPTED _("Agreed. Waiting...")
+
+TradeWindow::TradeWindow():
+ Window(_("Trade: You")),
+ mMyInventory(new Inventory(Inventory::TRADE)),
+ mPartnerInventory(new Inventory(Inventory::TRADE)),
+ mStatus(PROPOSING),
+ mAutoAddItem(0),
+ mAutoAddToNick(""),
+ mGotMoney(0),
+ mAutoMoney(0)
+{
+ logger->log1("TradeWindow::TradeWindow nick");
+
+ setWindowName("Trade");
+ setResizable(true);
+ setCloseButton(true);
+ setDefaultSize(386, 180, ImageRect::CENTER);
+ setMinWidth(386);
+ setMinHeight(180);
+
+ if (setupWindow)
+ setupWindow->registerWindowForReset(this);
+
+ std::string longestName = getFont()->getWidth(_("OK")) >
+ getFont()->getWidth(_("Trade")) ?
+ _("OK") : _("Trade");
+
+ mAddButton = new Button(_("Add"), "add", this);
+ mOkButton = new Button("", "", this); // Will be filled in later
+
+ int width = std::max(mOkButton->getFont()->getWidth(CAPTION_PROPOSE),
+ mOkButton->getFont()->getWidth(CAPTION_CONFIRMED));
+ width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPT));
+ width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPTED));
+
+ mOkButton->setWidth(8 + width);
+
+ mMyItemContainer = new ItemContainer(mMyInventory.get());
+ mMyItemContainer->addSelectionListener(this);
+
+ ScrollArea *myScroll = new ScrollArea(mMyItemContainer);
+ myScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mPartnerItemContainer = new ItemContainer(mPartnerInventory.get());
+ mPartnerItemContainer->addSelectionListener(this);
+
+ ScrollArea *partnerScroll = new ScrollArea(mPartnerItemContainer);
+ partnerScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mMoneyLabel = new Label(strprintf(_("You get %s"), ""));
+ gcn::Label *mMoneyLabel2 = new Label(_("You give:"));
+
+ mMoneyField = new TextField;
+ mMoneyField->setWidth(40);
+ mMoneyChangeButton = new Button(_("Change"), "money", this);
+
+ place(1, 0, mMoneyLabel);
+ place(0, 1, myScroll).setPadding(3);
+ place(1, 1, partnerScroll).setPadding(3);
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+ place(0, 0, mMoneyLabel2);
+ place(1, 0, mMoneyField, 2);
+ place(3, 0, mMoneyChangeButton).setHAlign(LayoutCell::LEFT);
+ place = getPlacer(0, 2);
+ place(0, 0, mAddButton);
+ place(1, 0, mOkButton);
+ Layout &layout = getLayout();
+ layout.extend(0, 2, 2, 1);
+ layout.setRowHeight(1, Layout::AUTO_SET);
+ layout.setRowHeight(2, 0);
+ layout.setColWidth(0, Layout::AUTO_SET);
+ layout.setColWidth(1, Layout::AUTO_SET);
+
+ loadWindowState();
+
+ reset();
+}
+
+TradeWindow::~TradeWindow()
+{
+}
+
+void TradeWindow::setMoney(int amount)
+{
+ if (amount < mGotMoney)
+ mMoneyLabel->setForegroundColor(Theme::getThemeColor(Theme::WARNING));
+ mMoneyLabel->setForegroundColor(Theme::getThemeColor(Theme::TEXT));
+
+ mGotMoney = amount;
+ mMoneyLabel->setCaption(strprintf(_("You get %s"),
+ Units::formatCurrency(amount).c_str()));
+ mMoneyLabel->adjustSize();
+}
+
+void TradeWindow::addItem(int id, bool own, int quantity, int refine)
+{
+ if (own)
+ mMyInventory->addItem(id, quantity, refine);
+ else
+ mPartnerInventory->addItem(id, quantity, refine);
+}
+
+void TradeWindow::addItem(int id, bool own, int quantity,
+ int refine, bool equipment)
+{
+ if (own)
+ mMyInventory->addItem(id, quantity, refine, equipment);
+ else
+ mPartnerInventory->addItem(id, quantity, refine, equipment);
+}
+
+void TradeWindow::changeQuantity(int index, bool own, int quantity)
+{
+ if (own)
+ {
+ if (mMyInventory->getItem(index))
+ mMyInventory->getItem(index)->setQuantity(quantity);
+ }
+ else
+ {
+ if (mPartnerInventory->getItem(index))
+ mPartnerInventory->getItem(index)->setQuantity(quantity);
+ }
+}
+
+void TradeWindow::increaseQuantity(int index, bool own, int quantity)
+{
+ if (own)
+ {
+ if (mMyInventory->getItem(index))
+ mMyInventory->getItem(index)->increaseQuantity(quantity);
+ }
+ else
+ {
+ if (mPartnerInventory->getItem(index))
+ mPartnerInventory->getItem(index)->increaseQuantity(quantity);
+ }
+}
+
+void TradeWindow::reset()
+{
+ mMyInventory->clear();
+ mPartnerInventory->clear();
+ mOkOther = false;
+ mOkMe = false;
+ setMoney(0);
+ mMoneyField->setEnabled(true);
+ mMoneyField->setText("");
+ mMoneyLabel->setForegroundColor(Theme::getThemeColor(Theme::TEXT));
+ mAddButton->setEnabled(true);
+ mMoneyChangeButton->setEnabled(true);
+ mGotMoney = 0;
+ setStatus(PREPARING);
+}
+
+void TradeWindow::receivedOk(bool own)
+{
+ if (own)
+ mOkMe = true;
+ else
+ mOkOther = true;
+
+ if (mOkMe && mOkOther)
+ {
+ //mOkMe = false;
+ //mOkOther = false;
+ setStatus(ACCEPTING);
+ }
+}
+
+void TradeWindow::tradeItem(Item *item, int quantity)
+{
+ Net::getTradeHandler()->addItem(item, quantity);
+}
+
+void TradeWindow::valueChanged(const gcn::SelectionEvent &event)
+{
+ if (!mMyItemContainer || !mPartnerItemContainer)
+ return;
+
+ /* If an item is selected in one container, make sure no item is selected
+ * in the other container.
+ */
+ if (event.getSource() == mMyItemContainer &&
+ mMyItemContainer->getSelectedItem())
+ {
+ mPartnerItemContainer->selectNone();
+ }
+ else if (mPartnerItemContainer->getSelectedItem())
+ {
+ mMyItemContainer->selectNone();
+ }
+}
+
+void TradeWindow::setStatus(Status s)
+{
+ if (s == mStatus)
+ return;
+ mStatus = s;
+
+ switch (s)
+ {
+ case PREPARING:
+ mOkButton->setCaption(CAPTION_PROPOSE);
+ mOkButton->setActionEventId("ok");
+ break;
+ case PROPOSING:
+ mOkButton->setCaption(CAPTION_CONFIRMED);
+ mOkButton->setActionEventId("");
+ break;
+ case ACCEPTING:
+ mOkButton->setCaption(CAPTION_ACCEPT);
+ mOkButton->setActionEventId("trade");
+ break;
+ case ACCEPTED:
+ mOkButton->setCaption(CAPTION_ACCEPTED);
+ mOkButton->setActionEventId("");
+ break;
+ default:
+ break;
+ }
+
+ mOkButton->setEnabled((s != PROPOSING && s != ACCEPTED));
+}
+
+void TradeWindow::action(const gcn::ActionEvent &event)
+{
+ if (!inventoryWindow)
+ return;
+
+ Item *item = inventoryWindow->getSelectedItem();
+
+ if (event.getId() == "add")
+ {
+ if (mStatus != PREPARING)
+ return;
+
+ if (!inventoryWindow->isVisible())
+ {
+ inventoryWindow->setVisible(true);
+ return;
+ }
+
+ if (!item)
+ return;
+
+ if (mMyInventory->getFreeSlot() == -1)
+ return;
+
+ if (mMyInventory->contains(item))
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(_("Failed adding item. You can not "
+ "overlap one kind of item on the window."), BY_SERVER);
+ }
+ return;
+ }
+
+ // Choose amount of items to trade
+ ItemAmountWindow::showWindow(ItemAmountWindow::TradeAdd, this, item);
+
+ setStatus(PREPARING);
+ }
+ else if (event.getId() == "cancel")
+ {
+ setVisible(false);
+ reset();
+ PlayerInfo::setTrading(false);
+
+ Net::getTradeHandler()->cancel();
+ }
+ else if (event.getId() == "ok")
+ {
+ mMoneyField->setEnabled(false);
+ mAddButton->setEnabled(false);
+ mMoneyChangeButton->setEnabled(false);
+ receivedOk(true);
+ setStatus(PROPOSING);
+ Net::getTradeHandler()->confirm();
+ }
+ else if (event.getId() == "trade")
+ {
+ receivedOk(true);
+ setStatus(ACCEPTED);
+ Net::getTradeHandler()->finish();
+ }
+ else if (event.getId() == "money")
+ {
+ if (mStatus != PREPARING)
+ return;
+
+ int v = atoi(mMoneyField->getText().c_str());
+ int curMoney = PlayerInfo::getAttribute(MONEY);
+ if (v > curMoney)
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(_("You don't have enough money."),
+ BY_SERVER);
+ }
+ v = curMoney;
+ }
+ Net::getTradeHandler()->setMoney(v);
+ mMoneyField->setText(strprintf("%d", v));
+ }
+}
+
+void TradeWindow::close()
+{
+ Net::getTradeHandler()->cancel();
+ clear();
+}
+
+void TradeWindow::clear()
+{
+ mAutoAddItem = 0;
+ mAutoAddToNick = "";
+ mAutoMoney = 0;
+ mAutoAddAmount = 0;
+ mGotMoney = 0;
+ mMoneyLabel->setForegroundColor(Theme::getThemeColor(Theme::TEXT));
+}
+
+void TradeWindow::addAutoItem(std::string nick, Item* item, int amount)
+{
+ mAutoAddToNick = nick;
+ mAutoAddItem = item;
+ mAutoAddAmount = amount;
+}
+
+void TradeWindow::addAutoMoney(std::string nick, int money)
+{
+ mAutoAddToNick = nick;
+ mAutoMoney = money;
+}
+
+void TradeWindow::initTrade(std::string nick)
+{
+ if (!player_node)
+ return;
+
+ if (!mAutoAddToNick.empty() && mAutoAddToNick == nick)
+ {
+ if (mAutoAddItem && mAutoAddItem->getQuantity())
+ {
+ Inventory *inv = PlayerInfo::getInventory();
+ if (inv)
+ {
+ Item *item = inv->findItem(mAutoAddItem->getId());
+ if (item)
+ tradeItem(item, mAutoAddItem->getQuantity());
+ }
+ }
+ if (mAutoMoney)
+ {
+ Net::getTradeHandler()->setMoney(mAutoMoney);
+ mMoneyField->setText(strprintf("%d", mAutoMoney));
+ }
+ }
+ clear();
+}
diff --git a/src/gui/trade.h b/src/gui/trade.h
new file mode 100644
index 000000000..1baa14fa8
--- /dev/null
+++ b/src/gui/trade.h
@@ -0,0 +1,170 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TRADE_H
+#define TRADE_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#include <memory>
+
+class Inventory;
+class Item;
+class ItemContainer;
+class ScrollArea;
+
+/**
+ * Trade dialog.
+ *
+ * \ingroup Interface
+ */
+class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ TradeWindow();
+
+ /**
+ * Destructor.
+ */
+ ~TradeWindow();
+
+ /**
+ * Displays expected money in the trade window.
+ */
+ void setMoney(int quantity);
+
+ /**
+ * Add an item to the trade window.
+ */
+ void addItem(int id, bool own, int quantity, int refine);
+
+ /**
+ * Reset both item containers
+ */
+ void reset();
+
+ /**
+ * Add an item to the trade window.
+ */
+ void addItem(int id, bool own, int quantity,
+ int refine, bool equipment);
+
+ /**
+ * Change quantity of an item.
+ */
+ void changeQuantity(int index, bool own, int quantity);
+
+ /**
+ * Increase quantity of an item.
+ */
+ void increaseQuantity(int index, bool own, int quantity);
+
+ /**
+ * Player received ok message from server
+ */
+ void receivedOk(bool own);
+
+ /**
+ * Send trade packet.
+ */
+ void tradeItem(Item *item, int quantity);
+
+ /**
+ * Updates the labels and makes sure only one item is selected in
+ * either my inventory or partner inventory.
+ */
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Closes the Trade Window, as well as telling the server that the
+ * window has been closed.
+ */
+ void close();
+
+ /**
+ * Clear auto trade items.
+ */
+ void clear();
+
+ /**
+ * Add item what will be added to trade.
+ */
+ void addAutoItem(std::string nick, Item* item, int amount);
+
+ void addAutoMoney(std::string nick, int money);
+
+ void initTrade(std::string nick);
+
+ std::string getAutoTradeNick()
+ { return mAutoAddToNick; }
+
+ private:
+ enum Status
+ {
+ PREPARING = 0, /**< Players are adding items. (1) */
+ PROPOSING, /**< Local player has confirmed the trade. (1) */
+ ACCEPTING, /**< Accepting the trade. (2) */
+ ACCEPTED /**< Local player has accepted the trade. */
+ };
+
+ /**
+ * Sets the current status of the trade.
+ */
+ void setStatus(Status s);
+
+ typedef const std::auto_ptr<Inventory> InventoryPtr;
+ InventoryPtr mMyInventory;
+ InventoryPtr mPartnerInventory;
+
+ ItemContainer *mMyItemContainer;
+ ItemContainer *mPartnerItemContainer;
+
+ gcn::Label *mMoneyLabel;
+ gcn::Button *mAddButton;
+ gcn::Button *mOkButton;
+ gcn::Button *mMoneyChangeButton;
+ gcn::TextField *mMoneyField;
+
+ Status mStatus;
+ bool mOkOther, mOkMe;
+ Item* mAutoAddItem;
+ std::string mAutoAddToNick;
+ int mGotMoney;
+ int mAutoMoney;
+ int mAutoAddAmount;
+};
+
+extern TradeWindow *tradeWindow;
+
+#endif
diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp
new file mode 100644
index 000000000..8e77c1ded
--- /dev/null
+++ b/src/gui/truetypefont.cpp
@@ -0,0 +1,336 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/truetypefont.h"
+
+#include "client.h"
+#include "graphics.h"
+#include "log.h"
+#include "main.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/stringutils.h"
+
+#include <guichan/exception.hpp>
+
+const unsigned int CACHE_SIZE = 256;
+const unsigned int CACHE_SIZE_SMALL1 = 90;
+const unsigned int CACHE_SIZE_SMALL2 = 150;
+
+char *strBuf;
+
+class TextChunk
+{
+ public:
+ TextChunk(const std::string &text, const gcn::Color &color) :
+ img(0), text(text), color(color)
+ {
+ }
+
+ ~TextChunk()
+ {
+ delete img;
+ img = 0;
+ }
+
+ bool operator==(const TextChunk &chunk) const
+ {
+ return (chunk.text == text && chunk.color == color);
+ }
+
+ void generate(TTF_Font *font)
+ {
+ SDL_Color sdlCol;
+ sdlCol.b = static_cast<Uint8>(color.b);
+ sdlCol.r = static_cast<Uint8>(color.r);
+ sdlCol.g = static_cast<Uint8>(color.g);
+
+ getSafeUtf8String(text, strBuf);
+
+// SDL_Surface *surface = TTF_RenderUTF8_Solid(
+ SDL_Surface *surface = TTF_RenderUTF8_Blended(
+ font, strBuf, sdlCol);
+
+ if (!surface)
+ {
+ img = 0;
+ return;
+ }
+
+ img = Image::load(surface);
+
+ SDL_FreeSurface(surface);
+ }
+
+ Image *img;
+ std::string text;
+ gcn::Color color;
+};
+
+typedef std::list<TextChunk>::iterator CacheIterator;
+
+static int fontCounter;
+
+TrueTypeFont::TrueTypeFont(const std::string &filename, int size, int style) :
+ mCreateCounter(0),
+ mDeleteCounter(0)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ if (fontCounter == 0 && TTF_Init() == -1)
+ {
+ throw GCN_EXCEPTION("Unable to initialize SDL_ttf: " +
+ std::string(TTF_GetError()));
+ }
+
+ if (!fontCounter)
+ {
+ strBuf = new char[65535];
+ memset(strBuf, 65535, 0);
+ }
+
+ ++fontCounter;
+ mFont = TTF_OpenFont(resman->getPath(filename).c_str(), size);
+
+ if (!mFont)
+ {
+ logger->log("Error finding font " + filename);
+ mFont = TTF_OpenFont(resman->getPath(
+ "fonts/dejavusans.ttf").c_str(), size);
+ if (!mFont)
+ {
+ throw GCN_EXCEPTION("SDLTrueTypeFont::SDLTrueTypeFont: " +
+ std::string(TTF_GetError()));
+ }
+ }
+
+ TTF_SetFontStyle(mFont, style);
+ mCleanTime = cur_time + 120;
+}
+
+TrueTypeFont::~TrueTypeFont()
+{
+ TTF_CloseFont(mFont);
+ mFont = 0;
+ --fontCounter;
+
+ if (fontCounter == 0)
+ {
+ TTF_Quit();
+ delete []strBuf;
+ }
+}
+
+void TrueTypeFont::loadFont(const std::string &filename, int size, int style)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ if (fontCounter == 0 && TTF_Init() == -1)
+ {
+ logger->log("Unable to initialize SDL_ttf: " +
+ std::string(TTF_GetError()));
+ return;
+ }
+
+ TTF_Font *font = TTF_OpenFont(resman->getPath(filename).c_str(), size);
+
+ if (!font)
+ {
+ logger->log("SDLTrueTypeFont::SDLTrueTypeFont: " +
+ std::string(TTF_GetError()));
+ return;
+ }
+
+ if (mFont)
+ TTF_CloseFont(mFont);
+
+ mFont = font;
+ TTF_SetFontStyle(mFont, style);
+ clear();
+}
+
+void TrueTypeFont::clear()
+{
+ for (unsigned short f = 0; f < (unsigned short)CACHES_NUMBER; f ++)
+ mCache[static_cast<unsigned short>(f)].clear();
+}
+
+void TrueTypeFont::drawString(gcn::Graphics *graphics,
+ const std::string &text,
+ int x, int y)
+{
+ if (text.empty())
+ return;
+
+ Graphics *g = dynamic_cast<Graphics *>(graphics);
+
+ gcn::Color col = g->getColor();
+ const float alpha = static_cast<float>(col.a) / 255.0f;
+
+ /* The alpha value is ignored at string generation so avoid caching the
+ * same text with different alpha values.
+ */
+ col.a = 255;
+
+ TextChunk chunk(text, col);
+
+ unsigned char chr = text[0];
+ std::list<TextChunk> *cache = &mCache[chr];
+
+ bool found = false;
+
+#ifdef DEBUG_FONT
+ int cnt = 0;
+#endif
+
+ for (CacheIterator i = cache->begin(); i != cache->end(); ++i)
+ {
+ if (chunk == (*i))
+ {
+ // Raise priority: move it to front
+ cache->splice(cache->begin(), *cache, i);
+ found = true;
+ break;
+ }
+#ifdef DEBUG_FONT
+ cnt ++;
+#endif
+ }
+#ifdef DEBUG_FONT
+ logger->log("drawString: " + text + ", iterations: " + toString(cnt));
+#endif
+
+ // Surface not found
+ if (!found)
+ {
+ if (cache->size() >= CACHE_SIZE)
+ {
+#ifdef DEBUG_FONT_COUNTERS
+ mDeleteCounter ++;
+#endif
+ cache->pop_back();
+ }
+#ifdef DEBUG_FONT_COUNTERS
+ mCreateCounter ++;
+#endif
+ cache->push_front(chunk);
+ cache->front().generate(mFont);
+
+ if (!mCleanTime)
+ {
+ mCleanTime = cur_time + 120;
+ }
+ else if (mCleanTime < cur_time)
+ {
+ doClean();
+ mCleanTime = cur_time + 120;
+ }
+ }
+
+ if (cache->front().img)
+ {
+ cache->front().img->setAlpha(alpha);
+ g->drawImage(cache->front().img, x, y);
+ }
+
+}
+
+void TrueTypeFont::createTextChunk(TextChunk *chunk)
+{
+ if (!chunk || chunk->text.empty())
+ return;
+
+ const float alpha = static_cast<float>(chunk->color.a) / 255.0f;
+ chunk->color.a = 255;
+ chunk->generate(mFont);
+ if (chunk->img)
+ chunk->img->setAlpha(alpha);
+}
+
+int TrueTypeFont::getWidth(const std::string &text) const
+{
+ if (text.empty())
+ return 0;
+
+ unsigned char chr = text[0];
+ std::list<TextChunk> *cache = &mCache[chr];
+
+#ifdef DEBUG_FONT
+ int cnt = 0;
+#endif
+
+ for (CacheIterator i = cache->begin(); i != cache->end(); i++)
+ {
+ if (i->text == text)
+ {
+ // Raise priority: move it to front
+ // Assumption is that TTF::draw will be called next
+ cache->splice(cache->begin(), *cache, i);
+ if (i->img)
+ return i->img->getWidth();
+ else
+ return 0;
+ }
+#ifdef DEBUG_FONT
+ cnt ++;
+#endif
+ }
+
+#ifdef DEBUG_FONT
+ logger->log("getWidth: " + text + ", iterations: " + toString(cnt));
+#endif
+
+ int w, h;
+ getSafeUtf8String(text, strBuf);
+ TTF_SizeUTF8(mFont, strBuf, &w, &h);
+ return w;
+}
+
+int TrueTypeFont::getHeight() const
+{
+ return TTF_FontHeight(mFont);
+}
+
+void TrueTypeFont::doClean()
+{
+ for (int f = 0; f < CACHES_NUMBER; f ++)
+ {
+ std::list<TextChunk> *cache = &mCache[f];
+ if (cache->size() > CACHE_SIZE_SMALL2)
+ {
+#ifdef DEBUG_FONT_COUNTERS
+ mDeleteCounter += 10;
+#endif
+ for (int d = 0; d < 10; d ++)
+ cache->pop_back();
+ }
+ else if (cache->size() > CACHE_SIZE_SMALL1)
+ {
+#ifdef DEBUG_FONT_COUNTERS
+ mDeleteCounter ++;
+#endif
+ cache->pop_back();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h
new file mode 100644
index 000000000..7a28c3b97
--- /dev/null
+++ b/src/gui/truetypefont.h
@@ -0,0 +1,104 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TRUETYPEFONT_H
+#define TRUETYPEFONT_H
+
+#include <guichan/font.hpp>
+
+#ifdef __APPLE__
+#include <SDL_ttf/SDL_ttf.h>
+#else
+#ifdef __WIN32__
+#include <SDL/SDL_ttf.h>
+#else
+#include <SDL_ttf.h>
+#endif
+#endif
+
+#include <list>
+#include <string>
+
+#define CACHES_NUMBER 256
+
+class TextChunk;
+
+/**
+ * A wrapper around SDL_ttf for allowing the use of TrueType fonts.
+ *
+ * <b>NOTE:</b> This class initializes SDL_ttf as necessary.
+ */
+class TrueTypeFont : public gcn::Font
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param filename Font filename.
+ * @param size Font size.
+ */
+ TrueTypeFont(const std::string &filename, int size, int style = 0);
+
+ /**
+ * Destructor.
+ */
+ ~TrueTypeFont();
+
+ void loadFont(const std::string &filename, int size, int style = 0);
+
+ void createTextChunk(TextChunk *chunk);
+
+ virtual int getWidth(const std::string &text) const;
+
+ virtual int getHeight() const;
+
+ std::list<TextChunk> *getCache()
+ { return mCache; }
+
+ /**
+ * @see Font::drawString
+ */
+ void drawString(gcn::Graphics *graphics,
+ const std::string &text,
+ int x, int y);
+
+ void clear();
+
+ void doClean();
+
+ int getCreateCounter() const
+ { return mCreateCounter; }
+
+ int getDeleteCounter() const
+ { return mDeleteCounter; }
+
+ private:
+ TTF_Font *mFont;
+ unsigned mCreateCounter;
+ unsigned mDeleteCounter;
+
+ // Word surfaces cache
+ mutable std::list<TextChunk> mCache[CACHES_NUMBER];
+ int mCleanTime;
+};
+
+#endif
diff --git a/src/gui/unregisterdialog.cpp b/src/gui/unregisterdialog.cpp
new file mode 100644
index 000000000..a226f0d84
--- /dev/null
+++ b/src/gui/unregisterdialog.cpp
@@ -0,0 +1,145 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/unregisterdialog.h"
+
+#include "client.h"
+#include "log.h"
+
+#include "gui/okdialog.h"
+#include "gui/register.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/passwordfield.h"
+#include "gui/widgets/textfield.h"
+
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
+#include <sstream>
+
+UnRegisterDialog::UnRegisterDialog(LoginData *loginData):
+ Window(_("Unregister"), true),
+ mWrongDataNoticeListener(new WrongDataNoticeListener),
+ mLoginData(loginData)
+{
+ gcn::Label *userLabel = new Label(strprintf(_("Name: %s"), mLoginData->
+ username.c_str()));
+ gcn::Label *passwordLabel = new Label(_("Password:"));
+ mPasswordField = new PasswordField(mLoginData->password);
+ mUnRegisterButton = new Button(_("Unregister"), "unregister", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ const int width = 210;
+ const int height = 80;
+ setContentSize(width, height);
+
+ userLabel->setPosition(5, 5);
+ userLabel->setWidth(width - 5);
+ mPasswordField->setPosition(
+ 68, userLabel->getY() + userLabel->getHeight() + 7);
+ mPasswordField->setWidth(130);
+
+ passwordLabel->setPosition(5, mPasswordField->getY() + 1);
+
+ mCancelButton->setPosition(
+ width - 5 - mCancelButton->getWidth(),
+ height - 5 - mCancelButton->getHeight());
+ mUnRegisterButton->setPosition(
+ mCancelButton->getX() - 5 - mUnRegisterButton->getWidth(),
+ mCancelButton->getY());
+
+ add(userLabel);
+ add(passwordLabel);
+ add(mPasswordField);
+ add(mUnRegisterButton);
+ add(mCancelButton);
+
+ center();
+ setVisible(true);
+ mPasswordField->requestFocus();
+ mPasswordField->setActionEventId("cancel");
+}
+
+UnRegisterDialog::~UnRegisterDialog()
+{
+ delete mWrongDataNoticeListener;
+ mWrongDataNoticeListener = 0;
+}
+
+void UnRegisterDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ Client::setState(STATE_CHAR_SELECT);
+ }
+ else if (event.getId() == "unregister")
+ {
+ const std::string username = mLoginData->username.c_str();
+ const std::string password = mPasswordField->getText();
+ logger->log("UnregisterDialog::unregistered, Username is %s",
+ username.c_str());
+
+ std::stringstream errorMessage;
+ bool error = false;
+
+ unsigned int min = Net::getLoginHandler()->getMinPasswordLength();
+ unsigned int max = Net::getLoginHandler()->getMaxPasswordLength();
+
+ // Check password
+ if (password.length() < min)
+ {
+ // Pass too short
+ errorMessage << strprintf(_("The password needs to be at least %d "
+ "characters long."), min);
+ error = true;
+ }
+ else if (password.length() > max - 1)
+ {
+ // Pass too long
+ errorMessage << strprintf(_("The password needs to be less than "
+ "%d characters long."), max);
+ error = true;
+ }
+
+ if (error)
+ {
+ mWrongDataNoticeListener->setTarget(this->mPasswordField);
+
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str());
+ dlg->addActionListener(mWrongDataNoticeListener);
+ }
+ else
+ {
+ // No errors detected, unregister the new user.
+ mUnRegisterButton->setEnabled(false);
+ mLoginData->password = password;
+ Client::setState(STATE_UNREGISTER_ATTEMPT);
+ }
+ }
+}
diff --git a/src/gui/unregisterdialog.h b/src/gui/unregisterdialog.h
new file mode 100644
index 000000000..dd330afdc
--- /dev/null
+++ b/src/gui/unregisterdialog.h
@@ -0,0 +1,68 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UNREGISTERDIALOG_H
+#define UNREGISTERDIALOG_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class LoginData;
+class OkDialog;
+class WrongDataNoticeListener;
+
+/**
+ * The Unregister dialog.
+ *
+ * \ingroup Interface
+ */
+class UnRegisterDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ UnRegisterDialog(LoginData *loginData);
+
+ ~UnRegisterDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::TextField *mPasswordField;
+
+ gcn::Button *mUnRegisterButton;
+ gcn::Button *mCancelButton;
+
+ WrongDataNoticeListener *mWrongDataNoticeListener;
+
+ LoginData *mLoginData;
+};
+
+#endif
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
new file mode 100644
index 000000000..e199d7a72
--- /dev/null
+++ b/src/gui/updatewindow.cpp
@@ -0,0 +1,672 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/updatewindow.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "log.h"
+#include "main.h"
+
+#include "gui/sdlinput.h"
+
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/progressbar.h"
+#include "gui/widgets/scrollarea.h"
+
+#include "net/download.h"
+#include "net/logindata.h"
+
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <iostream>
+#include <fstream>
+
+#include <sys/stat.h>
+
+const std::string xmlUpdateFile = "resources.xml";
+const std::string txtUpdateFile = "resources2.txt";
+
+std::vector<updateFile> loadXMLFile(const std::string &fileName);
+std::vector<updateFile> loadTxtFile(const std::string &fileName);
+
+/**
+ * Load the given file into a vector of updateFiles.
+ */
+std::vector<updateFile> loadXMLFile(const std::string &fileName)
+{
+ std::vector<updateFile> files;
+ XML::Document doc(fileName, false);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "updates"))
+ {
+ logger->log("Error loading update file: %s", fileName.c_str());
+ return files;
+ }
+
+ for_each_xml_child_node(fileNode, rootNode)
+ {
+ // Ignore all tags except for the "update" tags
+ if (!xmlStrEqual(fileNode->name, BAD_CAST "update"))
+ continue;
+
+ updateFile file;
+ file.name = XML::getProperty(fileNode, "file", "");
+ file.hash = XML::getProperty(fileNode, "hash", "");
+ file.type = XML::getProperty(fileNode, "type", "data");
+ file.desc = XML::getProperty(fileNode, "description", "");
+ if (XML::getProperty(fileNode, "required", "yes") == "yes")
+ file.required = true;
+ else
+ file.required = false;
+
+ files.push_back(file);
+ }
+
+ return files;
+}
+
+std::vector<updateFile> loadTxtFile(const std::string &fileName)
+{
+ std::vector<updateFile> files;
+ std::ifstream fileHandler;
+ fileHandler.open(fileName.c_str(), std::ios::in);
+
+ if (fileHandler.is_open())
+ {
+ while (fileHandler.good())
+ {
+ char name[256], hash[50];
+ fileHandler.getline(name, 256, ' ');
+ fileHandler.getline(hash, 50);
+
+ updateFile thisFile;
+ thisFile.name = name;
+ thisFile.hash = hash;
+ thisFile.type = "data";
+ thisFile.required = true;
+ thisFile.desc = "";
+
+ files.push_back(thisFile);
+ }
+ }
+ else
+ {
+ logger->log("Error loading update file: %s", fileName.c_str());
+ }
+ fileHandler.close();
+
+ return files;
+}
+
+UpdaterWindow::UpdaterWindow(const std::string &updateHost,
+ const std::string &updatesDir,
+ bool applyUpdates,
+ int updateType):
+ Window(_("Updating...")),
+ mDownloadStatus(UPDATE_NEWS),
+ mUpdateHost(updateHost),
+ mUpdatesDir(updatesDir),
+ mCurrentFile("news.txt"),
+ mDownloadProgress(0.0f),
+ mCurrentChecksum(0),
+ mStoreInMemory(true),
+ mDownloadComplete(true),
+ mUserCancel(false),
+ mDownloadedBytes(0),
+ mMemoryBuffer(NULL),
+ mDownload(NULL),
+ mUpdateIndex(0),
+ mLoadUpdates(applyUpdates),
+ mUpdateType(updateType)
+{
+ mBrowserBox = new BrowserBox;
+ mScrollArea = new ScrollArea(mBrowserBox);
+ mLabel = new Label(_("Connecting..."));
+ mProgressBar = new ProgressBar(0.0, 310, 20);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mPlayButton = new Button(_("Play"), "play", this);
+
+ mProgressBar->setSmoothProgress(false);
+ mBrowserBox->setOpaque(false);
+ mPlayButton->setEnabled(false);
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mScrollArea, 5, 3).setPadding(3);
+ place(0, 3, mLabel, 5);
+ place(0, 4, mProgressBar, 5);
+ place(3, 5, mCancelButton);
+ place(4, 5, mPlayButton);
+
+ reflowLayout(450, 400);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+
+ addKeyListener(this);
+
+ center();
+ setVisible(true);
+ mCancelButton->requestFocus();
+
+ // Try to download the updates list
+ download();
+}
+
+UpdaterWindow::~UpdaterWindow()
+{
+ if (mLoadUpdates)
+ loadUpdates();
+
+ if (mDownload)
+ {
+ mDownload->cancel();
+
+ delete mDownload;
+ mDownload = 0;
+ }
+ free(mMemoryBuffer);
+}
+
+void UpdaterWindow::setProgress(float p)
+{
+ // Do delayed progress bar update, since Guichan isn't thread-safe
+ MutexLocker lock(&mDownloadMutex);
+ mDownloadProgress = p;
+}
+
+void UpdaterWindow::setLabel(const std::string &str)
+{
+ // Do delayed label text update, since Guichan isn't thread-safe
+ MutexLocker lock(&mDownloadMutex);
+ mNewLabelCaption = str;
+}
+
+void UpdaterWindow::enable()
+{
+ mCancelButton->setEnabled(false);
+ mPlayButton->setEnabled(true);
+ mPlayButton->requestFocus();
+
+ if (mUpdateType & LoginData::Upd_Close)
+ Client::setState(STATE_LOAD_DATA);
+}
+
+void UpdaterWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ // Register the user cancel
+ mUserCancel = true;
+ // Skip the updating process
+ if (mDownloadStatus != UPDATE_COMPLETE)
+ {
+ mDownload->cancel();
+ mDownloadStatus = UPDATE_ERROR;
+ }
+ }
+ else if (event.getId() == "play")
+ {
+ Client::setState(STATE_LOAD_DATA);
+ }
+}
+
+void UpdaterWindow::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ESCAPE)
+ {
+ action(gcn::ActionEvent(NULL, mCancelButton->getActionEventId()));
+ Client::setState(STATE_WORLD_SELECT);
+ }
+ else if (key.getValue() == Key::ENTER)
+ {
+ if (mDownloadStatus == UPDATE_COMPLETE ||
+ mDownloadStatus == UPDATE_ERROR)
+ {
+ action(gcn::ActionEvent(NULL, mPlayButton->getActionEventId()));
+ }
+ else
+ {
+ action(gcn::ActionEvent(NULL, mCancelButton->getActionEventId()));
+ }
+ }
+}
+
+void UpdaterWindow::loadNews()
+{
+ if (!mMemoryBuffer)
+ {
+ logger->log1("Couldn't load news");
+ return;
+ }
+
+ // Reallocate and include terminating 0 character
+ mMemoryBuffer = static_cast<char*>(realloc(
+ mMemoryBuffer, mDownloadedBytes + 1));
+
+ mMemoryBuffer[mDownloadedBytes] = '\0';
+
+ mBrowserBox->clearRows();
+
+ // Tokenize and add each line separately
+ char *line = strtok(mMemoryBuffer, "\n");
+ while (line)
+ {
+ mBrowserBox->addRow(line);
+ line = strtok(NULL, "\n");
+ }
+
+ // Free the memory buffer now that we don't need it anymore
+ free(mMemoryBuffer);
+ mMemoryBuffer = NULL;
+ mDownloadedBytes = 0;
+
+ mScrollArea->setVerticalScrollAmount(0);
+}
+
+void UpdaterWindow::loadPatch()
+{
+ if (!mMemoryBuffer)
+ {
+ logger->log1("Couldn't load patch");
+ return;
+ }
+
+ // Reallocate and include terminating 0 character
+ mMemoryBuffer = static_cast<char*>(
+ realloc(mMemoryBuffer, mDownloadedBytes + 1));
+ mMemoryBuffer[mDownloadedBytes] = '\0';
+
+ std::string version;
+
+ // Tokenize and add each line separately
+ char *line = strtok(mMemoryBuffer, "\n");
+ if (line)
+ {
+ version = line;
+ if (version > CHECK_VERSION)
+ {
+ mBrowserBox->addRow("", true);
+ mBrowserBox->addRow(" ##1http://tmw.cetki.com/4144/", true);
+ mBrowserBox->addRow("##1You can download it from", true);
+ mBrowserBox->addRow("##1ManaPlus updated.", true);
+ }
+ else
+ {
+ mBrowserBox->addRow("You have latest client version.", true);
+ }
+ }
+
+ // Free the memory buffer now that we don't need it anymore
+ free(mMemoryBuffer);
+ mMemoryBuffer = NULL;
+ mDownloadedBytes = 0;
+
+ mScrollArea->setVerticalScrollAmount(0);
+}
+
+int UpdaterWindow::updateProgress(void *ptr, DownloadStatus status,
+ size_t dt, size_t dn)
+{
+ UpdaterWindow *uw = reinterpret_cast<UpdaterWindow *>(ptr);
+ if (!uw)
+ return -1;
+
+ if (status == DOWNLOAD_STATUS_COMPLETE)
+ {
+ uw->mDownloadComplete = true;
+ }
+ else if (status == DOWNLOAD_STATUS_ERROR ||
+ status == DOWNLOAD_STATUS_CANCELLED)
+ {
+ uw->mDownloadStatus = UPDATE_ERROR;
+ }
+
+ if (!dt)
+ dt = 1;
+
+ float progress = static_cast<float>(dn) /
+ static_cast<float>(dt);
+
+ if (progress != progress)
+ progress = 0.0f; // check for NaN
+ if (progress < 0.0f)
+ progress = 0.0f; // no idea how this could ever happen,
+ // but why not check for it anyway.
+ if (progress > 1.0f)
+ progress = 1.0f;
+
+ uw->setLabel(uw->mCurrentFile + " ("
+ + toString(static_cast<int>(progress * 100)) + "%)");
+
+ uw->setProgress(progress);
+
+ if (Client::getState() != STATE_UPDATE
+ || uw->mDownloadStatus == UPDATE_ERROR)
+ {
+ // If the action was canceled return an error code to stop the mThread
+ return -1;
+ }
+
+ return 0;
+}
+
+size_t UpdaterWindow::memoryWrite(void *ptr, size_t size,
+ size_t nmemb, void *stream)
+{
+ UpdaterWindow *uw = reinterpret_cast<UpdaterWindow *>(stream);
+ size_t totalMem = size * nmemb;
+ uw->mMemoryBuffer = static_cast<char*>(realloc(uw->mMemoryBuffer,
+ uw->mDownloadedBytes + totalMem));
+ if (uw->mMemoryBuffer)
+ {
+ memcpy(&(uw->mMemoryBuffer[uw->mDownloadedBytes]), ptr, totalMem);
+ uw->mDownloadedBytes += static_cast<int>(totalMem);
+ }
+
+ return totalMem;
+}
+
+void UpdaterWindow::download()
+{
+ if (mDownload)
+ {
+ mDownload->cancel();
+ delete mDownload;
+ }
+ if (mDownloadStatus == UPDATE_PATCH)
+ {
+ mDownload = new Net::Download(this, "http://tmw.cetki.com/update/"
+ + mCurrentFile, updateProgress);
+ }
+ else
+ {
+ mDownload = new Net::Download(this, mUpdateHost + "/" + mCurrentFile,
+ updateProgress);
+ }
+
+ if (mStoreInMemory)
+ {
+ mDownload->setWriteFunction(UpdaterWindow::memoryWrite);
+ }
+ else
+ {
+ if (mDownloadStatus == UPDATE_RESOURCES)
+ {
+ mDownload->setFile(mUpdatesDir + "/" + mCurrentFile,
+ mCurrentChecksum);
+ }
+ else
+ {
+ mDownload->setFile(mUpdatesDir + "/" + mCurrentFile);
+ }
+ }
+
+ if (mDownloadStatus != UPDATE_RESOURCES)
+ mDownload->noCache();
+
+ setLabel(mCurrentFile + " (0%)");
+ mDownloadComplete = false;
+
+ // TODO: check return
+ mDownload->start();
+}
+
+void UpdaterWindow::loadUpdates()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ if (mUpdateFiles.empty())
+ { // updates not downloaded
+ mUpdateFiles = loadXMLFile(mUpdatesDir + "/" + xmlUpdateFile);
+ if (!mUpdateFiles.size())
+ {
+ logger->log("Warning this server does not have a"
+ " %s file falling back to %s", xmlUpdateFile.c_str(),
+ txtUpdateFile.c_str());
+ mUpdateFiles = loadTxtFile(mUpdatesDir + "/" + txtUpdateFile);
+ }
+ }
+
+ std::string fixPath = mUpdatesDir + "/fix";
+ for (mUpdateIndex = 0; mUpdateIndex < mUpdateFiles.size(); mUpdateIndex++)
+ {
+ UpdaterWindow::addUpdateFile(resman, mUpdatesDir, fixPath,
+ mUpdateFiles[mUpdateIndex].name, false);
+ }
+}
+
+void UpdaterWindow::loadLocalUpdates(std::string dir)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ std::vector<updateFile> updateFiles
+ = loadXMLFile(dir + "/" + xmlUpdateFile);
+
+ if (updateFiles.empty())
+ {
+ logger->log("Warning this server does not have a"
+ " %s file falling back to %s", xmlUpdateFile.c_str(),
+ txtUpdateFile.c_str());
+ updateFiles = loadTxtFile(dir + "/" + txtUpdateFile);
+ }
+
+ std::string fixPath = dir + "/fix";
+ for (unsigned int updateIndex = 0;
+ updateIndex < updateFiles.size(); updateIndex++)
+ {
+ UpdaterWindow::addUpdateFile(resman, dir, fixPath,
+ updateFiles[updateIndex].name, false);
+ }
+}
+
+void UpdaterWindow::addUpdateFile(ResourceManager *resman, std::string path,
+ std::string fixPath, std::string file,
+ bool append)
+{
+ if (!append)
+ resman->addToSearchPath(path + "/" + file, append);
+
+ const std::string fixFile = fixPath + "/" + file;
+ struct stat statbuf;
+ if (!stat(fixFile.c_str(), &statbuf))
+ resman->addToSearchPath(fixFile, append);
+
+ if (append)
+ resman->addToSearchPath(path + "/" + file, append);
+}
+
+void UpdaterWindow::logic()
+{
+ // Update Scroll logic
+ mScrollArea->logic();
+
+ // Synchronize label caption when necessary
+ {
+ MutexLocker lock(&mDownloadMutex);
+
+ if (mLabel->getCaption() != mNewLabelCaption)
+ {
+ mLabel->setCaption(mNewLabelCaption);
+ mLabel->adjustSize();
+ }
+
+ mProgressBar->setProgress(mDownloadProgress);
+ }
+
+ std::string filename = mUpdatesDir + "/" + mCurrentFile;
+
+ switch (mDownloadStatus)
+ {
+ case UPDATE_ERROR:
+ // TODO: Only send complete sentences to gettext
+ mBrowserBox->addRow("");
+ mBrowserBox->addRow(_("##1 The update process is incomplete."));
+ // TRANSLATORS: Continues "you try again later.".
+ mBrowserBox->addRow(_("##1 It is strongly recommended that"));
+ // TRANSLATORS: Begins "It is strongly recommended that".
+ mBrowserBox->addRow(_("##1 you try again later."));
+
+ mBrowserBox->addRow(mDownload->getError());
+ mScrollArea->setVerticalScrollAmount(
+ mScrollArea->getVerticalMaxScroll());
+ mDownloadStatus = UPDATE_COMPLETE;
+ break;
+ case UPDATE_NEWS:
+ if (mDownloadComplete)
+ {
+ // Parse current memory buffer as news and dispose of the data
+ loadNews();
+
+ mCurrentFile = xmlUpdateFile;
+ mStoreInMemory = false;
+ mDownloadStatus = UPDATE_LIST;
+ download(); // download() changes mDownloadComplete to false
+ }
+ break;
+ case UPDATE_PATCH:
+ if (mDownloadComplete)
+ {
+ // Parse current memory buffer as news and dispose of the data
+ loadPatch();
+
+/*
+ mCurrentFile = "news.txt";
+ mStoreInMemory = true;
+ mDownloadStatus = UPDATE_NEWS;
+ download(); // download() changes mDownloadComplete to false
+*/
+ mDownloadStatus = UPDATE_COMPLETE;
+ }
+ break;
+
+ case UPDATE_LIST:
+ if (mDownloadComplete)
+ {
+ if (mCurrentFile == xmlUpdateFile)
+ {
+ mUpdateFiles = loadXMLFile(
+ mUpdatesDir + "/" + xmlUpdateFile);
+
+ if (mUpdateFiles.size() == 0)
+ {
+ logger->log("Warning this server does not have a %s"
+ " file falling back to %s",
+ xmlUpdateFile.c_str(),
+ txtUpdateFile.c_str());
+
+ // If the resources.xml file fails,
+ // fall back onto a older version
+ mCurrentFile = txtUpdateFile;
+ mStoreInMemory = false;
+ mDownloadStatus = UPDATE_LIST;
+ download();
+ break;
+ }
+ }
+ else if (mCurrentFile == txtUpdateFile)
+ {
+ mUpdateFiles = loadTxtFile(
+ mUpdatesDir + "/" + txtUpdateFile);
+ }
+ mStoreInMemory = false;
+ mDownloadStatus = UPDATE_RESOURCES;
+ }
+ break;
+ case UPDATE_RESOURCES:
+ if (mDownloadComplete)
+ {
+ if (mUpdateIndex < mUpdateFiles.size())
+ {
+ updateFile thisFile = mUpdateFiles[mUpdateIndex];
+ if (!thisFile.required)
+ {
+ // This statement checks to see if the file type
+ // is music, and if download-music is true
+ // If it fails, this statement returns true,
+ // and results in not downloading the file
+ // Else it will ignore the break,
+ // and download the file.
+
+ if (!(thisFile.type == "music"
+ && config.getBoolValue("download-music")))
+ {
+ mUpdateIndex++;
+ break;
+ }
+ }
+ mCurrentFile = thisFile.name;
+ std::string checksum;
+ checksum = thisFile.hash;
+ std::stringstream ss(checksum);
+ ss >> std::hex >> mCurrentChecksum;
+
+ std::ifstream temp(
+ (mUpdatesDir + "/" + mCurrentFile).c_str());
+
+ if (!temp.is_open())
+ {
+ temp.close();
+ download();
+ }
+ else
+ {
+ temp.close();
+ logger->log("%s already here", mCurrentFile.c_str());
+ }
+ mUpdateIndex++;
+ }
+ else
+ {
+ // Download of updates completed
+// mDownloadStatus = UPDATE_COMPLETE;
+ mCurrentFile = "latest.txt";
+ mStoreInMemory = true;
+ mDownloadStatus = UPDATE_PATCH;
+ download(); // download() changes
+ // mDownloadComplete to false
+ }
+ }
+ break;
+ case UPDATE_COMPLETE:
+ enable();
+ setLabel(_("Completed"));
+ break;
+ case UPDATE_IDLE:
+ break;
+ default:
+ logger->log("UpdaterWindow::logic unknown status: "
+ + toString(static_cast<unsigned>(mDownloadStatus)));
+ break;
+ }
+}
diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h
new file mode 100644
index 000000000..841af23a5
--- /dev/null
+++ b/src/gui/updatewindow.h
@@ -0,0 +1,210 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef _UPDATERWINDOW_H
+#define _UPDATERWINDOW_H
+
+#include "gui/widgets/window.h"
+
+#include "net/download.h"
+
+#include "utils/mutex.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+
+#include <string>
+#include <vector>
+
+class BrowserBox;
+class Button;
+class ProgressBar;
+class ResourceManager;
+class ScrollArea;
+
+struct updateFile
+{
+ public:
+ std::string name;
+ std::string hash;
+ std::string type;
+ bool required;
+ std::string desc;
+};
+
+/**
+ * Update progress window GUI
+ *
+ * \ingroup GUI
+ */
+class UpdaterWindow : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param updateHost Host where to get the updated files.
+ * @param updatesDir Directory where to store updates (should be absolute
+ * and already created).
+ * @param applyUpdates If true, the update window will pass the updates to teh
+ * resource manager
+ */
+ UpdaterWindow(const std::string &updateHost,
+ const std::string &updatesDir,
+ bool applyUpdates, int updateType);
+
+ /**
+ * Destructor
+ */
+ ~UpdaterWindow();
+
+ /**
+ * Set's progress bar status
+ */
+ void setProgress(float p);
+
+ /**
+ * Set's label above progress
+ */
+ void setLabel(const std::string &);
+
+ /**
+ * Enables play button
+ */
+ void enable();
+
+ /**
+ * Loads and display news. Assumes the news file contents have been loaded
+ * into the memory buffer.
+ */
+ void loadNews();
+
+ void loadPatch();
+
+ void action(const gcn::ActionEvent &event);
+
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ void logic();
+
+ static void loadLocalUpdates(std::string dir);
+
+ static void addUpdateFile(ResourceManager *resman, std::string path,
+ std::string fixPath, std::string file,
+ bool append);
+
+ int updateState;
+
+private:
+ void download();
+
+ /**
+ * Loads the updates this window has gotten into the resource manager
+ */
+ void loadUpdates();
+
+
+ /**
+ * A download callback for progress updates.
+ */
+ static int updateProgress(void *ptr, DownloadStatus status,
+ size_t dt, size_t dn);
+
+ /**
+ * A libcurl callback for writing to memory.
+ */
+ static size_t memoryWrite(void *ptr, size_t size, size_t nmemb,
+ void *stream);
+
+ enum UpdateDownloadStatus
+ {
+ UPDATE_ERROR = 0,
+ UPDATE_IDLE,
+ UPDATE_LIST,
+ UPDATE_COMPLETE,
+ UPDATE_NEWS,
+ UPDATE_RESOURCES,
+ UPDATE_PATCH
+ };
+
+ /** Status of the current download. */
+ UpdateDownloadStatus mDownloadStatus;
+
+ /** Host where we get the updated files. */
+ std::string mUpdateHost;
+
+ /** Place where the updates are stored (absolute path). */
+ std::string mUpdatesDir;
+
+ /** The file currently downloading. */
+ std::string mCurrentFile;
+
+ /** The new label caption to be set in the logic method. */
+ std::string mNewLabelCaption;
+
+ /** The new progress value to be set in the logic method. */
+ float mDownloadProgress;
+
+ /** The mutex used to guard access to mNewLabelCaption and mDownloadProgress. */
+ Mutex mDownloadMutex;
+
+ /** The Adler32 checksum of the file currently downloading. */
+ unsigned long mCurrentChecksum;
+
+ /** A flag to indicate whether to use a memory buffer or a regular file. */
+ bool mStoreInMemory;
+
+ /** Flag that show if current download is complete. */
+ bool mDownloadComplete;
+
+ /** Flag that show if the user has canceled the update. */
+ bool mUserCancel;
+
+ /** Byte count currently downloaded in mMemoryBuffer. */
+ int mDownloadedBytes;
+
+ /** Buffer for files downloaded to memory. */
+ char *mMemoryBuffer;
+
+ /** Download handle. */
+ Net::Download *mDownload;
+
+ /** List of files to download. */
+ std::vector<updateFile> mUpdateFiles;
+
+ /** Index of the file to be downloaded. */
+ unsigned int mUpdateIndex;
+
+ /** Tells ~UpdaterWindow() if it should load updates */
+ bool mLoadUpdates;
+
+ int mUpdateType;
+
+ gcn::Label *mLabel; /**< Progress bar caption. */
+ Button *mCancelButton; /**< Button to stop the update process. */
+ Button *mPlayButton; /**< Button to start playing. */
+ ProgressBar *mProgressBar; /**< Update progress bar. */
+ BrowserBox *mBrowserBox; /**< Box to display news. */
+ ScrollArea *mScrollArea; /**< Used to scroll news box. */
+};
+
+#endif
diff --git a/src/gui/userpalette.cpp b/src/gui/userpalette.cpp
new file mode 100644
index 000000000..03e5c1eed
--- /dev/null
+++ b/src/gui/userpalette.cpp
@@ -0,0 +1,292 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "userpalette.h"
+
+#include "configuration.h"
+#include "client.h"
+#include "log.h"
+
+#include "gui/gui.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <math.h>
+
+const std::string ColorTypeNames[] =
+{
+ "ColorBeing",
+ "ColorFriend",
+ "ColorDisregarded",
+ "ColorIgnored",
+ "ColorErased",
+ "ColorPlayer",
+ "ColorSelf",
+ "ColorGM",
+ "ColorNPC",
+ "ColorMonster",
+ "ColorMonsterHp",
+ "ColorMonsterHp2",
+ "ColorParty",
+ "ColorGuild",
+ "ColorParticle",
+ "ColorPickupInfo",
+ "ColorExpInfo",
+ "ColorHitPlayerMonster",
+ "ColorHitMonsterPlayer",
+ "ColorHitPlayerPlayer",
+ "ColorHitCritical",
+ "ColorHitLocalPlayerMonster",
+ "ColorHitLocalPlayerCritical",
+ "ColorHitLocalPlayerMiss",
+ "ColorMiss",
+ "ColorPortalHighlight",
+ "ColorCollisionHighlight",
+ "ColorWalkableTileHighlight",
+ "ColorAttackRange",
+ "ColorAttackRangeBorder",
+ "ColorMonsterAttackRange",
+ "ColorHomePlace",
+ "ColorHomePlaceBorder",
+ "ColorRoadPoint"
+};
+
+std::string UserPalette::getConfigName(const std::string &typeName)
+{
+ std::string res = "Color" + typeName;
+
+ int pos = 5;
+ for (size_t i = 0; i < typeName.length(); i++)
+ {
+ if (i == 0 || typeName[i] == '_')
+ {
+ if (i > 0)
+ i++;
+
+ res[pos] = typeName[i];
+ }
+ else
+ {
+ res[pos] = static_cast<char>(tolower(typeName[i]));
+ }
+ pos++;
+ }
+ res.erase(pos, res.length() - pos);
+
+ return res;
+}
+
+UserPalette::UserPalette():
+ Palette(USER_COLOR_LAST)
+{
+ mColors[BEING] = ColorElem();
+ mColors[PC] = ColorElem();
+ mColors[SELF] = ColorElem();
+ mColors[GM] = ColorElem();
+ mColors[NPC] = ColorElem();
+ mColors[MONSTER] = ColorElem();
+
+ addColor(BEING, 0xffffff, STATIC, _("Being"));
+ addColor(FRIEND, 0xb0ffb0, STATIC, _("Friend Names"));
+ addColor(DISREGARDED, 0xa00000, STATIC, _("Disregarded Names"));
+ addColor(IGNORED, 0xff0000, STATIC, _("Ignored Names"));
+ addColor(ERASED, 0xff0000, STATIC, _("Erased Names"));
+ addColor(PC, 0xffffff, STATIC, _("Other Players' Names"));
+ addColor(SELF, 0xff8040, STATIC, _("Own Name"));
+ addColor(GM, 0x00ff00, STATIC, _("GM Names"));
+ addColor(NPC, 0xc8c8ff, STATIC, _("NPCs"));
+ addColor(MONSTER, 0xff4040, STATIC, _("Monsters"));
+ addColor(MONSTER_HP, 0x00ff00, STATIC, _("Monster HP bar"), 50);
+ addColor(MONSTER_HP2, 0xff0000, STATIC,
+ _("Monster HP bar (second color)"), 50);
+ addColor(PARTY, 0xff00d8, STATIC, _("Party Members"));
+ addColor(GUILD, 0xff00d8, STATIC, _("Guild Members"));
+ addColor(PARTICLE, 0xffffff, STATIC, _("Particle Effects"));
+ addColor(PICKUP_INFO, 0x28dc28, STATIC, _("Pickup Notification"));
+ addColor(EXP_INFO, 0xffff00, STATIC, _("Exp Notification"));
+ addColor(HIT_PLAYER_MONSTER, 0x0064ff, STATIC, _("Player Hits Monster"));
+ addColor(HIT_MONSTER_PLAYER, 0xff3232, STATIC, _("Monster Hits Player"));
+ addColor(HIT_PLAYER_PLAYER, 0xff5050, STATIC,
+ _("Other Player Hits Local Player"));
+ addColor(HIT_CRITICAL, 0xff0000, RAINBOW, _("Critical Hit"));
+ addColor(HIT_LOCAL_PLAYER_MONSTER, 0x00ff00, STATIC,
+ _("Local Player Hits Monster"));
+ addColor(HIT_LOCAL_PLAYER_CRITICAL, 0xff0000, RAINBOW,
+ _("Local Player Critical Hit"));
+ addColor(HIT_LOCAL_PLAYER_MISS, 0x00ffa6, STATIC,
+ _("Local Player Miss"));
+ addColor(MISS, 0xffff00, STATIC, _("Misses"));
+ addColor(PORTAL_HIGHLIGHT, 0xC80000, STATIC, _("Portal Highlight"));
+ addColor(COLLISION_HIGHLIGHT, 0x0000C8, STATIC,
+ _("Collision Highlight"), 64);
+ addColor(WALKABLE_HIGHLIGHT, 0x00D000, STATIC,
+ _("Walkable Highlight"), 255);
+ addColor(ATTACK_RANGE, 0xffffff, STATIC,
+ _("Local Player Attack Range"), 5);
+ addColor(ATTACK_RANGE_BORDER, 0x0, STATIC,
+ _("Local Player Attack Range Border"), 76);
+ addColor(MONSTER_ATTACK_RANGE, 0xff0000, STATIC,
+ _("Monster Attack Range"), 20);
+ addColor(HOME_PLACE, 0xffffff, STATIC,
+ _("Home Place"), 20);
+ addColor(HOME_PLACE_BORDER, 0xffff00, STATIC,
+ _("Home Place Border"), 200);
+ addColor(ROAD_POINT, 0x000000, STATIC,
+ _("Road Point"), 100);
+ commit(true);
+}
+
+UserPalette::~UserPalette()
+{
+ for (Colors::iterator col = mColors.begin(),
+ colEnd = mColors.end(); col != colEnd; ++col)
+ {
+ const std::string &configName = ColorTypeNames[col->type];
+ config.setValue(configName + "Gradient",
+ static_cast<int>(col->committedGrad));
+ config.setValue(configName + "Delay", col->delay);
+
+ if (col->grad == STATIC || col->grad == PULSE)
+ {
+ char buffer[20];
+ sprintf(buffer, "0x%06x", col->getRGB());
+ config.setValue(configName, std::string(buffer));
+ }
+ }
+}
+
+void UserPalette::setColor(int type, int r, int g, int b)
+{
+ mColors[type].color.r = r;
+ mColors[type].color.g = g;
+ mColors[type].color.b = b;
+}
+
+void UserPalette::setGradient(int type, GradientType grad)
+{
+ ColorElem *elem = &mColors[type];
+ if (!elem)
+ return;
+
+ if (elem->grad != STATIC && grad == STATIC)
+ {
+ for (size_t i = 0; i < mGradVector.size(); i++)
+ {
+ if (mGradVector[i] == elem)
+ {
+ mGradVector.erase(mGradVector.begin() + i);
+ break;
+ }
+ }
+ }
+ else if (elem->grad == STATIC && grad != STATIC)
+ {
+ mGradVector.push_back(elem);
+ }
+
+ if (elem->grad != grad)
+ elem->grad = grad;
+}
+
+std::string UserPalette::getElementAt(int i)
+{
+ if (i < 0 || i >= getNumberOfElements())
+ return "";
+
+ return mColors[i].text;
+}
+
+void UserPalette::commit(bool commitNonStatic)
+{
+ for (Colors::iterator i = mColors.begin(), iEnd = mColors.end();
+ i != iEnd; ++i)
+ {
+ i->committedGrad = i->grad;
+ i->committedDelay = i->delay;
+ if (commitNonStatic || i->grad == STATIC)
+ i->committedColor = i->color;
+ else if (i->grad == PULSE)
+ i->committedColor = i->testColor;
+ }
+}
+
+void UserPalette::rollback()
+{
+ for (Colors::iterator i = mColors.begin(), iEnd = mColors.end();
+ i != iEnd; ++i)
+ {
+ if (i->grad != i->committedGrad)
+ setGradient(i->type, i->committedGrad);
+
+ setGradientDelay(i->type, i->committedDelay);
+ setColor(i->type, i->committedColor.r,
+ i->committedColor.g, i->committedColor.b);
+
+ if (i->grad == PULSE)
+ {
+ i->testColor.r = i->committedColor.r;
+ i->testColor.g = i->committedColor.g;
+ i->testColor.b = i->committedColor.b;
+ }
+ }
+}
+
+int UserPalette::getColorTypeAt(int i)
+{
+ if (i < 0 || i >= getNumberOfElements())
+ return BEING;
+
+ return mColors[i].type;
+}
+
+void UserPalette::addColor(unsigned type, unsigned rgb,
+ Palette::GradientType grad, const std::string &text,
+ int delay)
+{
+ const unsigned maxType = sizeof(ColorTypeNames)
+ / sizeof(ColorTypeNames[0]);
+
+ if (type >= maxType)
+ return;
+
+ const std::string &configName = ColorTypeNames[type];
+ char buffer[20];
+ sprintf(buffer, "0x%06x", rgb);
+
+ const std::string rgbString = config.getValue(configName,
+ std::string(buffer));
+ unsigned int rgbValue = 0;
+ if (rgbString.length() == 8 && rgbString[0] == '0' && rgbString[1] == 'x')
+ rgbValue = atox(rgbString);
+ else
+ rgbValue = atoi(rgbString.c_str());
+ gcn::Color trueCol = rgbValue;
+ grad = static_cast<GradientType>(config.getValue(configName + "Gradient",
+ static_cast<int>(grad)));
+ delay = config.getValueInt(configName + "Delay", delay);
+ mColors[type].set(type, trueCol, grad, delay);
+ mColors[type].text = text;
+
+ if (grad != STATIC)
+ mGradVector.push_back(&mColors[type]);
+}
diff --git a/src/gui/userpalette.h b/src/gui/userpalette.h
new file mode 100644
index 000000000..057d47113
--- /dev/null
+++ b/src/gui/userpalette.h
@@ -0,0 +1,222 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef USER_PALETTE_H
+#define USER_PALETTE_H
+
+#include "gui/palette.h"
+
+#include <guichan/listmodel.hpp>
+
+/**
+ * Class controlling the game's color palette.
+ */
+class UserPalette : public Palette, public gcn::ListModel
+{
+ public:
+ /** List of all colors that are configurable. */
+ enum
+ {
+ BEING = 0,
+ FRIEND,
+ DISREGARDED,
+ IGNORED,
+ ERASED,
+ PC,
+ SELF,
+ GM,
+ NPC,
+ MONSTER,
+ MONSTER_HP,
+ MONSTER_HP2,
+ PARTY,
+ GUILD,
+ PARTICLE,
+ PICKUP_INFO,
+ EXP_INFO,
+ HIT_PLAYER_MONSTER,
+ HIT_MONSTER_PLAYER,
+ HIT_PLAYER_PLAYER,
+ HIT_CRITICAL,
+ HIT_LOCAL_PLAYER_MONSTER,
+ HIT_LOCAL_PLAYER_CRITICAL,
+ HIT_LOCAL_PLAYER_MISS,
+ MISS,
+ PORTAL_HIGHLIGHT,
+ COLLISION_HIGHLIGHT,
+ WALKABLE_HIGHLIGHT,
+ ATTACK_RANGE,
+ ATTACK_RANGE_BORDER,
+ MONSTER_ATTACK_RANGE,
+ HOME_PLACE,
+ HOME_PLACE_BORDER,
+ ROAD_POINT,
+ USER_COLOR_LAST
+ };
+
+ /**
+ * Constructor
+ */
+ UserPalette();
+
+ /**
+ * Destructor
+ */
+ ~UserPalette();
+
+ /**
+ * Gets the committed color associated with the specified type.
+ *
+ * @param type the color type requested
+ *
+ * @return the requested committed color
+ */
+ inline const gcn::Color &getCommittedColor(int type)
+ {
+ return mColors[type].committedColor;
+ }
+
+ /**
+ * Gets the test color associated with the specified type.
+ *
+ * @param type the color type requested
+ *
+ * @return the requested test color
+ */
+ inline const gcn::Color &getTestColor(int type)
+ { return mColors[type].testColor; }
+
+ /**
+ * Sets the test color associated with the specified type.
+ *
+ * @param type the color type requested
+ * @param color the color that should be tested
+ */
+ inline void setTestColor(int type, gcn::Color color)
+ { mColors[type].testColor = color; }
+
+ /**
+ * Sets the color for the specified type.
+ *
+ * @param type color to be set
+ * @param r red component
+ * @param g green component
+ * @param b blue component
+ */
+ void setColor(int type, int r, int g, int b);
+
+ /**
+ * Sets the gradient type for the specified color.
+ *
+ * @param grad gradient type to set
+ */
+ void setGradient(int type, Palette::GradientType grad);
+
+ /**
+ * Sets the gradient delay for the specified color.
+ *
+ * @param grad gradient type to set
+ */
+ void setGradientDelay(int type, int delay)
+ { mColors[type].delay = delay; }
+
+ /**
+ * Returns the number of colors known.
+ *
+ * @return the number of colors known
+ */
+ inline int getNumberOfElements()
+ { return static_cast<int>(mColors.size()); }
+
+ /**
+ * Returns the name of the ith color.
+ *
+ * @param i index of color interested in
+ *
+ * @return the name of the color
+ */
+ std::string getElementAt(int i);
+
+ /**
+ * Commit the colors
+ */
+ inline void commit()
+ { commit(false); }
+
+ /**
+ * Rollback the colors
+ */
+ void rollback();
+
+ /**
+ * Gets the ColorType used by the color for the element at index i in
+ * the current color model.
+ *
+ * @param i the index of the color
+ *
+ * @return the color type of the color with the given index
+ */
+ int getColorTypeAt(int i);
+
+ private:
+ /**
+ * Define a color replacement.
+ *
+ * @param i the index of the color to replace
+ * @param r red component
+ * @param g green component
+ * @param b blue component
+ */
+ void setColorAt(int i, int r, int g, int b);
+
+ /**
+ * Commit the colors. Commit the non-static color values, if
+ * commitNonStatic is true. Only needed in the constructor.
+ */
+ void commit(bool commitNonStatic);
+
+ /**
+ * Prefixes the given string with "Color", lowercases all letters but
+ * the first and all following a '_'. All '_'s will be removed.
+ *
+ * E.g.: HIT_PLAYER_MONSTER -> HitPlayerMonster
+ *
+ * @param typeName string to transform
+ *
+ * @return the transformed string
+ */
+ static std::string getConfigName(const std::string &typeName);
+
+ /**
+ * Initialise color
+ *
+ * @param c character that needs initialising
+ * @param rgb default color if not found in config
+ * @param text identifier of color
+ */
+ void addColor(unsigned type, unsigned rgb, GradientType grad,
+ const std::string &text, int delay = GRADIENT_DELAY);
+};
+
+extern UserPalette *userPalette;
+
+#endif // USER_PALETTE_H
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
new file mode 100644
index 000000000..e2bab0621
--- /dev/null
+++ b/src/gui/viewport.cpp
@@ -0,0 +1,763 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/viewport.h"
+
+#include "actorsprite.h"
+#include "actorspritemanager.h"
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "itemshortcut.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "map.h"
+#include "textmanager.h"
+
+#include "gui/beingpopup.h"
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/ministatus.h"
+#include "gui/popupmenu.h"
+#include "gui/statuspopup.h"
+#include "gui/textpopup.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+
+#include "net/net.h"
+
+#include "resources/resourcemanager.h"
+
+#include "utils/stringutils.h"
+
+extern volatile int tick_time;
+
+Viewport::Viewport():
+ mMap(0),
+ mMouseX(0),
+ mMouseY(0),
+ mPixelViewX(0.0f),
+ mPixelViewY(0.0f),
+// mTileViewX(0),
+// mTileViewY(0),
+ mShowDebugPath(false),
+ mCameraMode(0),
+ mPlayerFollowMouse(false),
+ mLocalWalkTime(-1),
+ mHoverBeing(0),
+ mHoverItem(0),
+ mHoverSign(0),
+ mCameraRelativeX(0),
+ mCameraRelativeY(0)
+{
+ setOpaque(false);
+ addMouseListener(this);
+
+ mScrollLaziness = config.getIntValue("ScrollLaziness");
+ mScrollRadius = config.getIntValue("ScrollRadius");
+ mScrollCenterOffsetX = config.getIntValue("ScrollCenterOffsetX");
+ mScrollCenterOffsetY = config.getIntValue("ScrollCenterOffsetY");
+
+ config.addListener("ScrollLaziness", this);
+ config.addListener("ScrollRadius", this);
+
+ mPopupMenu = new PopupMenu;
+ mBeingPopup = new BeingPopup;
+ mTextPopup = new TextPopup;
+
+ setFocusable(true);
+}
+
+Viewport::~Viewport()
+{
+ config.removeListener("ScrollLaziness", this);
+ config.removeListener("ScrollRadius", this);
+
+ delete mPopupMenu;
+ mPopupMenu = 0;
+ delete mBeingPopup;
+ mBeingPopup = 0;
+ delete mTextPopup;
+ mTextPopup = 0;
+}
+
+void Viewport::setMap(Map *map)
+{
+ if (mMap && map)
+ map->setDebugFlags(mMap->getDebugFlags());
+ mMap = map;
+}
+
+extern MiniStatusWindow *miniStatusWindow;
+
+void Viewport::draw(gcn::Graphics *gcnGraphics)
+{
+ static int lastTick = tick_time;
+
+ if (!mMap || !player_node)
+ {
+ gcnGraphics->setColor(gcn::Color(64, 64, 64));
+ gcnGraphics->fillRectangle(
+ gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ return;
+ }
+
+ Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
+
+ // Avoid freaking out when tick_time overflows
+ if (tick_time < lastTick)
+ lastTick = tick_time;
+
+ // Calculate viewpoint
+ int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 2;
+ int midTileY = (graphics->getHeight() + mScrollCenterOffsetX) / 2;
+
+ const Vector &playerPos = player_node->getPosition();
+ const int player_x = static_cast<int>(playerPos.x)
+ - midTileX + mCameraRelativeX;
+ const int player_y = static_cast<int>(playerPos.y)
+ - midTileY + mCameraRelativeY;
+
+ if (mScrollLaziness < 1)
+ mScrollLaziness = 1; // Avoids division by zero
+
+ // Apply lazy scrolling
+ while (lastTick < tick_time)
+ {
+ if (player_x > static_cast<int>(mPixelViewX) + mScrollRadius)
+ {
+ mPixelViewX += static_cast<float>(player_x
+ - static_cast<int>(mPixelViewX) - mScrollRadius) /
+ static_cast<float>(mScrollLaziness);
+ }
+ if (player_x < static_cast<int>(mPixelViewX) - mScrollRadius)
+ {
+ mPixelViewX += static_cast<float>(player_x
+ - static_cast<int>(mPixelViewX) + mScrollRadius) /
+ static_cast<float>(mScrollLaziness);
+ }
+ if (player_y > static_cast<int>(mPixelViewY) + mScrollRadius)
+ {
+ mPixelViewY += static_cast<float>(player_y
+ - static_cast<int>(mPixelViewY) - mScrollRadius) /
+ static_cast<float>(mScrollLaziness);
+ }
+ if (player_y < static_cast<int>(mPixelViewY) - mScrollRadius)
+ {
+ mPixelViewY += static_cast<float>(player_y
+ - static_cast<int>(mPixelViewY) + mScrollRadius) /
+ static_cast<float>(mScrollLaziness);
+ }
+ lastTick++;
+ }
+
+ // Auto center when player is off screen
+ if (player_x - static_cast<int>(mPixelViewX) > graphics->getWidth() / 2
+ || static_cast<int>(mPixelViewX) - player_x > graphics->getWidth() / 2
+ || static_cast<int>(mPixelViewY) - player_y
+ > graphics->getHeight() / 2
+ || player_y - static_cast<int>(mPixelViewY)
+ > graphics->getHeight() / 2)
+ {
+ mPixelViewX = static_cast<float>(player_x);
+ mPixelViewY = static_cast<float>(player_y);
+ };
+
+ // Don't move camera so that the end of the map is on screen
+ const int viewXmax =
+ mMap->getWidth() * mMap->getTileWidth() - graphics->getWidth();
+ const int viewYmax =
+ mMap->getHeight() * mMap->getTileHeight() - graphics->getHeight();
+ if (mMap)
+ {
+ if (mPixelViewX < 0)
+ mPixelViewX = 0;
+ if (mPixelViewY < 0)
+ mPixelViewY = 0;
+ if (mPixelViewX > viewXmax)
+ mPixelViewX = static_cast<float>(viewXmax);
+ if (mPixelViewY > viewYmax)
+ mPixelViewY = static_cast<float>(viewYmax);
+ }
+
+ // Draw tiles and sprites
+ if (mMap)
+ {
+ mMap->draw(graphics, static_cast<int>(mPixelViewX),
+ static_cast<int>(mPixelViewY));
+
+ if (mShowDebugPath)
+ {
+ mMap->drawCollision(graphics,
+ static_cast<int>(mPixelViewX),
+ static_cast<int>(mPixelViewY),
+ mShowDebugPath);
+ if (mShowDebugPath == Map::MAP_DEBUG)
+ _drawDebugPath(graphics);
+ }
+ }
+
+ if (player_node->getCheckNameSetting())
+ {
+ player_node->setCheckNameSetting(false);
+ player_node->setName(player_node->getName());
+ }
+
+ // Draw text
+ if (textManager)
+ textManager->draw(graphics, static_cast<int>(mPixelViewX),
+ static_cast<int>(mPixelViewY));
+
+ // Draw player names, speech, and emotion sprite as needed
+ const ActorSprites &actors = actorSpriteManager->getAll();
+ for (ActorSpritesConstIterator it = actors.begin(), it_end = actors.end();
+ it != it_end; it++)
+ {
+ if ((*it)->getType() == ActorSprite::FLOOR_ITEM)
+ continue;
+ Being *b = static_cast<Being*>(*it);
+
+ b->drawSpeech(static_cast<int>(mPixelViewX),
+ static_cast<int>(mPixelViewY));
+ b->drawEmotion(graphics, static_cast<int>(mPixelViewX),
+ static_cast<int>(mPixelViewY));
+ }
+
+ if (miniStatusWindow)
+ miniStatusWindow->drawIcons(graphics);
+
+ // Draw contained widgets
+ WindowContainer::draw(gcnGraphics);
+}
+
+void Viewport::logic()
+{
+ WindowContainer::logic();
+
+ // Make the player follow the mouse position
+ // if the mouse is dragged elsewhere than in a window.
+ _followMouse();
+}
+
+void Viewport::_followMouse()
+{
+ Uint8 button = SDL_GetMouseState(&mMouseX, &mMouseY);
+ // If the left button is dragged
+ if (mPlayerFollowMouse && button & SDL_BUTTON(1))
+ {
+ // We create a mouse event and send it to mouseDragged.
+ Uint8 *keys = SDL_GetKeyState(NULL);
+ gcn::MouseEvent mouseEvent(NULL,
+ (keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]),
+ false,
+ false,
+ false,
+ gcn::MouseEvent::DRAGGED,
+ gcn::MouseEvent::LEFT,
+ mMouseX,
+ mMouseY,
+ 0);
+
+ mouseDragged(mouseEvent);
+ }
+}
+
+void Viewport::_drawDebugPath(Graphics *graphics)
+{
+ // Get the current mouse position
+ SDL_GetMouseState(&mMouseX, &mMouseY);
+
+ Path debugPath;
+
+ if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+ const int mouseTileX = (mMouseX + static_cast<int>(mPixelViewX)) / 32;
+ const int mouseTileY = (mMouseY + static_cast<int>(mPixelViewY)) / 32;
+ const Vector &playerPos = player_node->getPosition();
+
+ debugPath = mMap->findPath(
+ static_cast<int>(playerPos.x - 16) / 32,
+ static_cast<int>(playerPos.y - 32) / 32,
+ mouseTileX, mouseTileY, 0, 500);
+
+ _drawPath(graphics, debugPath);
+ }
+ else if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ const Vector &playerPos = player_node->getPosition();
+ const int playerRadius = player_node->getCollisionRadius();
+ // Draw player collision rectangle
+ graphics->setColor(gcn::Color(128, 128, 0, 120));
+ graphics->fillRectangle(
+ gcn::Rectangle(static_cast<int>(playerPos.x)
+ - static_cast<int>(mPixelViewX) - playerRadius,
+ static_cast<int>(playerPos.y)
+ - static_cast<int>(mPixelViewY) - playerRadius,
+ playerRadius * 2, playerRadius * 2));
+
+ debugPath = mMap->findPixelPath(
+ static_cast<int>(playerPos.x),
+ static_cast<int>(playerPos.y),
+ mMouseX + static_cast<int>(mPixelViewX),
+ mMouseY + static_cast<int>(mPixelViewY),
+ playerRadius, 0xFF);
+
+ // We draw the path proposed by mouse
+ _drawPath(graphics, debugPath, gcn::Color(128, 0, 128));
+
+ // But also the one currently walked on.
+ _drawPath(graphics, player_node->getPath(), gcn::Color(0, 0, 255));
+ }
+}
+
+void Viewport::_drawPath(Graphics *graphics, const Path &path,
+ gcn::Color color)
+{
+ graphics->setColor(color);
+
+ if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+ for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
+ {
+ int squareX = i->x * 32 - static_cast<int>(mPixelViewX) + 12;
+ int squareY = i->y * 32 - static_cast<int>(mPixelViewY) + 12;
+
+ graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8));
+ if (mMap)
+ {
+ graphics->drawText(
+ toString(mMap->getMetaTile(i->x, i->y)->Gcost),
+ squareX + 4, squareY + 12, gcn::Graphics::CENTER);
+ }
+ }
+ }
+ else if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
+ {
+ int squareX = i->x - static_cast<int>(mPixelViewX);
+ int squareY = i->y - static_cast<int>(mPixelViewY);
+
+ graphics->fillRectangle(gcn::Rectangle(squareX - 4, squareY - 4,
+ 8, 8));
+ if (mMap)
+ {
+ graphics->drawText(
+ toString(mMap->getMetaTile(i->x / 32, i->y / 32)->Gcost),
+ squareX + 4, squareY + 12, gcn::Graphics::CENTER);
+ }
+ }
+
+ }
+}
+
+void Viewport::mousePressed(gcn::MouseEvent &event)
+{
+ if (event.getSource() != this)
+ return;
+
+ // Check if we are alive and kickin'
+// if (!mMap || !player_node || !player_node->isAlive())
+ if (!mMap || !player_node)
+ return;
+
+ // Check if we are busy
+ // if commented, allow context menu if npc dialog open
+ if (Being::isTalking())
+ return;
+
+ mPlayerFollowMouse = false;
+
+ const int pixelX = event.getX() + static_cast<int>(mPixelViewX);
+ const int pixelY = event.getY() + static_cast<int>(mPixelViewY);
+
+ // Right click might open a popup
+ if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ if (mHoverBeing)
+ {
+ if (actorSpriteManager)
+ {
+ std::list<Being*> beings;
+ const int x = getMouseX() + static_cast<int>(mPixelViewX);
+ const int y = getMouseY() + static_cast<int>(mPixelViewY);
+ actorSpriteManager->findBeingsByPixel(beings, x, y, true);
+ if (beings.size() > 1)
+ {
+ mPopupMenu->showPopup(event.getX(), event.getY(), beings);
+ return;
+ }
+ else
+ {
+ mPopupMenu->showPopup(event.getX(), event.getY(),
+ mHoverBeing);
+ return;
+ }
+ }
+ }
+ else if (mHoverItem)
+ {
+ mPopupMenu->showPopup(event.getX(), event.getY(), mHoverItem);
+ return;
+ }
+ else if (mHoverSign)
+ {
+ mPopupMenu->showPopup(event.getX(), event.getY(), mHoverSign);
+ return;
+ }
+ }
+
+ // If a popup is active, just remove it
+ if (mPopupMenu->isVisible())
+ {
+ mPopupMenu->setVisible(false);
+ return;
+ }
+
+ // Left click can cause different actions
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ // Interact with some being
+ if (mHoverBeing)
+ {
+ if (!mHoverBeing->isAlive())
+ return;
+
+ if (mHoverBeing->canTalk())
+ {
+ mHoverBeing->talkTo();
+ }
+ else
+ {
+ if (mHoverBeing->getType() == ActorSprite::PLAYER)
+ {
+ if (actorSpriteManager)
+ actorSpriteManager->heal(player_node, mHoverBeing);
+ }
+ else if (player_node->withinAttackRange(mHoverBeing) ||
+ keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ {
+ player_node->attack(mHoverBeing,
+ !keyboard.isKeyActive(keyboard.KEY_TARGET));
+ }
+ else if (!keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ {
+ player_node->setGotoTarget(mHoverBeing);
+ }
+ }
+ // Picks up a item if we clicked on one
+ }
+ else if (mHoverItem)
+ {
+ player_node->pickUp(mHoverItem);
+ }
+ // Just walk around
+ else if (!keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ {
+ player_node->stopAttack();
+ player_node->cancelFollow();
+ mPlayerFollowMouse = true;
+
+ // Make the player go to the mouse position
+ _followMouse();
+ }
+ }
+ else if (event.getButton() == gcn::MouseEvent::MIDDLE)
+ {
+ // Find the being nearest to the clicked position
+ if (actorSpriteManager)
+ {
+ Being *target = actorSpriteManager->findNearestLivingBeing(
+ pixelX, pixelY, 20, ActorSprite::MONSTER);
+
+ if (target)
+ player_node->setTarget(target);
+ }
+ }
+}
+
+void Viewport::mouseDragged(gcn::MouseEvent &event)
+{
+ if (!mMap || !player_node)
+ return;
+
+ if (mPlayerFollowMouse && !event.isShiftPressed())
+ {
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ if (get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay)
+ {
+ mLocalWalkTime = tick_time;
+ player_node->setDestination(event.getX()
+ + static_cast<int>(mPixelViewX),
+ event.getY()
+ + static_cast<int>(mPixelViewY));
+ player_node->pathSetByMouse();
+ }
+ }
+ else
+ {
+ if (mLocalWalkTime != player_node->getActionTime())
+ {
+ mLocalWalkTime = player_node->getActionTime();
+ int destX = static_cast<int>((static_cast<float>(event.getX())
+ + mPixelViewX)
+ / static_cast<float>(mMap->getTileWidth()));
+ int destY = static_cast<int>((static_cast<float>(event.getY())
+ + mPixelViewY)
+ / static_cast<float>(mMap->getTileHeight()));
+ player_node->setDestination(destX, destY);
+ }
+ }
+ }
+}
+
+void Viewport::mouseReleased(gcn::MouseEvent &event _UNUSED_)
+{
+ mPlayerFollowMouse = false;
+
+ // Only useful for eAthena but doesn't hurt under ManaServ
+ mLocalWalkTime = -1;
+}
+
+void Viewport::showPopup(Window *parent, int x, int y, Item *item,
+ bool isInventory)
+{
+ mPopupMenu->showPopup(parent, x, y, item, isInventory);
+}
+
+void Viewport::showPopup(MapItem *item)
+{
+ mPopupMenu->showPopup(getMouseX(), getMouseY(), item);
+}
+
+void Viewport::showPopup(Window *parent, Item *item, bool isInventory)
+{
+ mPopupMenu->showPopup(parent, getMouseX(), getMouseY(), item, isInventory);
+}
+
+void Viewport::showItemPopup(Item *item)
+{
+ mPopupMenu->showItemPopup(getMouseX(), getMouseY(), item);
+}
+
+void Viewport::showItemPopup(int itemId)
+{
+ mPopupMenu->showItemPopup(getMouseX(), getMouseY(), itemId);
+}
+
+void Viewport::showDropPopup(Item *item)
+{
+ mPopupMenu->showDropPopup(getMouseX(), getMouseY(), item);
+}
+
+void Viewport::showOutfitsPopup(int x, int y)
+{
+ mPopupMenu->showOutfitsPopup(x, y);
+}
+
+void Viewport::showOutfitsPopup()
+{
+ mPopupMenu->showOutfitsPopup(getMouseX(), getMouseY());
+}
+
+void Viewport::showSpellPopup(TextCommand *cmd)
+{
+ mPopupMenu->showSpellPopup(getMouseX(), getMouseY(), cmd);
+}
+
+void Viewport::showChatPopup(int x, int y, ChatTab *tab)
+{
+ mPopupMenu->showChatPopup(x, y, tab);
+}
+
+void Viewport::showChatPopup(ChatTab *tab)
+{
+ mPopupMenu->showChatPopup(getMouseX(), getMouseY(), tab);
+}
+
+void Viewport::showPopup(int x, int y, Being *being)
+{
+ mPopupMenu->showPopup(x, y, being);
+}
+
+void Viewport::showPlayerPopup(std::string nick)
+{
+ mPopupMenu->showPlayerPopup(getMouseX(), getMouseY(), nick);
+}
+
+void Viewport::showPopup(int x, int y, Button *button)
+{
+ mPopupMenu->showPopup(x, y, button);
+}
+
+void Viewport::closePopupMenu()
+{
+ if (mPopupMenu)
+ mPopupMenu->handleLink("cancel", 0);
+}
+
+void Viewport::optionChanged(const std::string &name _UNUSED_)
+{
+ mScrollLaziness = config.getIntValue("ScrollLaziness");
+ mScrollRadius = config.getIntValue("ScrollRadius");
+}
+
+void Viewport::mouseMoved(gcn::MouseEvent &event _UNUSED_)
+{
+ // Check if we are on the map
+ if (!mMap || !player_node || !actorSpriteManager)
+ return;
+
+ const int x = getMouseX() + static_cast<int>(mPixelViewX);
+ const int y = getMouseY() + static_cast<int>(mPixelViewY);
+
+ mHoverBeing = actorSpriteManager->findBeingByPixel(x, y, true);
+ if (mHoverBeing && mHoverBeing->getType() == Being::PLAYER)
+ {
+ mTextPopup->setVisible(false);
+ mBeingPopup->show(getMouseX(), getMouseY(), mHoverBeing);
+ }
+ else
+ {
+ mBeingPopup->setVisible(false);
+ }
+
+ mHoverItem = 0;
+ if (!mHoverBeing && actorSpriteManager)
+ {
+ mHoverItem = actorSpriteManager->findItem(x / mMap->getTileWidth(),
+ y / mMap->getTileHeight());
+ }
+ if (!mHoverBeing && !mHoverItem)
+ {
+ SpecialLayer *specialLayer = mMap->getSpecialLayer();
+ if (specialLayer)
+ {
+ int mouseTileX = (getMouseX() + getCameraX())
+ / mMap->getTileWidth();
+ int mouseTileY = (getMouseY() + getCameraY())
+ / mMap->getTileHeight();
+
+ mHoverSign = specialLayer->getTile(mouseTileX, mouseTileY);
+ if (mHoverSign && mHoverSign->getType() != MapItem::EMPTY)
+ {
+ if (!mHoverSign->getComment().empty())
+ {
+ if (mBeingPopup)
+ mBeingPopup->setVisible(false);
+ mTextPopup->show(getMouseX(), getMouseY(),
+ mHoverSign->getComment());
+ }
+ else
+ {
+ if (mTextPopup->isVisible())
+ mTextPopup->setVisible(false);
+ }
+ return;
+ }
+ }
+ }
+ if (mTextPopup->isVisible())
+ mTextPopup->setVisible(false);
+
+ if (mHoverBeing)
+ {
+ switch (mHoverBeing->getType())
+ {
+ // NPCs
+ case ActorSprite::NPC:
+ gui->setCursorType(Gui::CURSOR_TALK);
+ break;
+
+ // Monsters
+ case ActorSprite::MONSTER:
+ gui->setCursorType(Gui::CURSOR_FIGHT);
+ break;
+ default:
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ break;
+ }
+ }
+ // Item mouseover
+ else if (mHoverItem)
+ {
+ gui->setCursorType(Gui::CURSOR_PICKUP);
+ }
+ else
+ {
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ }
+}
+
+void Viewport::toggleDebugPath()
+{
+ mShowDebugPath++;
+ if (mShowDebugPath > Map::MAP_BLACKWHITE)
+ mShowDebugPath = Map::MAP_NORMAL;
+ if (mMap)
+ mMap->setDebugFlags(mShowDebugPath);
+}
+
+void Viewport::toggleCameraMode()
+{
+ mCameraMode++;
+ if (mCameraMode > 1)
+ mCameraMode = 0;
+ if (!mCameraMode)
+ {
+ mCameraRelativeX = 0;
+ mCameraRelativeY = 0;
+ }
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void Viewport::hideBeingPopup()
+{
+ if (mBeingPopup)
+ mBeingPopup->setVisible(false);
+ if (mTextPopup)
+ mTextPopup->setVisible(false);
+}
+
+void Viewport::clearHover(ActorSprite *actor)
+{
+ if (mHoverBeing == actor)
+ mHoverBeing = 0;
+
+ if (mHoverItem == actor)
+ mHoverItem = 0;
+}
+
+void Viewport::cleanHoverItems()
+{
+ mHoverBeing = 0;
+ mHoverItem = 0;
+ mHoverSign = 0;
+}
+
+void Viewport::moveCamera(int dx, int dy)
+{
+ mCameraRelativeX += dx;
+ mCameraRelativeY += dy;
+} \ No newline at end of file
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
new file mode 100644
index 000000000..cf5e53c4d
--- /dev/null
+++ b/src/gui/viewport.h
@@ -0,0 +1,298 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef VIEWPORT_H
+#define VIEWPORT_H
+
+#include "actorspritemanager.h"
+#include "configlistener.h"
+#include "position.h"
+
+#include "gui/widgets/windowcontainer.h"
+
+#include <guichan/mouselistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class ActorSprite;
+class Button;
+class Being;
+class BeingPopup;
+class ChatTab;
+class FloorItem;
+class Graphics;
+class ImageSet;
+class Item;
+class ItemShortcut;
+class Map;
+class PopupMenu;
+class TextCommand;
+class StatusPopup;
+class TextPopup;
+class Window;
+
+/** Delay between two mouse calls when dragging mouse and move the player */
+const int walkingMouseDelay = 500;
+
+/**
+ * The viewport on the map. Displays the current map and handles mouse input
+ * and the popup menu.
+ *
+ * TODO: This class is planned to be extended to allow floating widgets on top
+ * of it such as NPC messages, which are positioned using map pixel
+ * coordinates.
+ */
+class Viewport : public WindowContainer, public gcn::MouseListener,
+ public ConfigListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Viewport();
+
+ /**
+ * Destructor.
+ */
+ ~Viewport();
+
+ /**
+ * Sets the map displayed by the viewport.
+ */
+ void setMap(Map *map);
+
+ /**
+ * Draws the viewport.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Implements player to keep following mouse.
+ */
+ void logic();
+
+ /**
+ * Toggles whether the path debug graphics are shown. normal, debug with all images and grid, debug with out big images and with out grid.
+ */
+ void toggleDebugPath();
+
+ void toggleCameraMode();
+
+ /**
+ * Handles mouse press on map.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse move on map
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse button release on map.
+ */
+ void mouseReleased(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse move on map.
+ */
+ void mouseMoved(gcn::MouseEvent &event);
+
+ /**
+ * Shows a popup for an item.
+ * TODO Find some way to get rid of Item here
+ */
+ void showPopup(Window *parent, int x, int y, Item *item,
+ bool isInventory = true);
+
+ /**
+ * Shows a popup for an item.
+ * TODO Find some way to get rid of Item here
+ */
+ void showPopup(Window *parent, Item *item, bool isInventory = true);
+
+ void showPopup(int x, int y, Button *button);
+
+ void showPopup(MapItem *item);
+
+ void showItemPopup(Item *item);
+
+ void showItemPopup(int itemId);
+
+ void showDropPopup(Item *item);
+
+ /**
+ * Shows a popup for being.
+ */
+ void showPopup(int x, int y, Being *being);
+
+ void showPlayerPopup(std::string nick);
+
+ void showOutfitsPopup(int x, int y);
+
+ void showOutfitsPopup();
+
+ void showSpellPopup(TextCommand *cmd);
+
+ /**
+ * Shows the related popup menu when right click on the chat
+ * at the specified mouse coordinates.
+ */
+ void showChatPopup(int x, int y, ChatTab *tab);
+
+ /**
+ * Shows the related popup menu when right click on the chat
+ */
+ void showChatPopup(ChatTab *tab);
+
+ /**
+ * Closes the popup menu. Needed for when the player dies or switching
+ * maps.
+ */
+ void closePopupMenu();
+
+ /**
+ * A relevant config option changed.
+ */
+ void optionChanged(const std::string &name);
+
+ /**
+ * Returns camera x offset in pixels.
+ */
+ int getCameraX() const
+ { return static_cast<int>(mPixelViewX); }
+
+ /**
+ * Returns camera y offset in pixels.
+ */
+ int getCameraY() const
+ { return static_cast<int>(mPixelViewY); }
+
+ /**
+ * Returns mouse x in pixels.
+ */
+ int getMouseX() const
+ { return mMouseX; }
+
+ /**
+ * Returns mouse y in pixels.
+ */
+ int getMouseY() const
+ { return mMouseY; }
+
+ /**
+ * Changes viewpoint by relative pixel coordinates.
+ */
+ void scrollBy(float x, float y)
+ { mPixelViewX += x; mPixelViewY += y; }
+
+ /**
+ * Returns the current map object.
+ */
+ Map *getCurrentMap() const
+ { return mMap; }
+
+ int getDebugPath()
+ { return mShowDebugPath; }
+
+ int getCameraMode()
+ { return mCameraMode; }
+
+ /**
+ * Hides the BeingPopup.
+ */
+ void hideBeingPopup();
+
+ /**
+ * Clear all hover item\being etc
+ */
+ void cleanHoverItems();
+
+ Map *getMap()
+ { return mMap; }
+
+ void moveCamera(int dx, int dy);
+
+ int getCameraRelativeX()
+ { return mCameraRelativeX; }
+
+ int getCameraRelativeY()
+ { return mCameraRelativeY; }
+
+ protected:
+ friend class ActorSpriteManager;
+
+ /// Clears any matching hovers
+ void clearHover(ActorSprite *actor);
+
+ private:
+ /**
+ * Finds a path from the player to the mouse, and draws it. This is for
+ * debug purposes.
+ */
+ void _drawDebugPath(Graphics *graphics);
+
+ /**
+ * Draws the given path.
+ */
+ void _drawPath(Graphics *graphics, const Path &path,
+ gcn::Color color = gcn::Color(255, 0, 0));
+
+ /**
+ * Make the player go to the mouse position.
+ */
+ void _followMouse();
+
+ Map *mMap; /**< The current map. */
+
+ int mScrollRadius;
+ int mScrollLaziness;
+ int mScrollCenterOffsetX;
+ int mScrollCenterOffsetY;
+ int mMouseX; /**< Current mouse position in pixels. */
+ int mMouseY; /**< Current mouse position in pixels. */
+ float mPixelViewX; /**< Current viewpoint in pixels. */
+ float mPixelViewY; /**< Current viewpoint in pixels. */
+ int mShowDebugPath; /**< Show a path from player to pointer. */
+ int mCameraMode; /**< Camera mode. */
+
+ bool mPlayerFollowMouse;
+
+ int mLocalWalkTime; /**< Timestamp before the next walk can be sent. */
+
+ PopupMenu *mPopupMenu; /**< Popup menu. */
+ Being *mHoverBeing; /**< Being mouse is currently over. */
+ FloorItem *mHoverItem; /**< FloorItem mouse is currently over. */
+ MapItem *mHoverSign; /**< Map sign mouse is currently over. */
+ BeingPopup *mBeingPopup; /**< Being information popup. */
+ TextPopup *mTextPopup; /**< Map Item information popup. */
+
+ int mCameraRelativeX;
+ int mCameraRelativeY;
+};
+
+extern Viewport *viewport; /**< The viewport. */
+
+#endif
diff --git a/src/gui/whoisonline.cpp b/src/gui/whoisonline.cpp
new file mode 100644
index 000000000..84485b995
--- /dev/null
+++ b/src/gui/whoisonline.cpp
@@ -0,0 +1,550 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "whoisonline.h"
+
+#include <SDL.h>
+#include <SDL_thread.h>
+#include <vector>
+#include <algorithm>
+
+#include "gui/viewport.h"
+#include "gui/widgets/button.h"
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/chattab.h"
+
+#include "actorspritemanager.h"
+#include "client.h"
+#include "configuration.h"
+#include "localplayer.h"
+#include "playerrelations.h"
+#include "main.h"
+
+#include "gui/chat.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+// Curl should be included after Guichan to avoid Windows redefinitions
+#include <curl/curl.h>
+
+bool stringCompare(const std::string &left, const std::string &right);
+
+bool stringCompare(const std::string &left, const std::string &right )
+{
+ for (std::string::const_iterator lit = left.begin(),
+ rit = right.begin();
+ lit != left.end() && rit != right.end(); ++lit, ++rit)
+ {
+ if (tolower(*lit) < tolower(*rit))
+ return true;
+ else if (tolower(*lit) > tolower(*rit))
+ return false;
+ }
+ if (left.size() < right.size())
+ return true;
+ return false;
+}
+
+WhoIsOnline::WhoIsOnline():
+ Window(_("Who Is Online - Updating")),
+ mThread(NULL),
+ mDownloadStatus(UPDATE_LIST),
+ mDownloadComplete(true),
+ mDownloadedBytes(0),
+ mMemoryBuffer(NULL),
+ mCurlError(new char[CURL_ERROR_SIZE]),
+ mAllowUpdate(true),
+ mShowLevel(false)
+{
+ mCurlError[0] = 0;
+ setWindowName("WhoIsOnline");
+
+ const int h = 350;
+ const int w = 200;
+ setDefaultSize(w, h, ImageRect::CENTER);
+// setContentSize(w, h);
+ setCloseButton(true);
+ setResizable(true);
+
+ mUpdateButton = new Button(_("Update"), "update", this);
+ mUpdateButton->setEnabled(false);
+ mUpdateButton->setDimension(gcn::Rectangle(5, 5, w - 10, 20 + 5));
+
+ mBrowserBox = new BrowserBox();
+ mScrollArea = new ScrollArea(mBrowserBox);
+ mScrollArea->setOpaque(false);
+ mBrowserBox->setOpaque(false);
+ mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
+ mScrollArea->setDimension(gcn::Rectangle(5, 20 + 10, w - 10, h - 10 - 30));
+ mScrollArea->setSize(w - 10, h - 10 - 30);
+ mBrowserBox->setLinkHandler(this);
+
+ add(mUpdateButton);
+ add(mScrollArea);
+
+ mUpdateTimer = 0;
+ setLocationRelativeTo(getParent());
+
+ loadWindowState();
+
+ download();
+
+ config.addListener("updateOnlineList", this);
+ mUpdateOnlineList = config.getBoolValue("updateOnlineList");
+}
+
+WhoIsOnline::~WhoIsOnline()
+{
+ config.removeListener("updateOnlineList", this);
+
+ if (mThread && SDL_GetThreadID(mThread))
+ SDL_WaitThread(mThread, NULL);
+
+ free(mMemoryBuffer);
+ mMemoryBuffer = 0;
+
+ // Remove possibly leftover temporary download
+ delete[] mCurlError;
+}
+
+void WhoIsOnline::handleLink(const std::string& link, gcn::MouseEvent *event)
+{
+ if (!event || event->getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (chatWindow)
+ {
+ if (config.getBoolValue("whispertab"))
+ chatWindow->localChatInput("/q " + link);
+ else
+ chatWindow->addInputText("/w \"" + link + "\" ");
+ }
+ }
+ else if (event->getButton() == gcn::MouseEvent::RIGHT)
+ {
+ if (player_node && link == player_node->getName())
+ return;
+
+ if (viewport)
+ {
+ if (actorSpriteManager)
+ {
+ Being* being = actorSpriteManager->findBeingByName(
+ link, Being::PLAYER);
+
+ if (being && viewport)
+ {
+ viewport->showPopup(event->getX(), event->getY(), being);
+ return;
+ }
+ }
+ viewport->showPlayerPopup(link);
+ }
+ }
+}
+
+void WhoIsOnline::loadList()
+{
+ if (!mMemoryBuffer)
+ return;
+
+ // Reallocate and include terminating 0 character
+ mMemoryBuffer = static_cast<char*>(
+ realloc(mMemoryBuffer, mDownloadedBytes + 1));
+ mMemoryBuffer[mDownloadedBytes] = '\0';
+
+ mBrowserBox->clearRows();
+ bool listStarted(false);
+ std::string lineStr;
+ int numOnline(0);
+ std::vector<std::string> friends;
+ std::vector<std::string> neutral;
+ std::vector<std::string> disregard;
+
+ // Tokenize and add each line separately
+ char *line = strtok(mMemoryBuffer, "\n");
+ const std::string gmText = "(GM)";
+ mOnlinePlayers.clear();
+
+ mShowLevel = config.getBoolValue("showlevel");
+
+ while (line != NULL)
+ {
+ std::string nick;
+ lineStr = line;
+ trim(lineStr);
+ if (listStarted == true)
+ {
+ size_t found;
+ found = lineStr.find(" users are online.");
+ if (found == std::string::npos)
+ {
+ int level = 0;
+
+ std::string::size_type pos = 0;
+ if (lineStr.length() > 24)
+ {
+ nick = lineStr.substr(0, 24);
+ lineStr = lineStr.substr(25);
+ }
+ else
+ {
+ nick = lineStr;
+ lineStr = "";
+ }
+ trim(nick);
+
+ pos = lineStr.find(gmText, 0);
+ if (pos != std::string::npos)
+ lineStr = lineStr.substr(pos + gmText.length());
+
+ trim(lineStr);
+ pos = lineStr.find("/", 0);
+
+ if (pos != std::string::npos)
+ lineStr = lineStr.substr(0, pos);
+
+ if (!lineStr.empty())
+ level = atoi(lineStr.c_str());
+
+ if (actorSpriteManager)
+ {
+ Being *being = actorSpriteManager->findBeingByName(
+ nick, Being::PLAYER);
+ if (being)
+ {
+ if (level > 0)
+ {
+ being->setLevel(level);
+ being->updateName();
+ }
+ else
+ {
+ if (being->getLevel() > 1)
+ level = being->getLevel();
+ }
+ }
+ }
+
+ mOnlinePlayers.insert(nick);
+
+ numOnline++;
+ switch (player_relations.getRelation(nick))
+ {
+ case PlayerRelation::NEUTRAL:
+ neutral.push_back(prepareNick(nick, level, "0"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ friends.push_back(prepareNick(nick, level, "2"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ disregard.push_back(prepareNick(nick, level, "8"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ case PlayerRelation::ERASED:
+ default:
+ //Ignore the ignored.
+ break;
+ }
+ }
+ }
+ else if (lineStr.find("------------------------------")
+ != std::string::npos)
+ {
+ listStarted = true;
+ }
+ line = strtok(NULL, "\n");
+ }
+
+ //Set window caption
+ setCaption(_("Who Is Online - ") + toString(numOnline));
+
+ //List the online people
+ sort(friends.begin(), friends.end(), stringCompare);
+ sort(neutral.begin(), neutral.end(), stringCompare);
+ sort(disregard.begin(), disregard.end(), stringCompare);
+ bool addedFromSection(false);
+ for (int i = 0; i < static_cast<int>(friends.size()); i++)
+ {
+ mBrowserBox->addRow(friends.at(i));
+ addedFromSection = true;
+ }
+ if (addedFromSection == true)
+ {
+ mBrowserBox->addRow("---");
+ addedFromSection = false;
+ }
+ for (int i = 0; i < static_cast<int>(neutral.size()); i++)
+ {
+ mBrowserBox->addRow(neutral.at(i));
+ addedFromSection = true;
+ }
+ if (addedFromSection == true && !disregard.empty())
+ {
+ mBrowserBox->addRow("---");
+ addedFromSection = false;
+ }
+ for (int i = 0; i < static_cast<int>(disregard.size()); i++)
+ {
+ mBrowserBox->addRow(disregard.at(i));
+ }
+
+ // Free the memory buffer now that we don't need it anymore
+ free(mMemoryBuffer);
+ mMemoryBuffer = 0;
+
+ if (mScrollArea->getVerticalMaxScroll() <
+ mScrollArea->getVerticalScrollAmount())
+ {
+ mScrollArea->setVerticalScrollAmount(
+ mScrollArea->getVerticalMaxScroll());
+ }
+}
+
+size_t WhoIsOnline::memoryWrite(void *ptr, size_t size,
+ size_t nmemb, FILE *stream)
+{
+ WhoIsOnline *wio = reinterpret_cast<WhoIsOnline *>(stream);
+ size_t totalMem = size * nmemb;
+ wio->mMemoryBuffer = static_cast<char*>(realloc(wio->mMemoryBuffer,
+ wio->mDownloadedBytes + totalMem));
+ if (wio->mMemoryBuffer)
+ {
+ memcpy(&(wio->mMemoryBuffer[wio->mDownloadedBytes]), ptr, totalMem);
+ wio->mDownloadedBytes += static_cast<int>(totalMem);
+ }
+
+ return totalMem;
+}
+
+int WhoIsOnline::downloadThread(void *ptr)
+{
+ int attempts = 0;
+ WhoIsOnline *wio = reinterpret_cast<WhoIsOnline *>(ptr);
+ CURL *curl;
+ CURLcode res;
+
+ std::string url(Client::getServerName() + "/online.txt");
+
+ while (attempts < 1 && !wio->mDownloadComplete)
+ {
+ curl = curl_easy_init();
+
+ if (curl)
+ {
+ if (!wio->mAllowUpdate)
+ {
+ curl_easy_cleanup(curl);
+ break;
+ }
+ wio->mDownloadedBytes = 0;
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+ WhoIsOnline::memoryWrite);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr);
+
+ curl_easy_setopt(curl, CURLOPT_USERAGENT,
+ strprintf(PACKAGE_EXTENDED_VERSION, branding
+ .getValue("appShort", "mana").c_str()).c_str());
+
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, wio->mCurlError);
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, ptr);
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 7);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
+
+ struct curl_slist *pHeaders = 0;
+ // Make sure the resources2.txt and news.txt aren't cached,
+ // in order to always get the latest version.
+ pHeaders = curl_slist_append(pHeaders, "pragma: no-cache");
+ pHeaders =
+ curl_slist_append(pHeaders, "Cache-Control: no-cache");
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHeaders);
+
+ if ((res = curl_easy_perform(curl)) != 0)
+ {
+ wio->mDownloadStatus = UPDATE_ERROR;
+ switch (res)
+ {
+ case CURLE_COULDNT_CONNECT:
+ default:
+ std::cerr << "curl error "
+ << static_cast<unsigned>(res) << ": "
+ << wio->mCurlError << " host: "
+ << url.c_str() << std::endl;
+ break;
+ }
+ attempts++;
+ continue;
+ }
+
+ curl_easy_cleanup(curl);
+
+ curl_slist_free_all(pHeaders);
+
+ // It's stored in memory, we're done
+ wio->mDownloadComplete = true;
+ }
+ if (!wio->mAllowUpdate)
+ break;
+ attempts++;
+ }
+
+ if (!wio->mDownloadComplete)
+ wio->mDownloadStatus = UPDATE_ERROR;
+
+// wio->mThread = 0;
+ return 0;
+}
+
+void WhoIsOnline::download()
+{
+ mDownloadComplete = true;
+ if (mThread && SDL_GetThreadID(mThread))
+ SDL_WaitThread(mThread, NULL);
+
+ mDownloadComplete = false;
+ mThread = SDL_CreateThread(WhoIsOnline::downloadThread, this);
+
+ if (mThread == NULL)
+ mDownloadStatus = UPDATE_ERROR;
+}
+
+void WhoIsOnline::logic()
+{
+ // Update Scroll logic
+ mScrollArea->logic();
+
+ if (!mAllowUpdate)
+ return;
+
+ if (mUpdateTimer == 0)
+ mUpdateTimer = cur_time;
+
+ double timeDiff = difftime(cur_time, mUpdateTimer);
+ int timeLimit = isVisible() ? 20 : 120;
+
+ if (mUpdateOnlineList && timeDiff >= timeLimit
+ && mDownloadStatus != UPDATE_LIST)
+ {
+ if (mDownloadComplete == true)
+ {
+ setCaption(_("Who Is Online - Updating"));
+ mUpdateTimer = 0;
+ mDownloadStatus = UPDATE_LIST;
+ download();
+ }
+ }
+
+ switch (mDownloadStatus)
+ {
+ case UPDATE_ERROR:
+ mBrowserBox->clearRows();
+ mBrowserBox->addRow("##1Failed to fetch the online list!");
+ mBrowserBox->addRow(mCurlError);
+ mDownloadStatus = UPDATE_COMPLETE;
+ setCaption(_("Who Is Online - error"));
+ mUpdateButton->setEnabled(true);
+ mUpdateTimer = cur_time + 240;
+ break;
+ case UPDATE_LIST:
+ if (mDownloadComplete == true)
+ {
+ loadList();
+ mDownloadStatus = UPDATE_COMPLETE;
+ mUpdateButton->setEnabled(true);
+ mUpdateTimer = 0;
+ updateSize();
+ if (mOnlinePlayers.size() > 0 && chatWindow)
+ chatWindow->updateOnline(mOnlinePlayers);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void WhoIsOnline::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "update")
+ {
+ if (mDownloadStatus == UPDATE_COMPLETE)
+ {
+ mUpdateTimer = cur_time - 20;
+ if (mUpdateButton)
+ mUpdateButton->setEnabled(false);
+ setCaption(_("Who Is Online - Update"));
+ if (mThread && SDL_GetThreadID(mThread))
+ {
+ SDL_WaitThread(mThread, NULL);
+ mThread = NULL;
+ }
+ mDownloadComplete = true;
+ }
+ }
+}
+
+void WhoIsOnline::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+ updateSize();
+}
+
+void WhoIsOnline::updateSize()
+{
+ if (mDownloadStatus == UPDATE_COMPLETE)
+ {
+ const gcn::Rectangle area = getChildrenArea();
+ if (mUpdateButton)
+ mUpdateButton->setWidth(area.width - 10);
+
+ if (mScrollArea)
+ mScrollArea->setSize(area.width - 10, area.height - 10 - 30);
+ }
+}
+
+const std::string WhoIsOnline::prepareNick(std::string nick, int level,
+ std::string color) const
+{
+ if (mShowLevel && level > 1)
+ {
+ return strprintf("@@%s|##%s%s (%d)@@", nick.c_str(),
+ color.c_str(), nick.c_str(), level);
+ }
+ else
+ {
+ return strprintf("@@%s|##%s%s@@", nick.c_str(),
+ color.c_str(), nick.c_str());
+ }
+}
+
+void WhoIsOnline::optionChanged(const std::string &name)
+{
+ if (name == "updateOnlineList")
+ mUpdateOnlineList = config.getBoolValue("updateOnlineList");
+} \ No newline at end of file
diff --git a/src/gui/whoisonline.h b/src/gui/whoisonline.h
new file mode 100644
index 000000000..d6ac177d6
--- /dev/null
+++ b/src/gui/whoisonline.h
@@ -0,0 +1,139 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _WHOISONLINE_H
+#define _WHOISONLINE_H
+
+#include <string>
+#include <set>
+
+#include "configlistener.h"
+
+#include "gui/widgets/linkhandler.h"
+#include "gui/widgets/window.h"
+
+#include "../utils/mutex.h"
+
+#include <guichan/actionlistener.hpp>
+
+class BrowserBox;
+class ScrollArea;
+
+struct SDL_Thread;
+
+/**
+ * Update progress window GUI
+ *
+ * \ingroup GUI
+ */
+class WhoIsOnline : public Window,
+ public LinkHandler,
+ public gcn::ActionListener,
+ public ConfigListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ WhoIsOnline();
+
+ /**
+ * Destructor
+ */
+ ~WhoIsOnline();
+
+ /**
+ * Loads and display online list from the memory buffer.
+ */
+ void loadList();
+
+ void handleLink(const std::string& link, gcn::MouseEvent *event);
+
+ void logic();
+
+ void action(const gcn::ActionEvent &event);
+
+ void widgetResized(const gcn::Event &event);
+
+ std::set<std::string> &getOnlinePlayers()
+ { return mOnlinePlayers; }
+
+ void setAllowUpdate(bool n)
+ { mAllowUpdate = n; }
+
+ void optionChanged(const std::string &name);
+
+private:
+ void download();
+
+ void updateSize();
+
+ /**
+ * The thread function that download the files.
+ */
+ static int downloadThread(void *ptr);
+
+ /**
+ * A libcurl callback for writing to memory.
+ */
+ static size_t memoryWrite(void *ptr, size_t size, size_t nmemb,
+ FILE *stream);
+
+ const std::string prepareNick(std::string nick, int level,
+ std::string color) const;
+ enum DownloadStatus
+ {
+ UPDATE_ERROR = 0,
+ UPDATE_COMPLETE,
+ UPDATE_LIST
+ };
+
+ /** A thread that use libcurl to download updates. */
+ SDL_Thread *mThread;
+
+ /** Status of the current download. */
+ DownloadStatus mDownloadStatus;
+
+ /** Flag that show if current download is complete. */
+ bool mDownloadComplete;
+
+ /** Byte count currently downloaded in mMemoryBuffer. */
+ int mDownloadedBytes;
+
+ /** Buffer for files downloaded to memory. */
+ char *mMemoryBuffer;
+
+ /** Buffer to handler human readable error provided by curl. */
+ char *mCurlError;
+
+ BrowserBox *mBrowserBox;
+ ScrollArea *mScrollArea;
+ time_t mUpdateTimer;
+ std::set<std::string> mOnlinePlayers;
+
+ gcn::Button *mUpdateButton;
+ bool mAllowUpdate;
+ bool mShowLevel;
+ bool mUpdateOnlineList;
+};
+
+#endif
diff --git a/src/gui/widgets/avatarlistbox.cpp b/src/gui/widgets/avatarlistbox.cpp
new file mode 100644
index 000000000..d665c81ce
--- /dev/null
+++ b/src/gui/widgets/avatarlistbox.cpp
@@ -0,0 +1,346 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/avatarlistbox.h"
+
+#include "actorspritemanager.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "guild.h"
+#include "localplayer.h"
+
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/palette.h"
+#include "gui/viewport.h"
+#include "gui/theme.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/stringutils.h"
+
+#include <guichan/font.hpp>
+
+int AvatarListBox::instances = 0;
+Image *AvatarListBox::onlineIcon = 0;
+Image *AvatarListBox::offlineIcon = 0;
+
+AvatarListBox::AvatarListBox(AvatarListModel *model):
+ ListBox(model),
+ mShowGender(false),
+ mShowLevel(false)
+{
+ instances++;
+
+ if (instances == 1)
+ {
+ onlineIcon = Theme::getImageFromTheme("circle-green.png");
+ offlineIcon = Theme::getImageFromTheme("circle-gray.png");
+ }
+
+ setWidth(200);
+
+ mShowGender = config.getBoolValue("showgender");
+ mShowLevel = config.getBoolValue("showlevel");
+
+ config.addListener("showgender", this);
+ config.addListener("showlevel", this);
+}
+
+AvatarListBox::~AvatarListBox()
+{
+ config.removeListener("showgender", this);
+ config.removeListener("showlevel", this);
+
+ instances--;
+
+ if (instances == 0)
+ {
+ if (onlineIcon)
+ onlineIcon->decRef();
+ if (offlineIcon)
+ offlineIcon->decRef();
+ }
+}
+
+void AvatarListBox::draw(gcn::Graphics *gcnGraphics)
+{
+ if (!mListModel || !player_node)
+ return;
+
+ AvatarListModel *model = static_cast<AvatarListModel*>(mListModel);
+// Guild *guild = dynamic_cast<Guild*>(model);
+
+ updateAlpha();
+
+ Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
+
+ graphics->setColor(Theme::getThemeColor(Theme::HIGHLIGHT,
+ static_cast<int>(mAlpha * 255.0f)));
+ graphics->setFont(getFont());
+
+ const int fontHeight = getFont()->getHeight();
+
+ Widget *parent = getParent();
+
+ const std::string name = player_node->getName();
+
+ // Draw the list elements
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ for (int i = 0, y = 0;
+ i < model->getNumberOfElements();
+ ++i, y += fontHeight)
+ {
+ Avatar *a = model->getAvatarAt(i);
+ if (!a)
+ continue;
+
+ // Draw online status
+ Image *icon = a->getOnline() ? onlineIcon : offlineIcon;
+ if (icon)
+ graphics->drawImage(icon, 2, y + 1);
+
+ if (a->getDisplayBold())
+ graphics->setFont(boldFont);
+
+ std::string text;
+
+ if (a->getMaxHp() > 0)
+ {
+ if (mShowLevel && a->getLevel() > 1)
+ {
+ text = strprintf("%s %d/%d (%d)", a->getComplexName().c_str(),
+ a->getHp(), a->getMaxHp(), a->getLevel());
+ }
+ else
+ {
+ text = strprintf("%s %d/%d", a->getComplexName().c_str(),
+ a->getHp(), a->getMaxHp());
+ }
+ if (parent && a->getMaxHp())
+ {
+ gcn::Color color = Theme::getProgressColor(
+ Theme::PROG_HP, static_cast<float>(a->getHp())
+ / static_cast<float>(a->getMaxHp()));
+ color.a = 80;
+ graphics->setColor(color);
+
+ graphics->fillRectangle(gcn::Rectangle(0, y,
+ parent->getWidth() * a->getHp() / a->getMaxHp(),
+ fontHeight));
+ }
+ }
+ else if (a->getDamageHp() != 0 && a->getName() != name)
+ {
+ if (mShowLevel && a->getLevel() > 1)
+ {
+ text = strprintf("%s -%d (%d)", a->getComplexName().c_str(),
+ a->getDamageHp(), a->getLevel());
+ }
+ else
+ {
+ text = strprintf("%s -%d", a->getComplexName().c_str(),
+ a->getDamageHp());
+ }
+
+ if (parent)
+ {
+// int diff;
+// if (a->getDamageHp() > 1024)
+// diff = 0;
+// else
+// diff = 1024 - a->getDamageHp();
+ gcn::Color color = Theme::getProgressColor(Theme::PROG_HP,
+ 1);
+// 0 / 1024);
+/*
+ if (a->getDamageHp() >= 400)
+ {
+ }
+ else
+ {
+// int intens = 1024/(400 - a->getDamageHp());
+ int intens = a->getDamageHp() / 1024;
+ if (intens > 1)
+ intens = 1;
+ color = Theme::getProgressColor(Theme::PROG_HP,
+ intens);
+ }
+*/
+
+ color.a = 80;
+ graphics->setColor(color);
+ graphics->fillRectangle(gcn::Rectangle(0, y,
+ parent->getWidth() * a->getDamageHp() / 1024,
+ fontHeight));
+
+ if (a->getLevel() > 1)
+ {
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ int minHp = 40 + ((a->getLevel() - 1) * 5);
+ if (minHp < 0)
+ minHp = 40;
+
+ graphics->drawLine(parent->getWidth()*minHp / 1024, y,
+ parent->getWidth() * minHp / 1024, y + fontHeight);
+ }
+ }
+ }
+ else
+ {
+ if (mShowLevel && a->getLevel() > 1)
+ {
+ text = strprintf("%s (%d)", a->getComplexName().c_str(),
+ a->getLevel());
+ }
+ else
+ {
+ text = a->getComplexName();
+ }
+ }
+
+ if (!a->getMap().empty())
+ {
+ if (a->getX() != -1)
+ {
+ text += strprintf(" [%d,%d %s]", a->getX(), a->getY(),
+ a->getMap().c_str());
+ }
+ else
+ {
+ text += strprintf(" [%s]", a->getMap().c_str());
+ }
+ }
+
+ if (mShowGender)
+ {
+ switch (a->getGender())
+ {
+ case GENDER_FEMALE:
+ text += strprintf(" \u2640 %s",
+ a->getAdditionString().c_str());
+ break;
+ case GENDER_MALE:
+ text += strprintf(" \u2642 %s",
+ a->getAdditionString().c_str());
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ text += a->getAdditionString();
+ }
+
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+
+ // Draw Name
+ graphics->drawText(text, 15, y);
+
+ if (a->getDisplayBold())
+ graphics->setFont(getFont());
+ }
+
+ setWidth(parent->getWidth() - 10);
+}
+
+void AvatarListBox::mousePressed(gcn::MouseEvent &event)
+{
+ if (!actorSpriteManager || !player_node || !viewport
+ || !getFont()->getHeight())
+ {
+ return;
+ }
+
+ int y = event.getY() / getFont()->getHeight();
+ if (!mListModel || y > mListModel->getNumberOfElements())
+ return;
+
+ setSelected(y);
+ distributeActionEvent();
+ int selected = getSelected();
+ AvatarListModel *model = static_cast<AvatarListModel*>(mListModel);
+ if (!model)
+ return;
+ Avatar *ava = model->getAvatarAt(selected);
+ if (!ava)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (ava->getType() == AVATAR_PLAYER)
+ {
+ Being* being = actorSpriteManager->findBeingByName(ava->getName(),
+ Being::PLAYER);
+ if (being)
+ actorSpriteManager->heal(player_node, being);
+ }
+ else
+ {
+ player_node->navigateTo(ava->getX(), ava->getY());
+ }
+ }
+ else if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ if (ava->getType() == AVATAR_PLAYER)
+ {
+ Being* being = actorSpriteManager->findBeingByName(
+ model->getAvatarAt(selected)->getName(), Being::PLAYER);
+ if (being)
+ {
+ viewport->showPopup(event.getX(), event.getY(), being);
+ }
+ else
+ {
+ viewport->showPlayerPopup(
+ model->getAvatarAt(selected)->getName());
+ }
+ }
+ else
+ {
+ Map *map = viewport->getMap();
+ Avatar *ava = model->getAvatarAt(selected);
+ if (map && ava)
+ {
+ MapItem *mapItem = map->findPortalXY(ava->getX(), ava->getY());
+ viewport->showPopup(mapItem);
+ }
+ }
+ }
+
+ else if (event.getButton() == gcn::MouseEvent::MIDDLE)
+ {
+ if (ava->getType() == AVATAR_PLAYER && chatWindow)
+ {
+ chatWindow->addWhisperTab(model->getAvatarAt(selected)
+ ->getName(), true);
+ }
+ }
+}
+
+void AvatarListBox::optionChanged(const std::string &value)
+{
+ if (value == "showgender")
+ mShowGender = config.getBoolValue("showgender");
+ else if (value == "showlevel")
+ mShowLevel = config.getBoolValue("showlevel");
+} \ No newline at end of file
diff --git a/src/gui/widgets/avatarlistbox.h b/src/gui/widgets/avatarlistbox.h
new file mode 100644
index 000000000..c7bc11f7c
--- /dev/null
+++ b/src/gui/widgets/avatarlistbox.h
@@ -0,0 +1,70 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_GUILDLISTBOX_H
+#define GUI_GUILDLISTBOX_H
+
+#include "avatar.h"
+
+#include "configlistener.h"
+
+#include "gui/widgets/listbox.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class Image;
+
+class AvatarListModel : public gcn::ListModel
+{
+public:
+ virtual Avatar *getAvatarAt(int i) = 0;
+
+ std::string getElementAt(int i)
+ { return getAvatarAt(i)->getName(); }
+};
+
+class AvatarListBox : public ListBox, public ConfigListener
+{
+public:
+ AvatarListBox(AvatarListModel *model);
+
+ ~AvatarListBox();
+
+ /**
+ * Draws the list box.
+ */
+ void draw(gcn::Graphics *gcnGraphics);
+
+ void mousePressed(gcn::MouseEvent &event);
+
+ void optionChanged(const std::string &value);
+
+private:
+ bool mShowGender;
+ bool mShowLevel;
+
+ static int instances;
+ static Image *onlineIcon;
+ static Image *offlineIcon;
+};
+
+#endif
diff --git a/src/gui/widgets/battletab.cpp b/src/gui/widgets/battletab.cpp
new file mode 100644
index 000000000..68f1a0453
--- /dev/null
+++ b/src/gui/widgets/battletab.cpp
@@ -0,0 +1,54 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/battletab.h"
+
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/theme.h"
+
+#include "net/net.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+BattleTab::BattleTab() :
+ ChatTab(_("Battle"))
+{
+ loadFromLogFile("#Battle");
+}
+
+BattleTab::~BattleTab()
+{
+}
+
+void BattleTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log(std::string("#Battle"), std::string(msg));
+}
diff --git a/src/gui/widgets/battletab.h b/src/gui/widgets/battletab.h
new file mode 100644
index 000000000..fdfe626f0
--- /dev/null
+++ b/src/gui/widgets/battletab.h
@@ -0,0 +1,47 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BATTLETAB_H
+#define BATTLETAB_H
+
+#include "gui/widgets/chattab.h"
+
+/**
+ * A tab for a party chat channel.
+ */
+class BattleTab : public ChatTab
+{
+ public:
+ BattleTab();
+
+ ~BattleTab();
+
+ int getType() const
+ { return ChatTab::TAB_BATTLE; }
+
+ void saveToLogFile(std::string &msg);
+};
+
+extern BattleTab *battleChatTab;
+#endif
+
+
+
diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp
new file mode 100644
index 000000000..acb182c3c
--- /dev/null
+++ b/src/gui/widgets/browserbox.cpp
@@ -0,0 +1,534 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/browserbox.h"
+
+#include "client.h"
+#include "log.h"
+
+#include "utils/stringutils.h"
+
+#include "gui/palette.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/linkhandler.h"
+
+#include <guichan/graphics.hpp>
+#include <guichan/font.hpp>
+#include <guichan/cliprectangle.hpp>
+
+#include <algorithm>
+
+BrowserBox::BrowserBox(unsigned int mode, bool opaque):
+ gcn::Widget(),
+ mMode(mode), mHighMode(UNDERLINE | BACKGROUND),
+ mOpaque(opaque),
+ mUseLinksAndUserColors(true),
+ mSelectedLink(-1),
+ mMaxRows(0),
+ mHeight(0),
+ mWidth(0),
+ mYStart(0),
+ mUpdateTime(-1),
+ mAlwaysUpdate(true)
+{
+ setFocusable(true);
+ addMouseListener(this);
+}
+
+BrowserBox::~BrowserBox()
+{
+}
+
+void BrowserBox::setLinkHandler(LinkHandler* linkHandler)
+{
+ mLinkHandler = linkHandler;
+}
+
+void BrowserBox::setOpaque(bool opaque)
+{
+ mOpaque = opaque;
+}
+
+void BrowserBox::setHighlightMode(unsigned int highMode)
+{
+ mHighMode = highMode;
+}
+
+void BrowserBox::addRow(const std::string &row, bool atTop)
+{
+ std::string tmp = row;
+ std::string newRow;
+ std::string::size_type idx1, idx2, idx3;
+ gcn::Font *font = getFont();
+
+ // Use links and user defined colors
+ if (mUseLinksAndUserColors)
+ {
+ BROWSER_LINK bLink;
+
+ // Check for links in format "@@link|Caption@@"
+ idx1 = tmp.find("@@");
+ while (idx1 != std::string::npos)
+ {
+ idx2 = tmp.find("|", idx1);
+ idx3 = tmp.find("@@", idx2);
+
+ if (idx2 == std::string::npos || idx3 == std::string::npos)
+ break;
+ bLink.link = tmp.substr(idx1 + 2, idx2 - (idx1 + 2));
+ bLink.caption = tmp.substr(idx2 + 1, idx3 - (idx2 + 1));
+ bLink.y1 = static_cast<int>(mTextRows.size()) * font->getHeight();
+ bLink.y2 = bLink.y1 + font->getHeight();
+
+ newRow += tmp.substr(0, idx1);
+
+ std::string tmp2 = newRow;
+ idx1 = tmp2.find("##");
+ while (idx1 != std::string::npos)
+ {
+ tmp2.erase(idx1, 3);
+ idx1 = tmp2.find("##");
+ }
+ bLink.x1 = font->getWidth(tmp2) - 1;
+ bLink.x2 = bLink.x1 + font->getWidth(bLink.caption) + 1;
+
+ mLinks.push_back(bLink);
+
+ newRow += "##<" + bLink.caption;
+
+ tmp.erase(0, idx3 + 2);
+ if (!tmp.empty())
+ newRow += "##>";
+
+ idx1 = tmp.find("@@");
+ }
+
+ newRow += tmp;
+ }
+ // Don't use links and user defined colors
+ else
+ {
+ newRow = row;
+ }
+
+ if (atTop)
+ mTextRows.push_front(newRow);
+ else
+ mTextRows.push_back(newRow);
+
+ //discard older rows when a row limit has been set
+ if (mMaxRows > 0)
+ {
+ while (mTextRows.size() > mMaxRows)
+ {
+ mTextRows.pop_front();
+ for (unsigned int i = 0; i < mLinks.size(); i++)
+ {
+ mLinks[i].y1 -= font->getHeight();
+ mLinks[i].y2 -= font->getHeight();
+
+ if (mLinks[i].y1 < 0)
+ mLinks.erase(mLinks.begin() + i);
+ }
+ }
+ }
+
+ // Auto size mode
+ if (mMode == AUTO_SIZE)
+ {
+ std::string plain = newRow;
+ for (idx1 = plain.find("##");
+ idx1 != std::string::npos;
+ idx1 = plain.find("##"))
+ {
+ plain.erase(idx1, 3);
+ }
+
+ // Adjust the BrowserBox size
+ int w = font->getWidth(plain);
+ if (w > getWidth())
+ setWidth(w);
+ }
+
+ if (mMode == AUTO_WRAP)
+ {
+ unsigned int y = 0;
+ unsigned int nextChar;
+ const char *hyphen = "~";
+ int hyphenWidth = font->getWidth(hyphen);
+ int x = 0;
+
+ for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++)
+ {
+ std::string row = *i;
+ for (unsigned int j = 0; j < row.size(); j++)
+ {
+ std::string character = row.substr(j, 1);
+ x += font->getWidth(character);
+ nextChar = j + 1;
+
+ // Wraping between words (at blank spaces)
+ if ((nextChar < row.size()) && (row.at(nextChar) == ' '))
+ {
+ int nextSpacePos = static_cast<int>(
+ row.find(" ", (nextChar + 1)));
+ if (nextSpacePos <= 0)
+ nextSpacePos = static_cast<int>(row.size()) - 1;
+
+ int nextWordWidth = font->getWidth(
+ row.substr(nextChar,
+ (nextSpacePos - nextChar)));
+
+ if ((x + nextWordWidth + 10) > getWidth())
+ {
+ x = 15; // Ident in new line
+ y += 1;
+ j++;
+ }
+ }
+ // Wrapping looong lines (brutal force)
+ else if ((x + 2 * hyphenWidth) > getWidth())
+ {
+ x = 15; // Ident in new line
+ y += 1;
+ }
+ }
+ }
+
+ setHeight(font->getHeight() * (static_cast<int>(
+ mTextRows.size()) + y));
+ }
+ else
+ {
+ setHeight(font->getHeight() * static_cast<int>(mTextRows.size()));
+ }
+ mUpdateTime = 0;
+ updateHeight();
+}
+
+void BrowserBox::clearRows()
+{
+ mTextRows.clear();
+ mLinks.clear();
+ setWidth(0);
+ setHeight(0);
+ mSelectedLink = -1;
+ mUpdateTime = 0;
+ updateHeight();
+}
+
+struct MouseOverLink
+{
+ MouseOverLink(int x, int y) : mX(x), mY(y)
+ { }
+
+ bool operator() (BROWSER_LINK &link)
+ {
+ return (mX >= link.x1 && mX < link.x2 &&
+ mY >= link.y1 && mY < link.y2);
+ }
+ int mX, mY;
+};
+
+void BrowserBox::mousePressed(gcn::MouseEvent &event)
+{
+ if (!mLinkHandler)
+ return;
+
+ LinkIterator i = find_if(mLinks.begin(), mLinks.end(),
+ MouseOverLink(event.getX(), event.getY()));
+
+ if (i != mLinks.end())
+ mLinkHandler->handleLink(i->link, &event);
+}
+
+void BrowserBox::mouseMoved(gcn::MouseEvent &event)
+{
+ LinkIterator i = find_if(mLinks.begin(), mLinks.end(),
+ MouseOverLink(event.getX(), event.getY()));
+
+ mSelectedLink = (i != mLinks.end())
+ ? static_cast<int>(i - mLinks.begin()) : -1;
+}
+
+void BrowserBox::draw(gcn::Graphics *graphics)
+{
+ gcn::ClipRectangle cr = graphics->getCurrentClipArea();
+ mYStart = cr.y - cr.yOffset;
+ int yEnd = mYStart + cr.height;
+ if (mYStart < 0)
+ mYStart = 0;
+
+ if (getWidth() != mWidth)
+ updateHeight();
+
+ if (mOpaque)
+ {
+ graphics->setColor(Theme::getThemeColor(Theme::BACKGROUND));
+ graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
+ if (mSelectedLink >= 0 && mSelectedLink < (signed)mLinks.size())
+ {
+ if ((mHighMode & BACKGROUND))
+ {
+ graphics->setColor(Theme::getThemeColor(Theme::HIGHLIGHT));
+ graphics->fillRectangle(gcn::Rectangle(
+ mLinks[mSelectedLink].x1,
+ mLinks[mSelectedLink].y1,
+ mLinks[mSelectedLink].x2 - mLinks[mSelectedLink].x1,
+ mLinks[mSelectedLink].y2 - mLinks[mSelectedLink].y1
+ ));
+ }
+
+ if ((mHighMode & UNDERLINE))
+ {
+ graphics->setColor(Theme::getThemeColor(Theme::HYPERLINK));
+ graphics->drawLine(
+ mLinks[mSelectedLink].x1,
+ mLinks[mSelectedLink].y2,
+ mLinks[mSelectedLink].x2,
+ mLinks[mSelectedLink].y2);
+ }
+ }
+
+ gcn::Font *font = getFont();
+
+ for (LinePartIterator i = mLineParts.begin();
+ i != mLineParts.end();
+ i ++)
+ {
+ const LinePart &part = *i;
+ if (part.mY + 50 < mYStart)
+ continue;
+ if (part.mY > yEnd)
+ break;
+ graphics->setColor(part.mColor);
+ font->drawString(graphics, part.mText, part.mX, part.mY);
+ }
+
+ return;
+}
+
+int BrowserBox::calcHeight()
+{
+ int x = 0, y = 0;
+ int wrappedLines = 0;
+ int link = 0;
+ gcn::Font *font = getFont();
+
+ int fontHeight = font->getHeight();
+ int fontWidthMinus = font->getWidth("-");
+ char const *hyphen = "~";
+ int hyphenWidth = font->getWidth(hyphen);
+
+ gcn::Color selColor = Theme::getThemeColor(Theme::TEXT);
+ const gcn::Color textColor = Theme::getThemeColor(Theme::TEXT);
+
+ mLineParts.clear();
+
+ for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++)
+ {
+ const std::string row = *(i);
+ bool wrapped = false;
+ x = 0;
+
+ // Check for separator lines
+ if (row.find("---", 0) == 0)
+ {
+ const int dashWidth = fontWidthMinus;
+ for (x = 0; x < getWidth(); x++)
+ {
+ mLineParts.push_back(LinePart(x, y, selColor, "-"));
+ x += dashWidth - 2;
+ }
+
+ y += fontHeight;
+ continue;
+ }
+
+ gcn::Color prevColor = selColor;
+
+ // TODO: Check if we must take texture size limits into account here
+ // TODO: Check if some of the O(n) calls can be removed
+ for (std::string::size_type start = 0, end = std::string::npos;
+ start != std::string::npos;
+ start = end, end = std::string::npos)
+ {
+ // Wrapped line continuation shall be indented
+ if (wrapped)
+ {
+ y += fontHeight;
+ x = 15;
+ wrapped = false;
+ }
+
+ // "Tokenize" the string at control sequences
+ if (mUseLinksAndUserColors)
+ end = row.find("##", start + 1);
+
+ if (mUseLinksAndUserColors ||
+ (!mUseLinksAndUserColors && (start == 0)))
+ {
+ // Check for color change in format "##x", x = [L,P,0..9]
+ if (row.find("##", start) == start && row.size() > start + 2)
+ {
+ const char c = row.at(start + 2);
+
+ bool valid;
+ const gcn::Color col = Theme::getThemeColor(c, valid);
+
+ if (c == '>')
+ {
+ selColor = prevColor;
+ }
+ else if (c == '<')
+ {
+// link++;
+ prevColor = selColor;
+ selColor = col;
+ }
+ else if (valid)
+ {
+ selColor = col;
+ }
+ else
+ {
+
+ switch (c)
+ {
+ case '1': selColor = RED; break;
+ case '2': selColor = GREEN; break;
+ case '3': selColor = BLUE; break;
+ case '4': selColor = ORANGE; break;
+ case '5': selColor = YELLOW; break;
+ case '6': selColor = PINK; break;
+ case '7': selColor = PURPLE; break;
+ case '8': selColor = GRAY; break;
+ case '9': selColor = BROWN; break;
+ case '0':
+ default:
+ selColor = textColor;
+ }
+ }
+
+ if (c == '<' && link < (signed)mLinks.size())
+ {
+ const int size =
+ font->getWidth(mLinks[link].caption) + 1;
+
+ mLinks[link].x1 = x;
+ mLinks[link].y1 = y;
+ mLinks[link].x2 = mLinks[link].x1 + size;
+ mLinks[link].y2 = y + fontHeight - 1;
+ link++;
+ }
+ start += 3;
+
+ if (start == row.size())
+ break;
+ }
+ }
+
+ std::string::size_type len =
+ end == std::string::npos ? end : end - start;
+
+ if (start >= row.length())
+ break;
+
+ std::string part = row.substr(start, len);
+
+ // Auto wrap mode
+ if (mMode == AUTO_WRAP && getWidth() > 0
+ && font->getWidth(part) > 0
+ && (x + font->getWidth(part) + 10) > getWidth())
+ {
+ bool forced = false;
+
+ /* FIXME: This code layout makes it easy to crash remote
+ clients by talking garbage. Forged long utf-8 characters
+ will cause either a buffer underflow in substr or an
+ infinite loop in the main loop. */
+ do
+ {
+ if (!forced)
+ end = row.rfind(' ', end);
+
+ // Check if we have to (stupidly) force-wrap
+ if (end == std::string::npos || end <= start)
+ {
+ forced = true;
+ end = row.size();
+ x += hyphenWidth; // Account for the wrap-notifier
+ continue;
+ }
+
+ // Skip to the start of the current character
+ while ((row[end] & 192) == 128)
+ end--;
+ end--; // And then to the last byte of the previous one
+
+ part = row.substr(start, end - start + 1);
+ }
+ while (end > start && font->getWidth(part) > 0
+ && (x + font->getWidth(part) + 10) > getWidth());
+
+ if (forced)
+ {
+ x -= hyphenWidth; // Remove the wrap-notifier accounting
+ mLineParts.push_back(LinePart(getWidth() - hyphenWidth,
+ y, selColor, hyphen));
+ end++; // Skip to the next character
+ }
+ else
+ {
+ end += 2; // Skip to after the space
+ }
+
+ wrapped = true;
+ wrappedLines++;
+ }
+
+ mLineParts.push_back(LinePart(x, y, selColor, part.c_str()));
+
+ if (mMode == AUTO_WRAP && font->getWidth(part) == 0)
+ break;
+
+ x += font->getWidth(part);
+ }
+ y += fontHeight;
+ }
+ return (static_cast<int>(mTextRows.size()) + wrappedLines) * fontHeight;
+}
+
+void BrowserBox::updateHeight()
+{
+ if (mAlwaysUpdate || mUpdateTime != cur_time
+ || mTextRows.size() < 3 || !mUpdateTime)
+ {
+ mWidth = getWidth();
+ mHeight = calcHeight();
+ setHeight(mHeight);
+ mUpdateTime = cur_time;
+ }
+}
diff --git a/src/gui/widgets/browserbox.h b/src/gui/widgets/browserbox.h
new file mode 100644
index 000000000..cd9cc92de
--- /dev/null
+++ b/src/gui/widgets/browserbox.h
@@ -0,0 +1,205 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BROWSERBOX_H
+#define BROWSERBOX_H
+
+#include <guichan/mouselistener.hpp>
+#include <guichan/widget.hpp>
+
+#include <list>
+#include <vector>
+
+class LinkHandler;
+
+struct BROWSER_LINK
+{
+ int x1, x2, y1, y2; /**< Where link is placed */
+ std::string link;
+ std::string caption;
+};
+
+class LinePart
+{
+ public:
+ LinePart(int x, int y, gcn::Color color, std::string text) :
+ mX(x), mY(y), mColor(color), mText(text)
+ {
+ }
+
+ int mX, mY;
+ gcn::Color mColor;
+ std::string mText;
+};
+
+/**
+ * A simple browser box able to handle links and forward events to the
+ * parent conteiner.
+ */
+class BrowserBox : public gcn::Widget,
+ public gcn::MouseListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ BrowserBox(unsigned int mode = AUTO_SIZE, bool opaque = true);
+
+ /**
+ * Destructor.
+ */
+ ~BrowserBox();
+
+ /**
+ * Sets the handler for links.
+ */
+ void setLinkHandler(LinkHandler *linkHandler);
+
+ /**
+ * Sets the BrowserBox opacity.
+ */
+ void setOpaque(bool opaque);
+
+ /**
+ * Sets the Highlight mode for links.
+ */
+ void setHighlightMode(unsigned int highMode);
+
+ /**
+ * Sets the maximum numbers of rows in the browser box. 0 = no limit.
+ */
+ void setMaxRow(unsigned max) {mMaxRows = max; };
+
+ /**
+ * Disable links & user defined colors to be used in chat input.
+ */
+/*
+ void disableLinksAndUserColors();
+*/
+ /**
+ * Adds a text row to the browser.
+ */
+ void addRow(const std::string &row, bool atTop = false);
+
+ /**
+ * Remove all rows.
+ */
+ void clearRows();
+
+// void setSize(int width, int height);
+
+// void widgetResized(const gcn::Event &event);
+
+ /**
+ * Handles mouse actions.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+ void mouseMoved(gcn::MouseEvent &event);
+
+ /**
+ * Draws the browser box.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ void updateHeight();
+
+// void widgetResized(const gcn::Event &event);
+
+ /**
+ * BrowserBox modes.
+ */
+ enum
+ {
+ AUTO_SIZE = 0,
+ AUTO_WRAP /**< Maybe it needs a fix or to be redone. */
+ };
+
+ /**
+ * BrowserBox colors.
+ *
+ * NOTES (by Javila):
+ * - color values is "0x" prefix followed by HTML color style.
+ * - we can add up to 10 different colors: [0..9].
+ * - not all colors will be fine with all backgrounds due transparent
+ * windows and widgets. So, I think it's better keep BrowserBox
+ * opaque (white background) by default.
+ */
+ enum
+ {
+ RED = 0xff0000, /**< Color 1 */
+ GREEN = 0x009000, /**< Color 2 */
+ BLUE = 0x0000ff, /**< Color 3 */
+ ORANGE = 0xe0980e, /**< Color 4 */
+ YELLOW = 0xf1dc27, /**< Color 5 */
+ PINK = 0xff00d8, /**< Color 6 */
+ PURPLE = 0x8415e2, /**< Color 7 */
+ GRAY = 0x919191, /**< Color 8 */
+ BROWN = 0x8e4c17 /**< Color 9 */
+ };
+
+ /**
+ * Highlight modes for links.
+ * This can be used for a bitmask.
+ */
+ enum
+ {
+ UNDERLINE = 1,
+ BACKGROUND = 2
+ };
+
+ typedef std::list<std::string> TextRows;
+
+ TextRows &getRows()
+ { return mTextRows; }
+
+ void setAlwaysUpdate(bool n)
+ { mAlwaysUpdate = n; }
+
+ private:
+ int calcHeight();
+
+ typedef TextRows::iterator TextRowIterator;
+ TextRows mTextRows;
+
+ typedef std::list<LinePart> LinePartList;
+ typedef LinePartList::iterator LinePartIterator;
+ LinePartList mLineParts;
+
+ typedef std::vector<BROWSER_LINK> Links;
+ typedef Links::iterator LinkIterator;
+ Links mLinks;
+
+ LinkHandler *mLinkHandler;
+ unsigned int mMode;
+ unsigned int mHighMode;
+ bool mOpaque;
+ bool mUseLinksAndUserColors;
+ int mSelectedLink;
+ unsigned int mMaxRows;
+ int mHeight;
+ int mWidth;
+ int mYStart;
+ int mUpdateTime;
+ bool mAlwaysUpdate;
+};
+
+#endif
diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp
new file mode 100644
index 000000000..3445928a1
--- /dev/null
+++ b/src/gui/widgets/button.cpp
@@ -0,0 +1,227 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/button.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+
+#include "gui/palette.h"
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+#include <guichan/exception.hpp>
+#include <guichan/font.hpp>
+
+int Button::mInstances = 0;
+float Button::mAlpha = 1.0;
+
+enum
+{
+ BUTTON_STANDARD = 0, // 0
+ BUTTON_HIGHLIGHTED, // 1
+ BUTTON_PRESSED, // 2
+ BUTTON_DISABLED, // 3
+ BUTTON_COUNT // 4 - Must be last.
+};
+
+struct ButtonData
+{
+ char const *file;
+ int gridX;
+ int gridY;
+};
+
+static ButtonData const data[BUTTON_COUNT] =
+{
+ { "button.png", 0, 0 },
+ { "buttonhi.png", 9, 4 },
+ { "buttonpress.png", 16, 19 },
+ { "button_disabled.png", 25, 23 }
+};
+
+ImageRect Button::button[BUTTON_COUNT];
+
+Button::Button():
+ mDescription(""), mClickCount(0)
+{
+ init();
+}
+
+Button::Button(const std::string &caption, const std::string &actionEventId,
+ gcn::ActionListener *listener):
+ gcn::Button(caption),
+ mDescription(""), mClickCount(0)
+{
+ init();
+ setActionEventId(actionEventId);
+
+ if (listener)
+ addActionListener(listener);
+}
+
+void Button::init()
+{
+ setFrameSize(0);
+
+ if (mInstances == 0)
+ {
+ // Load the skin
+ Image *btn[BUTTON_COUNT];
+
+ int a, x, y, mode;
+
+ for (mode = 0; mode < BUTTON_COUNT; mode++)
+ {
+ btn[mode] = Theme::getImageFromTheme(data[mode].file);
+ if (!btn[mode])
+ continue;
+
+ a = 0;
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ button[mode].grid[a] = btn[mode]->getSubImage(
+ data[x].gridX, data[y].gridY,
+ data[x + 1].gridX - data[x].gridX + 1,
+ data[y + 1].gridY - data[y].gridY + 1);
+ a++;
+ }
+ }
+ if (btn[mode])
+ btn[mode]->decRef();
+ }
+ updateAlpha();
+ }
+ mInstances++;
+}
+
+Button::~Button()
+{
+ mInstances--;
+
+ if (mInstances == 0)
+ {
+ for (int mode = 0; mode < BUTTON_COUNT; mode++)
+ {
+ if (button[mode].grid)
+ {
+ for_each(button[mode].grid,
+ button[mode].grid + 9, dtor<Image*>());
+ }
+ }
+ }
+}
+
+void Button::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (mAlpha != alpha)
+ {
+ mAlpha = alpha;
+ for (int a = 0; a < 9; a++)
+ {
+ if (button[BUTTON_DISABLED].grid[a])
+ button[BUTTON_DISABLED].grid[a]->setAlpha(mAlpha);
+ if (button[BUTTON_PRESSED].grid[a])
+ button[BUTTON_PRESSED].grid[a]->setAlpha(mAlpha);
+ if (button[BUTTON_HIGHLIGHTED].grid[a])
+ button[BUTTON_HIGHLIGHTED].grid[a]->setAlpha(mAlpha);
+ if (button[BUTTON_STANDARD].grid[a])
+ button[BUTTON_STANDARD].grid[a]->setAlpha(mAlpha);
+ }
+ }
+}
+
+void Button::draw(gcn::Graphics *graphics)
+{
+ int mode;
+
+ if (!isEnabled())
+ mode = BUTTON_DISABLED;
+ else if (isPressed())
+ mode = BUTTON_PRESSED;
+ else if (mHasMouse || isFocused())
+ mode = BUTTON_HIGHLIGHTED;
+ else
+ mode = BUTTON_STANDARD;
+
+ updateAlpha();
+
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(0, 0, getWidth(), getHeight(), button[mode]);
+
+ if (mode == BUTTON_DISABLED)
+ graphics->setColor(Theme::getThemeColor(Theme::BUTTON_DISABLED));
+ else
+ graphics->setColor(Theme::getThemeColor(Theme::BUTTON));
+
+ int textX;
+ int textY = getHeight() / 2 - getFont()->getHeight() / 2;
+
+ switch (getAlignment())
+ {
+ default:
+ case gcn::Graphics::LEFT:
+ textX = 4;
+ break;
+ case gcn::Graphics::CENTER:
+ textX = getWidth() / 2;
+ break;
+ case gcn::Graphics::RIGHT:
+ textX = getWidth() - 4;
+ break;
+// throw GCN_EXCEPTION("Button::draw. Unknown alignment.");
+ }
+
+ graphics->setFont(getFont());
+
+ if (isPressed())
+ graphics->drawText(getCaption(), textX + 1, textY + 1, getAlignment());
+ else
+ graphics->drawText(getCaption(), textX, textY, getAlignment());
+}
+
+void Button::mouseReleased(gcn::MouseEvent& mouseEvent)
+{
+ if (mouseEvent.getButton() == gcn::MouseEvent::LEFT
+ && mMousePressed && mHasMouse)
+ {
+ mMousePressed = false;
+ mClickCount = mouseEvent.getClickCount();
+ distributeActionEvent();
+ mouseEvent.consume();
+ }
+ else if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
+ {
+ mMousePressed = false;
+ mClickCount = 0;
+ mouseEvent.consume();
+ }
+}
diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h
new file mode 100644
index 000000000..301d02fbe
--- /dev/null
+++ b/src/gui/widgets/button.h
@@ -0,0 +1,94 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BUTTON_H
+#define BUTTON_H
+
+#include <guichan/widgets/button.hpp>
+#include <guichan/mouseevent.hpp>
+
+class ImageRect;
+
+/**
+ * Button widget. Same as the Guichan button but with custom look.
+ *
+ * \ingroup GUI
+ */
+class Button : public gcn::Button
+{
+ public:
+ /**
+ * Default constructor.
+ */
+ Button();
+
+ /**
+ * Constructor, sets the caption of the button to the given string and
+ * adds the given action listener.
+ */
+ Button(const std::string &caption, const std::string &actionEventId,
+ gcn::ActionListener *listener);
+
+ /**
+ * Destructor.
+ */
+ ~Button();
+
+ /**
+ * Draws the button.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Update the alpha value to the button components.
+ */
+ void updateAlpha();
+
+ virtual void mouseReleased(gcn::MouseEvent& mouseEvent);
+
+ void setDescription(std::string text)
+ { mDescription = text; }
+
+ std::string getDescription()
+ { return mDescription; }
+
+ unsigned getClickCount()
+ { return mClickCount; }
+
+ void setTag(int tag)
+ { mTag = tag; }
+
+ int getTag()
+ { return mTag; }
+
+ private:
+ void init();
+
+ static ImageRect button[4]; /**< Button state graphics */
+ static int mInstances; /**< Number of button instances */
+ static float mAlpha;
+
+ std::string mDescription;
+ unsigned mClickCount;
+ int mTag;
+};
+
+#endif
diff --git a/src/gui/widgets/channeltab.cpp b/src/gui/widgets/channeltab.cpp
new file mode 100644
index 000000000..a7370a4c5
--- /dev/null
+++ b/src/gui/widgets/channeltab.cpp
@@ -0,0 +1,132 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "channeltab.h"
+
+#include "channel.h"
+
+#include "net/chathandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+
+ChannelTab::ChannelTab(Channel *channel) :
+ ChatTab(channel->getName()),
+ mChannel(channel)
+{
+ channel->setTab(this);
+}
+
+ChannelTab::~ChannelTab()
+{
+}
+
+void ChannelTab::handleInput(const std::string &msg)
+{
+ Net::getChatHandler()->sendToChannel(getChannel()->getId(), msg);
+}
+
+void ChannelTab::showHelp()
+{
+ chatLog(_("/users > Lists the users in the current channel"));
+ chatLog(_("/topic > Set the topic of the current channel"));
+ chatLog(_("/quit > Leave a channel"));
+ chatLog(_("/op > Make a user a channel operator"));
+ chatLog(_("/kick > Kick a user from the channel"));
+}
+
+bool ChannelTab::handleCommand(const std::string &type,
+ const std::string &args)
+{
+ if (type == "help")
+ {
+ if (args == "users")
+ {
+ chatLog(_("Command: /users"));
+ chatLog(_("This command shows the users in this channel."));
+ }
+ else if (args == "topic")
+ {
+ chatLog(_("Command: /topic <message>"));
+ chatLog(_("This command sets the topic to <message>."));
+ }
+ else if (args == "quit")
+ {
+ chatLog(_("Command: /quit"));
+ chatLog(_("This command leaves the current channel."));
+ chatLog(_("If you're the last person in the channel, "
+ "it will be deleted."));
+ }
+ else if (args == "op")
+ {
+ chatLog(_("Command: /op <nick>"));
+ chatLog(_("This command makes <nick> a channel operator."));
+ chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ chatLog(_("Channel operators can kick and op other users "
+ "from the channel."));
+ }
+ else if (args == "kick")
+ {
+ chatLog(_("Command: /kick <nick>"));
+ chatLog(_("This command makes <nick> leave the channel."));
+ chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ }
+ else
+ return false;
+ }
+ else if (type == "users")
+ {
+ Net::getChatHandler()->userList(mChannel->getName());
+ }
+ else if (type == "topic")
+ {
+ Net::getChatHandler()->setChannelTopic(mChannel->getId(), args);
+ }
+ else if (type == "topic")
+ {
+ Net::getChatHandler()->setChannelTopic(mChannel->getId(), args);
+ }
+ else if (type == "quit")
+ {
+ Net::getChatHandler()->quitChannel(mChannel->getId());
+ }
+ else if (type == "op")
+ {
+ // set the user mode 'o' to op a user
+ if (args != "")
+ Net::getChatHandler()->setUserMode(mChannel->getId(), args, 'o');
+ else
+ chatLog(_("Need a user to op!"), BY_CHANNEL);
+ }
+ else if (type == "kick")
+ {
+ if (args != "")
+ Net::getChatHandler()->kickUser(mChannel->getId(), args);
+ else
+ chatLog(_("Need a user to kick!"), BY_CHANNEL);
+ }
+ else
+ return false;
+
+ return true;
+}
diff --git a/src/gui/widgets/channeltab.h b/src/gui/widgets/channeltab.h
new file mode 100644
index 000000000..842b80f7d
--- /dev/null
+++ b/src/gui/widgets/channeltab.h
@@ -0,0 +1,62 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHANNELTAB_H
+#define CHANNELTAB_H
+
+#include "chattab.h"
+
+class Channel;
+
+/**
+ * A tab for a chat channel.
+ */
+class ChannelTab : public ChatTab
+{
+ public:
+
+ Channel *getChannel() const { return mChannel; }
+
+ void showHelp();
+
+ bool handleCommand(const std::string &type,
+ const std::string &args);
+
+ protected:
+ friend class Channel;
+
+ /**
+ * Constructor.
+ */
+ ChannelTab(Channel *channel);
+
+ /**
+ * Destructor.
+ */
+ ~ChannelTab();
+
+ void handleInput(const std::string &msg);
+
+ private:
+ Channel *mChannel;
+};
+
+#endif // CHANNELTAB_H
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
new file mode 100644
index 000000000..06ba3d3ed
--- /dev/null
+++ b/src/gui/widgets/chattab.cpp
@@ -0,0 +1,431 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/chattab.h"
+
+#include "actorspritemanager.h"
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "configuration.h"
+#include "localplayer.h"
+#include "log.h"
+#include "sound.h"
+
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/itemlinkhandler.h"
+#include "gui/widgets/tradetab.h"
+
+#include "net/chathandler.h"
+#include "net/net.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <guichan/widgets/tabbedarea.hpp>
+
+#define MAX_WORD_SIZE 50
+
+ChatTab::ChatTab(const std::string &name) :
+ Tab(),
+ mAllowHightlight(true)
+{
+ setCaption(name);
+
+ mTextOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
+ mTextOutput->setOpaque(false);
+ mTextOutput->setMaxRow((int) config.getIntValue("ChatLogLength"));
+ if (chatWindow)
+ mTextOutput->setLinkHandler(chatWindow->mItemLinkHandler);
+ mTextOutput->setAlwaysUpdate(false);
+
+ mScrollArea = new ScrollArea(mTextOutput);
+ mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
+ gcn::ScrollArea::SHOW_ALWAYS);
+ mScrollArea->setScrollAmount(0, 1);
+ mScrollArea->setOpaque(false);
+
+ if (chatWindow)
+ chatWindow->addTab(this);
+}
+
+ChatTab::~ChatTab()
+{
+ if (chatWindow)
+ chatWindow->removeTab(this);
+
+ delete mTextOutput;
+ mTextOutput = 0;
+ delete mScrollArea;
+ mScrollArea = 0;
+}
+
+void ChatTab::chatLog(std::string line, Own own,
+ bool ignoreRecord, bool tryRemoveColors)
+{
+ // Trim whitespace
+ trim(line);
+
+ if (line.empty())
+ return;
+
+ if (tryRemoveColors && own == BY_OTHER &&
+ config.getBoolValue("removeColors"))
+ {
+ line = removeColors(line);
+ if (line.empty())
+ return;
+ }
+
+ unsigned lineLim = config.getIntValue("chatMaxCharLimit");
+ if (lineLim > 0 && line.length() > lineLim)
+ line = line.substr(0, lineLim);
+
+ if (line.empty())
+ return;
+
+ CHATLOG tmp;
+ tmp.own = own;
+ tmp.nick = "";
+ tmp.text = line;
+
+ std::string::size_type pos = line.find(" : ");
+ if (pos != std::string::npos)
+ {
+ if (line.length() <= pos + 3)
+ return;
+
+ tmp.nick = line.substr(0, pos);
+ tmp.text = line.substr(pos + 3);
+ }
+ else
+ {
+ // Fix the owner of welcome message.
+ if (line.length() > 7 && line.substr(0, 7) == "Welcome")
+ own = BY_SERVER;
+ }
+
+ // *implements actions in a backwards compatible way*
+ if ((own == BY_PLAYER || own == BY_OTHER) &&
+ tmp.text.at(0) == '*' &&
+ tmp.text.at(tmp.text.length()-1) == '*')
+ {
+ tmp.text[0] = ' ';
+ tmp.text.erase(tmp.text.length() - 1);
+ own = ACT_IS;
+ }
+
+ std::string lineColor = "##C";
+ switch (own)
+ {
+ case BY_GM:
+ if (tmp.nick.empty())
+ {
+ tmp.nick = std::string(_("Global announcement:"));
+ tmp.nick += " ";
+ lineColor = "##G";
+ }
+ else
+ {
+ tmp.nick = strprintf(_("Global announcement from %s:"),
+ tmp.nick.c_str());
+ tmp.nick += " ";
+ lineColor = "##1"; // Equiv. to BrowserBox::RED
+ }
+ break;
+ case BY_PLAYER:
+ tmp.nick += ": ";
+ lineColor = "##Y";
+ break;
+ case BY_OTHER:
+ tmp.nick += ": ";
+ lineColor = "##C";
+ break;
+ case BY_SERVER:
+ tmp.nick = _("Server:");
+ tmp.nick += " ";
+ tmp.text = line;
+ lineColor = "##S";
+ break;
+ case BY_CHANNEL:
+ tmp.nick = "";
+ // TODO: Use a predefined color
+ lineColor = "##2"; // Equiv. to BrowserBox::GREEN
+ break;
+ case ACT_WHISPER:
+ tmp.nick = strprintf(_("%s whispers: %s"), tmp.nick.c_str(), "");
+ lineColor = "##W";
+ break;
+ case ACT_IS:
+ lineColor = "##I";
+ break;
+ case BY_LOGGER:
+ tmp.nick = "";
+ tmp.text = line;
+ lineColor = "##L";
+ break;
+ default:
+ logger->log1("ChatTab::chatLog incorrect value in switch");
+ break;
+ }
+
+ if (tmp.nick == ": ")
+ {
+ tmp.nick = "";
+ lineColor = "##S";
+ }
+
+ // if configured, move magic messages log to debug chat tab
+ if (localChatTab && this == localChatTab
+ && ((config.getBoolValue("showMagicInDebug")
+ && own == BY_PLAYER && tmp.text.length() > 1
+ && tmp.text.length() > 1 && tmp.text.at(0) == '#'
+ && tmp.text.at(1) != '#')
+ || (config.getBoolValue("serverMsgInDebug") && (own == BY_SERVER
+ || tmp.nick.empty()))))
+ {
+ if (debugChatTab)
+ debugChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
+ return;
+ }
+
+ // Get the current system time
+ time_t t;
+ time(&t);
+
+ // Format the time string properly
+ std::stringstream timeStr;
+ timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "")
+ << static_cast<int>(((t / 60) / 60) % 24)
+ << ":" << (((t / 60) % 60 < 10) ? "0" : "")
+ << static_cast<int>((t / 60) % 60)
+ << "] ";
+
+ line = lineColor + timeStr.str() + tmp.nick + tmp.text;
+
+ if (config.getBoolValue("enableChatLog"))
+ saveToLogFile(line);
+
+ mTextOutput->setMaxRow(config.getIntValue("chatMaxLinesLimit"));
+
+ // We look if the Vertical Scroll Bar is set at the max before
+ // adding a row, otherwise the max will always be a row higher
+ // at comparison.
+ if (mScrollArea->getVerticalScrollAmount() >=
+ mScrollArea->getVerticalMaxScroll())
+ {
+ addRow(line);
+ mScrollArea->setVerticalScrollAmount(
+ mScrollArea->getVerticalMaxScroll());
+ }
+ else
+ {
+ addRow(line);
+ }
+
+ mScrollArea->logic();
+ if (own != BY_PLAYER)
+ {
+ if (own == BY_SERVER && (getType() == TAB_PARTY
+ || getType() == TAB_GUILD))
+ {
+ return;
+ }
+
+ if (!getTabbedArea())
+ return;
+
+ if (this != getTabbedArea()->getSelectedTab())
+ {
+ if (getFlash() == 0)
+ {
+ if (player_node)
+ {
+ std::string::size_type pos
+ = tmp.text.find(player_node->getName());
+ if (pos != std::string::npos)
+ setFlash(2);
+ else
+ setFlash(1);
+ }
+ else
+ {
+ setFlash(1);
+ }
+ }
+ }
+
+ if (getAllowHighlight() && (this != getTabbedArea()->getSelectedTab()
+ || (Client::getIsMinimized() || (!Client::getMouseFocused()
+ && !Client::getInputFocused()))))
+ {
+ if (own != BY_SERVER)
+ sound.playGuiSfx("system/newmessage.ogg");
+ }
+ }
+}
+
+void ChatTab::chatLog(const std::string &nick, std::string msg)
+{
+ Own byWho = (nick == player_node->getName() ? BY_PLAYER : BY_OTHER);
+ if (byWho == BY_OTHER && config.getBoolValue("removeColors"))
+ msg = removeColors(msg);
+ chatLog(nick + " : " + msg, byWho, false, false);
+}
+
+void ChatTab::chatInput(const std::string &message)
+{
+ std::string msg = message;
+ trim(msg);
+
+ if (msg.empty())
+ return;
+
+ // Check for item link
+ std::string::size_type start = msg.find('[');
+ while (start + 1 < msg.size() && start != std::string::npos
+ && msg[start + 1] != '@')
+ {
+ std::string::size_type end = msg.find(']', start);
+ if (start + 1 != end && end != std::string::npos)
+ {
+ // Catch multiple embeds and ignore them
+ // so it doesn't crash the client.
+ while ((msg.find('[', start + 1) != std::string::npos) &&
+ (msg.find('[', start + 1) < end))
+ {
+ start = msg.find('[', start + 1);
+ }
+
+ std::string temp = "";
+ if (start + 1 < msg.length() && end < msg.length()
+ && end > start + 1)
+ {
+ temp = msg.substr(start + 1, end - start - 1);
+
+ const ItemInfo itemInfo = ItemDB::get(temp);
+ if (itemInfo.getId() != 0)
+ {
+ msg.insert(end, "@@");
+ msg.insert(start + 1, "|");
+ msg.insert(start + 1, toString(itemInfo.getId()));
+ msg.insert(start + 1, "@@");
+ }
+ }
+ }
+ start = msg.find('[', start + 1);
+ }
+
+ // Prepare ordinary message
+ if (msg[0] != '/')
+ handleInput(msg);
+ else
+ handleCommand(std::string(msg, 1));
+}
+
+void ChatTab::scroll(int amount)
+{
+ int range = mScrollArea->getHeight() / 8 * amount;
+ gcn::Rectangle scr;
+ scr.y = mScrollArea->getVerticalScrollAmount() + range;
+ scr.height = abs(range);
+ mTextOutput->showPart(scr);
+}
+
+void ChatTab::clearText()
+{
+ mTextOutput->clearRows();
+}
+
+void ChatTab::handleInput(const std::string &msg)
+{
+ if (chatWindow)
+ Net::getChatHandler()->talk(chatWindow->doReplace(msg));
+ else
+ Net::getChatHandler()->talk(msg);
+}
+
+void ChatTab::handleCommand(const std::string &msg)
+{
+ if (commandHandler)
+ commandHandler->handleCommands(msg, this);
+}
+
+bool ChatTab::handleCommands(const std::string &type, const std::string &args)
+{
+ // need split to commands and call each
+
+ return handleCommand(type, args);
+}
+
+void ChatTab::saveToLogFile(std::string &msg)
+{
+ if (getType() == TAB_INPUT && chatLogger)
+ chatLogger->log(msg);
+}
+
+int ChatTab::getType() const
+{
+ if (getCaption() == "General" || getCaption() == _("General"))
+ return TAB_INPUT;
+ else if (getCaption() == "Debug" || getCaption() == _("Debug"))
+ return TAB_DEBUG;
+ else
+ return TAB_UNKNOWN;
+}
+
+void ChatTab::addRow(std::string &line)
+{
+ std::string::size_type idx = 0;
+
+ for (unsigned int f = 0; f < line.length(); f++)
+ {
+ if (line.at(f) == ' ')
+ {
+ idx = f;
+ }
+ else if (f - idx > MAX_WORD_SIZE)
+ {
+ line.insert(f, " ");
+ idx = f;
+ }
+ }
+ mTextOutput->addRow(line);
+}
+
+void ChatTab::loadFromLogFile(std::string name)
+{
+ if (chatLogger)
+ {
+ std::list<std::string> list;
+ chatLogger->loadLast(name, list, 5);
+ std::list<std::string>::iterator i = list.begin();
+ while (i != list.end())
+ {
+ std::string line = "##9" + *i;
+ addRow(line);
+ ++i;
+ }
+ }
+}
diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h
new file mode 100644
index 000000000..ddc36d29c
--- /dev/null
+++ b/src/gui/widgets/chattab.h
@@ -0,0 +1,173 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHATTAB_H
+#define CHATTAB_H
+
+#include "gui/chat.h"
+
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/tab.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class ScrollArea;
+
+/**
+ * A tab for the chat window. This is special to ease chat handling.
+ */
+class ChatTab : public Tab
+{
+ public:
+ enum Type
+ {
+ TAB_UNKNOWN = 0,
+ TAB_INPUT,
+ TAB_WHISPER,
+ TAB_PARTY,
+ TAB_GUILD,
+ TAB_DEBUG,
+ TAB_TRADE,
+ TAB_BATTLE
+ };
+
+ /**
+ * Constructor.
+ */
+ ChatTab(const std::string &name);
+ ~ChatTab();
+
+ /**
+ * Adds a line of text to our message list. Parameters:
+ *
+ * @param line Text message.
+ * @param own Type of message (usually the owner-type).
+ * @param channelName which channel to send the message to.
+ * @param ignoreRecord should this not be recorded?
+ * @param removeColors try remove color if configured
+ */
+ void chatLog(std::string line, Own own = BY_SERVER,
+ bool ignoreRecord = false, bool tryRemoveColors = true);
+
+ /**
+ * Adds the text to the message list
+ *
+ * @param msg The message text which is to be sent.
+ */
+ void chatLog(const std::string &nick, std::string msg);
+
+ /**
+ * Determines whether the message is a command or message, then
+ * sends the given message to the game server to be said, or to the
+ * command handler
+ *
+ * @param msg The message text which is to be sent.
+ */
+ void chatInput(const std::string &msg);
+
+ /**
+ * Scrolls the chat window
+ *
+ * @param amount direction and amount to scroll. Negative numbers scroll
+ * up, positive numbers scroll down. The absolute amount indicates the
+ * amount of 1/8ths of chat window real estate that should be scrolled.
+ */
+ void scroll(int amount);
+
+ /**
+ * Clears the text from the tab
+ */
+ void clearText();
+
+ /**
+ * Add any extra help text to the output. Allows tabs to define help
+ * for commands defined by the tab itself.
+ */
+ virtual void showHelp() {}
+
+ /**
+ * Handle special commands. Allows a tab to handle commands it
+ * defines itself.
+ *
+ * @returns true if the command was handled
+ * false if the command was not handled
+ */
+ virtual bool handleCommand(const std::string &type _UNUSED_,
+ const std::string &args _UNUSED_)
+ { return false; }
+
+ /**
+ * Handle special commands. Allows a tab to handle commands it
+ * defines itself.
+ *
+ * @returns true if the command was handled
+ * false if the command was not handled
+ */
+ virtual bool handleCommands(const std::string &type,
+ const std::string &args);
+
+ /**
+ * Returns type of the being.
+ */
+ virtual int getType() const;
+
+ virtual void saveToLogFile(std::string &msg);
+
+ std::list<std::string> &getRows()
+ { return mTextOutput->getRows(); }
+
+ void loadFromLogFile(std::string name);
+
+ bool getAllowHighlight()
+ { return mAllowHightlight; }
+
+ void setAllowHighlight(bool n)
+ { mAllowHightlight = n; }
+
+ protected:
+ friend class ChatWindow;
+ friend class WhisperWindow;
+
+ virtual void setCurrent()
+ { setFlash(false); }
+
+ virtual void handleInput(const std::string &msg);
+
+ virtual void handleCommand(const std::string &msg);
+
+ virtual void getAutoCompleteList(std::vector<std::string>&) const
+ {}
+
+ void addRow(std::string &line);
+
+ ScrollArea *mScrollArea;
+ BrowserBox *mTextOutput;
+ bool mAllowHightlight;
+};
+
+extern ChatTab *localChatTab;
+extern ChatTab *debugChatTab;
+
+#endif // CHATTAB_H
diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp
new file mode 100644
index 000000000..01331ddba
--- /dev/null
+++ b/src/gui/widgets/checkbox.cpp
@@ -0,0 +1,187 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/checkbox.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+
+#include "gui/palette.h"
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+#include <guichan/actionlistener.hpp>
+
+int CheckBox::instances = 0;
+float CheckBox::mAlpha = 1.0;
+Image *CheckBox::checkBoxNormal;
+Image *CheckBox::checkBoxChecked;
+Image *CheckBox::checkBoxDisabled;
+Image *CheckBox::checkBoxDisabledChecked;
+Image *CheckBox::checkBoxNormalHi;
+Image *CheckBox::checkBoxCheckedHi;
+
+CheckBox::CheckBox(const std::string &caption, bool selected,
+ gcn::ActionListener* listener, std::string eventId):
+ gcn::CheckBox(caption, selected),
+ mHasMouse(false)
+{
+ if (instances == 0)
+ {
+ Image *checkBox = Theme::getImageFromTheme("checkbox.png");
+ if (checkBox)
+ {
+ checkBoxNormal = checkBox->getSubImage(0, 0, 9, 10);
+ checkBoxChecked = checkBox->getSubImage(9, 0, 9, 10);
+ checkBoxDisabled = checkBox->getSubImage(18, 0, 9, 10);
+ checkBoxDisabledChecked = checkBox->getSubImage(27, 0, 9, 10);
+ checkBoxNormalHi = checkBox->getSubImage(36, 0, 9, 10);
+ checkBoxCheckedHi = checkBox->getSubImage(45, 0, 9, 10);
+ checkBoxNormal->setAlpha(mAlpha);
+ checkBoxChecked->setAlpha(mAlpha);
+ checkBoxDisabled->setAlpha(mAlpha);
+ checkBoxDisabledChecked->setAlpha(mAlpha);
+ checkBoxNormalHi->setAlpha(mAlpha);
+ checkBoxCheckedHi->setAlpha(mAlpha);
+ checkBox->decRef();
+ }
+ else
+ {
+ checkBoxNormal = 0;
+ checkBoxChecked = 0;
+ checkBoxDisabled = 0;
+ checkBoxDisabledChecked = 0;
+ checkBoxNormalHi = 0;
+ checkBoxCheckedHi = 0;
+ }
+ }
+
+ instances++;
+
+ if (!eventId.empty())
+ setActionEventId(eventId);
+
+ if (listener)
+ addActionListener(listener);
+}
+
+CheckBox::~CheckBox()
+{
+ instances--;
+
+ if (instances == 0)
+ {
+ delete checkBoxNormal;
+ checkBoxNormal = 0;
+ delete checkBoxChecked;
+ checkBoxChecked = 0;
+ delete checkBoxDisabled;
+ checkBoxDisabled = 0;
+ delete checkBoxDisabledChecked;
+ checkBoxDisabledChecked = 0;
+ delete checkBoxNormalHi;
+ checkBoxNormalHi = 0;
+ delete checkBoxCheckedHi;
+ checkBoxCheckedHi = 0;
+ }
+}
+
+void CheckBox::draw(gcn::Graphics* graphics)
+{
+ drawBox(graphics);
+
+ graphics->setFont(getFont());
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+
+ const int h = getHeight() + getHeight() / 2;
+
+ graphics->drawText(getCaption(), h - 2, 0);
+}
+
+void CheckBox::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (mAlpha != alpha)
+ {
+ mAlpha = alpha;
+ if (checkBoxNormal)
+ checkBoxNormal->setAlpha(mAlpha);
+ if (checkBoxChecked)
+ checkBoxChecked->setAlpha(mAlpha);
+ if (checkBoxDisabled)
+ checkBoxDisabled->setAlpha(mAlpha);
+ if (checkBoxDisabledChecked)
+ checkBoxDisabledChecked->setAlpha(mAlpha);
+ if (checkBoxNormal)
+ checkBoxNormal->setAlpha(mAlpha);
+ if (checkBoxCheckedHi)
+ checkBoxCheckedHi->setAlpha(mAlpha);
+ }
+}
+
+void CheckBox::drawBox(gcn::Graphics* graphics)
+{
+ Image *box;
+
+ if (isEnabled())
+ {
+ if (isSelected())
+ {
+ if (mHasMouse)
+ box = checkBoxCheckedHi;
+ else
+ box = checkBoxChecked;
+ }
+ else
+ {
+ if (mHasMouse)
+ box = checkBoxNormalHi;
+ else
+ box = checkBoxNormal;
+ }
+ }
+ else
+ {
+ if (isSelected())
+ box = checkBoxDisabledChecked;
+ else
+ box = checkBoxDisabled;
+ }
+
+ updateAlpha();
+
+ if (box)
+ static_cast<Graphics*>(graphics)->drawImage(box, 2, 2);
+}
+
+void CheckBox::mouseEntered(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = true;
+}
+
+void CheckBox::mouseExited(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = false;
+}
diff --git a/src/gui/widgets/checkbox.h b/src/gui/widgets/checkbox.h
new file mode 100644
index 000000000..b885e8922
--- /dev/null
+++ b/src/gui/widgets/checkbox.h
@@ -0,0 +1,92 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHECKBOX_H
+#define CHECKBOX_H
+
+#include <guichan/widgets/checkbox.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+
+/**
+ * Check box widget. Same as the Guichan check box but with custom look.
+ *
+ * \ingroup GUI
+ */
+class CheckBox : public gcn::CheckBox
+{
+ public:
+ /**
+ * Constructor.
+ */
+ CheckBox(const std::string &caption, bool selected = false,
+ gcn::ActionListener* listener = NULL,
+ std::string eventId = "");
+
+ /**
+ * Destructor.
+ */
+ ~CheckBox();
+
+ /**
+ * Draws the caption, then calls drawBox to draw the check box.
+ */
+ void draw(gcn::Graphics* graphics);
+
+ /**
+ * Update the alpha value to the checkbox components.
+ */
+ void updateAlpha();
+
+ /**
+ * Draws the check box, not the caption.
+ */
+ void drawBox(gcn::Graphics* graphics);
+
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
+ private:
+ static int instances;
+ static float mAlpha;
+ bool mHasMouse;
+ static Image *checkBoxNormal;
+ static Image *checkBoxChecked;
+ static Image *checkBoxDisabled;
+ static Image *checkBoxDisabledChecked;
+ static Image *checkBoxNormalHi;
+ static Image *checkBoxCheckedHi;
+};
+
+#endif
diff --git a/src/gui/widgets/container.cpp b/src/gui/widgets/container.cpp
new file mode 100644
index 000000000..b788b0610
--- /dev/null
+++ b/src/gui/widgets/container.cpp
@@ -0,0 +1,33 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/container.h"
+
+Container::Container()
+{
+ setOpaque(false);
+}
+
+Container::~Container()
+{
+ while (!mWidgets.empty())
+ delete mWidgets.front();
+}
diff --git a/src/gui/widgets/container.h b/src/gui/widgets/container.h
new file mode 100644
index 000000000..c2696a65f
--- /dev/null
+++ b/src/gui/widgets/container.h
@@ -0,0 +1,43 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_CONTAINER_H
+#define GUI_CONTAINER_H
+
+#include <guichan/widgets/container.hpp>
+
+/**
+ * A widget container.
+ *
+ * The main difference between the standard Guichan container and this one is
+ * that childs added to this container are automatically deleted when the
+ * container is deleted.
+ *
+ * This container is also non-opaque by default.
+ */
+class Container : public gcn::Container
+{
+ public:
+ Container();
+ ~Container();
+};
+
+#endif
diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp
new file mode 100644
index 000000000..fa5b1698a
--- /dev/null
+++ b/src/gui/widgets/desktop.cpp
@@ -0,0 +1,157 @@
+/*
+ * Desktop widget
+ * Copyright (c) 2009-2010 The Mana World Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/desktop.h"
+
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+#include "main.h"
+
+#include "gui/palette.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/label.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+#include "resources/wallpaper.h"
+
+#include "utils/stringutils.h"
+
+Desktop::Desktop()
+ : mWallpaper(0)
+{
+ addWidgetListener(this);
+
+ Wallpaper::loadWallpapers();
+
+ std::string appName = branding.getValue("appName", std::string(""));
+
+ if (appName.empty())
+ mVersionLabel = new Label(FULL_VERSION);
+ else
+ mVersionLabel = new Label(strprintf("%s (Mana %s)", appName.c_str(),
+ FULL_VERSION));
+
+ mVersionLabel->setBackgroundColor(gcn::Color(255, 255, 255, 128));
+ add(mVersionLabel, 25, 2);
+}
+
+Desktop::~Desktop()
+{
+ if (mWallpaper)
+ mWallpaper->decRef();
+}
+
+void Desktop::reloadWallpaper()
+{
+ Wallpaper::loadWallpapers();
+ setBestFittingWallpaper();
+}
+
+void Desktop::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ setBestFittingWallpaper();
+}
+
+void Desktop::draw(gcn::Graphics *graphics)
+{
+ Graphics *g = static_cast<Graphics *>(graphics);
+
+ if (!mWallpaper || (getWidth() > mWallpaper->getWidth() ||
+ getHeight() > mWallpaper->getHeight()))
+ {
+ // TODO: Color from palette
+ g->setColor(gcn::Color(64, 64, 64));
+ g->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
+ if (mWallpaper)
+ {
+ if (!mWallpaper->useOpenGL())
+ {
+ g->drawImage(mWallpaper,
+ (getWidth() - mWallpaper->getWidth()) / 2,
+ (getHeight() - mWallpaper->getHeight()) / 2);
+ }
+ else
+ {
+ g->drawRescaledImage(mWallpaper, 0, 0, 0, 0,
+ mWallpaper->getWidth(), mWallpaper->getHeight(),
+ getWidth(), getHeight(), false);
+ }
+ }
+
+ // Draw a thin border under the application version...
+ g->setColor(gcn::Color(255, 255, 255, 128));
+ g->fillRectangle(gcn::Rectangle(mVersionLabel->getDimension()));
+
+ Container::draw(graphics);
+}
+
+void Desktop::setBestFittingWallpaper()
+{
+ if (!config.getBoolValue("showBackground"))
+ return;
+
+ const std::string wallpaperName =
+ Wallpaper::getWallpaper(getWidth(), getHeight());
+
+ Image *nWallPaper = Theme::getImageFromTheme(wallpaperName);
+
+ if (nWallPaper)
+ {
+ if (mWallpaper)
+ mWallpaper->decRef();
+
+ if (!nWallPaper->useOpenGL()
+ && (nWallPaper->getWidth() != getWidth()
+ || nWallPaper->getHeight() != getHeight()))
+ {
+ // We rescale to obtain a fullscreen wallpaper...
+ Image *newRsclWlPpr = nWallPaper->SDLgetScaledImage(
+ getWidth(), getHeight());
+ std::string idPath = nWallPaper->getIdPath();
+
+ // We replace the resource in the resource manager
+ nWallPaper->decRef();
+ if (newRsclWlPpr)
+ {
+ ResourceManager::getInstance()->addResource(
+ idPath, newRsclWlPpr);
+
+ mWallpaper = newRsclWlPpr;
+ }
+ else
+ {
+ mWallpaper = nWallPaper;
+ }
+ }
+ else
+ {
+ mWallpaper = nWallPaper;
+ }
+ }
+ else
+ {
+ logger->log("Couldn't load %s as wallpaper", wallpaperName.c_str());
+ }
+}
diff --git a/src/gui/widgets/desktop.h b/src/gui/widgets/desktop.h
new file mode 100644
index 000000000..83568c66f
--- /dev/null
+++ b/src/gui/widgets/desktop.h
@@ -0,0 +1,73 @@
+/*
+ * Desktop widget
+ * Copyright (c) 2009-2010 The Mana World Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef DESKTOP_H
+#define DESKTOP_H
+
+#include "guichanfwd.h"
+
+#include "gui/widgets/container.h"
+
+#include <guichan/widgetlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+
+/**
+ * Desktop widget, for drawing a background image and color.
+ *
+ * It picks the best fitting background image. If the image doesn't fit, a
+ * background color is drawn and the image is centered.
+ *
+ * When the desktop widget is resized, the background image is automatically
+ * updated.
+ *
+ * The desktop also displays the client version in the top-right corner.
+ *
+ * \ingroup GUI
+ */
+class Desktop : public Container, gcn::WidgetListener
+{
+ public:
+ Desktop();
+ ~Desktop();
+
+ /**
+ * Has to be called after updates have been loaded.
+ */
+ void reloadWallpaper();
+
+ void widgetResized(const gcn::Event &event);
+
+ void draw(gcn::Graphics *graphics);
+
+ private:
+ void setBestFittingWallpaper();
+
+ Image *mWallpaper;
+ gcn::Label *mVersionLabel;
+};
+
+#endif // DESKTOP_H
diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp
new file mode 100644
index 000000000..b8616643b
--- /dev/null
+++ b/src/gui/widgets/dropdown.cpp
@@ -0,0 +1,303 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/dropdown.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+
+#include "gui/palette.h"
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/scrollarea.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+#include <algorithm>
+
+int DropDown::instances = 0;
+Image *DropDown::buttons[2][2];
+ImageRect DropDown::skin;
+float DropDown::mAlpha = 1.0;
+
+DropDown::DropDown(gcn::ListModel *listModel):
+ gcn::DropDown::DropDown(listModel,
+ new ScrollArea,
+ new ListBox(listModel))
+{
+ setFrameSize(2);
+
+ // Initialize graphics
+ if (instances == 0)
+ {
+ // Load the background skin
+
+ // Get the button skin
+ buttons[1][0] = Theme::getImageFromTheme("vscroll_up_default.png");
+ buttons[0][0] = Theme::getImageFromTheme("vscroll_down_default.png");
+ buttons[1][1] = Theme::getImageFromTheme("vscroll_up_pressed.png");
+ buttons[0][1] = Theme::getImageFromTheme("vscroll_down_pressed.png");
+
+ if (buttons[0][0])
+ buttons[0][0]->setAlpha(mAlpha);
+ if (buttons[0][1])
+ buttons[0][1]->setAlpha(mAlpha);
+ if (buttons[1][0])
+ buttons[1][0]->setAlpha(mAlpha);
+ if (buttons[1][1])
+ buttons[1][1]->setAlpha(mAlpha);
+
+ // get the border skin
+ Image *boxBorder = Theme::getImageFromTheme("deepbox.png");
+ if (boxBorder)
+ {
+ int gridx[4] = {0, 3, 28, 31};
+ int gridy[4] = {0, 3, 28, 31};
+ int a = 0, x, y;
+
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ skin.grid[a] = boxBorder->getSubImage(gridx[x], gridy[y],
+ gridx[x + 1] -
+ gridx[x] + 1,
+ gridy[y + 1] -
+ gridy[y] + 1);
+ if (skin.grid[a])
+ skin.grid[a]->setAlpha(mAlpha);
+ a++;
+ }
+ }
+
+ boxBorder->decRef();
+ }
+ }
+
+ instances++;
+}
+
+DropDown::~DropDown()
+{
+ instances--;
+ // Free images memory
+ if (instances == 0)
+ {
+ if (buttons[0][0])
+ buttons[0][0]->decRef();
+ if (buttons[0][1])
+ buttons[0][1]->decRef();
+ if (buttons[1][0])
+ buttons[1][0]->decRef();
+ if (buttons[1][1])
+ buttons[1][1]->decRef();
+
+ for_each(skin.grid, skin.grid + 9, dtor<Image*>());
+ }
+
+ delete mScrollArea;
+ mScrollArea = 0;
+}
+
+void DropDown::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (mAlpha != alpha)
+ {
+ mAlpha = alpha;
+
+ if (buttons[0][0])
+ buttons[0][0]->setAlpha(mAlpha);
+ if (buttons[0][1])
+ buttons[0][1]->setAlpha(mAlpha);
+ if (buttons[1][0])
+ buttons[1][0]->setAlpha(mAlpha);
+ if (buttons[1][1])
+ buttons[1][1]->setAlpha(mAlpha);
+
+ for (int a = 0; a < 9; a++)
+ {
+ if (skin.grid[a])
+ skin.grid[a]->setAlpha(mAlpha);
+ }
+ }
+}
+
+void DropDown::draw(gcn::Graphics* graphics)
+{
+ int h;
+
+ if (mDroppedDown)
+ h = mFoldedUpHeight;
+ else
+ h = getHeight();
+
+ updateAlpha();
+
+ const int alpha = static_cast<int>(mAlpha * 255.0f);
+ gcn::Color faceColor = getBaseColor();
+ faceColor.a = alpha;
+ const gcn::Color *highlightColor = &Theme::getThemeColor(Theme::HIGHLIGHT,
+ alpha);
+ gcn::Color shadowColor = faceColor - 0x303030;
+ shadowColor.a = alpha;
+
+ if (mListBox->getListModel() && mListBox->getSelected() >= 0)
+ {
+ graphics->setFont(getFont());
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ graphics->drawText(mListBox->getListModel()->getElementAt(
+ mListBox->getSelected()), 1, 0);
+ }
+
+ if (isFocused())
+ {
+ if (highlightColor)
+ graphics->setColor(*highlightColor);
+ graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth() - h, h));
+ }
+
+ drawButton(graphics);
+
+ if (mDroppedDown)
+ {
+ drawChildren(graphics);
+
+ // Draw two lines separating the ListBox with selected
+ // element view.
+ if (highlightColor)
+ graphics->setColor(*highlightColor);
+ graphics->drawLine(0, h, getWidth(), h);
+ graphics->setColor(shadowColor);
+ graphics->drawLine(0, h + 1, getWidth(), h + 1);
+ }
+}
+
+void DropDown::drawFrame(gcn::Graphics *graphics)
+{
+ const int bs = getFrameSize();
+ const int w = getWidth() + bs * 2;
+ const int h = getHeight() + bs * 2;
+
+ static_cast<Graphics*>(graphics)->drawImageRect(0, 0, w, h, skin);
+}
+
+void DropDown::drawButton(gcn::Graphics *graphics)
+{
+ int height = mDroppedDown ? mFoldedUpHeight : getHeight();
+
+ if (buttons[mDroppedDown][mPushed])
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImage(buttons[mDroppedDown][mPushed],
+ getWidth() - height + 2, 1);
+ }
+}
+
+// -- KeyListener notifications
+void DropDown::keyPressed(gcn::KeyEvent& keyEvent)
+{
+ if (keyEvent.isConsumed())
+ return;
+
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ENTER || key.getValue() == Key::SPACE)
+ dropDown();
+ else if (key.getValue() == Key::UP)
+ setSelected(getSelected() - 1);
+ else if (key.getValue() == Key::DOWN)
+ setSelected(getSelected() + 1);
+ else if (key.getValue() == Key::HOME)
+ setSelected(0);
+ else if (key.getValue() == Key::END && mListBox->getListModel())
+ setSelected(mListBox->getListModel()->getNumberOfElements() - 1);
+ else
+ return;
+
+ keyEvent.consume();
+}
+
+void DropDown::focusLost(const gcn::Event& event)
+{
+ gcn::DropDown::focusLost(event);
+ releaseModalMouseInputFocus();
+}
+
+void DropDown::mousePressed(gcn::MouseEvent& mouseEvent)
+{
+ gcn::DropDown::mousePressed(mouseEvent);
+
+ if (0 <= mouseEvent.getY() && mouseEvent.getY() < getHeight() &&
+ mouseEvent.getX() >= 0 && mouseEvent.getX() < getWidth() &&
+ mouseEvent.getButton() == gcn::MouseEvent::LEFT && mDroppedDown &&
+ mouseEvent.getSource() == mListBox)
+ {
+ mPushed = false;
+ foldUp();
+ releaseModalMouseInputFocus();
+ distributeActionEvent();
+ }
+}
+
+void DropDown::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent)
+{
+ setSelected(getSelected() - 1);
+ mouseEvent.consume();
+}
+
+void DropDown::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent)
+{
+ setSelected(getSelected() + 1);
+ mouseEvent.consume();
+}
+
+void DropDown::setSelectedString(std::string str)
+{
+ gcn::ListModel *listModel = mListBox->getListModel();
+ if (!listModel)
+ return;
+
+ for (int f = 0; f < listModel->getNumberOfElements(); f ++)
+ {
+ if (listModel->getElementAt(f) == str)
+ {
+ setSelected(f);
+ break;
+ }
+ }
+}
+
+std::string DropDown::getSelectedString() const
+{
+ gcn::ListModel *listModel = mListBox->getListModel();
+ if (!listModel)
+ return "";
+
+ return listModel->getElementAt(getSelected());
+}
diff --git a/src/gui/widgets/dropdown.h b/src/gui/widgets/dropdown.h
new file mode 100644
index 000000000..f6e347b2b
--- /dev/null
+++ b/src/gui/widgets/dropdown.h
@@ -0,0 +1,97 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef DROPDOWN_H
+#define DROPDOWN_H
+
+#include <guichan/widgets/dropdown.hpp>
+
+class Image;
+class ImageRect;
+
+/**
+ * A drop down box from which you can select different values.
+ *
+ * A ListModel provides the contents of the drop down. To be able to use
+ * DropDown you must give DropDown an implemented ListModel which represents
+ * your list.
+ */
+class DropDown : public gcn::DropDown
+{
+ public:
+ /**
+ * Contructor.
+ *
+ * @param listModel the ListModel to use.
+ * @param scrollArea the ScrollArea to use.
+ * @param listBox the listBox to use.
+ * @see ListModel, ScrollArea, ListBox.
+ */
+ DropDown(gcn::ListModel *listModel = 0);
+
+ ~DropDown();
+
+ /**
+ * Update the alpha value to the graphic components.
+ */
+ void updateAlpha();
+
+ void draw(gcn::Graphics *graphics);
+
+ void drawFrame(gcn::Graphics *graphics);
+
+ // Inherited from FocusListener
+
+ void focusLost(const gcn::Event& event);
+
+ // Inherited from KeyListener
+
+ void keyPressed(gcn::KeyEvent& keyEvent);
+
+ // Inherited from MouseListener
+
+ void mousePressed(gcn::MouseEvent& mouseEvent);
+
+ void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent);
+
+ void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent);
+
+ void setSelectedString(std::string str);
+
+ std::string getSelectedString() const;
+
+ protected:
+ /**
+ * Draws the button with the little down arrow.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ void drawButton(gcn::Graphics *graphics);
+
+ // Add own Images.
+ static int instances;
+ static Image *buttons[2][2];
+ static ImageRect skin;
+ static float mAlpha;
+};
+
+#endif // end DROPDOWN_H
+
diff --git a/src/gui/widgets/dropshortcutcontainer.cpp b/src/gui/widgets/dropshortcutcontainer.cpp
new file mode 100644
index 000000000..c3aaed829
--- /dev/null
+++ b/src/gui/widgets/dropshortcutcontainer.cpp
@@ -0,0 +1,303 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/widgets/dropshortcutcontainer.h"
+
+#include "gui/inventorywindow.h"
+#include "gui/itempopup.h"
+#include "gui/palette.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "configuration.h"
+#include "dropshortcut.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/stringutils.h"
+
+DropShortcutContainer::DropShortcutContainer():
+ ShortcutContainer(),
+ mItemClicked(false),
+ mItemMoved(NULL)
+{
+ addMouseListener(this);
+ addWidgetListener(this);
+
+ mItemPopup = new ItemPopup;
+
+ mBackgroundImg = Theme::getImageFromTheme("item_shortcut_bgr.png");
+ if (dropShortcut)
+ mMaxItems = dropShortcut->getItemCount();
+ else
+ mMaxItems = 0;
+
+ if (mBackgroundImg)
+ {
+ mBackgroundImg->setAlpha(Client::getGuiAlpha());
+ mBoxHeight = mBackgroundImg->getHeight();
+ mBoxWidth = mBackgroundImg->getWidth();
+ }
+ else
+ {
+ mBoxHeight = 1;
+ mBoxWidth = 1;
+ }
+}
+
+DropShortcutContainer::~DropShortcutContainer()
+{
+ if (mBackgroundImg)
+ mBackgroundImg->decRef();
+ delete mItemPopup;
+ mItemPopup = 0;
+}
+
+void DropShortcutContainer::draw(gcn::Graphics *graphics)
+{
+ if (!dropShortcut)
+ return;
+
+ if (Client::getGuiAlpha() != mAlpha)
+ {
+ mAlpha = Client::getGuiAlpha();
+ if (mBackgroundImg)
+ mBackgroundImg->setAlpha(mAlpha);
+ }
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ graphics->setFont(getFont());
+
+ for (unsigned i = 0; i < mMaxItems; i++)
+ {
+ const int itemX = (i % mGridWidth) * mBoxWidth;
+ const int itemY = (i / mGridWidth) * mBoxHeight;
+
+ if (mBackgroundImg)
+ g->drawImage(mBackgroundImg, itemX, itemY);
+
+/* // Draw item keyboard shortcut.
+ const char *key = SDL_GetKeyName(
+ (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_1 + i));
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
+ g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT);
+*/
+ if (dropShortcut->getItem(i) < 0)
+ continue;
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *item = inv->findItem(dropShortcut->getItem(i));
+
+ if (item)
+ {
+ // Draw item icon.
+ Image* image = item->getImage();
+
+ if (image)
+ {
+ std::string caption;
+ if (item->getQuantity() > 1)
+ caption = toString(item->getQuantity());
+ else if (item->isEquipped())
+ caption = "Eq.";
+
+ image->setAlpha(1.0f);
+ g->drawImage(image, itemX, itemY);
+ if (item->isEquipped())
+ g->setColor(Theme::getThemeColor(Theme::ITEM_EQUIPPED));
+ else
+ g->setColor(Theme::getThemeColor(Theme::TEXT));
+ g->drawText(caption, itemX + mBoxWidth / 2,
+ itemY + mBoxHeight - 14, gcn::Graphics::CENTER);
+ }
+ }
+ }
+
+ if (mItemMoved)
+ {
+ // Draw the item image being dragged by the cursor.
+ Image* image = mItemMoved->getImage();
+ if (image)
+ {
+ const int tPosX = mCursorPosX - (image->getWidth() / 2);
+ const int tPosY = mCursorPosY - (image->getHeight() / 2);
+
+ g->drawImage(image, tPosX, tPosY);
+ g->drawText(toString(mItemMoved->getQuantity()),
+ tPosX + mBoxWidth / 2, tPosY + mBoxHeight - 14,
+ gcn::Graphics::CENTER);
+ }
+ }
+}
+
+void DropShortcutContainer::mouseDragged(gcn::MouseEvent &event)
+{
+ if (!dropShortcut)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (!mItemMoved && mItemClicked)
+ {
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ const int itemId = dropShortcut->getItem(index);
+
+ if (itemId < 0)
+ return;
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *item = inv->findItem(itemId);
+
+ if (item)
+ {
+ mItemMoved = item;
+ dropShortcut->removeItem(index);
+ }
+ }
+ if (mItemMoved)
+ {
+ mCursorPosX = event.getX();
+ mCursorPosY = event.getY();
+ }
+ }
+}
+
+void DropShortcutContainer::mousePressed(gcn::MouseEvent &event)
+{
+ if (!dropShortcut || !inventoryWindow)
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ // Stores the selected item if theirs one.
+ if (dropShortcut->isItemSelected() && inventoryWindow->isVisible())
+ {
+ dropShortcut->setItem(index);
+ dropShortcut->setItemSelected(-1);
+ }
+ else if (dropShortcut->getItem(index))
+ {
+ mItemClicked = true;
+ }
+ }
+ else if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *item = inv->findItem(dropShortcut->getItem(index));
+
+ if (viewport)
+ viewport->showDropPopup(item);
+ }
+}
+
+void DropShortcutContainer::mouseReleased(gcn::MouseEvent &event)
+{
+ if (!dropShortcut)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (dropShortcut->isItemSelected())
+ dropShortcut->setItemSelected(-1);
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1)
+ {
+ mItemMoved = NULL;
+ return;
+ }
+ if (mItemMoved)
+ {
+ dropShortcut->setItems(index, mItemMoved->getId());
+ mItemMoved = NULL;
+ }
+
+ if (mItemClicked)
+ mItemClicked = false;
+ }
+}
+
+// Show ItemTooltip
+void DropShortcutContainer::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!dropShortcut)
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ const int itemId = dropShortcut->getItem(index);
+
+ if (itemId < 0)
+ return;
+
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *item = inv->findItem(itemId);
+
+ if (item && viewport)
+ {
+ mItemPopup->setItem(item);
+ mItemPopup->position(viewport->getMouseX(), viewport->getMouseY());
+ }
+ else
+ {
+ mItemPopup->setVisible(false);
+ }
+}
+
+// Hide ItemTooltip
+void DropShortcutContainer::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ mItemPopup->setVisible(false);
+}
diff --git a/src/gui/widgets/dropshortcutcontainer.h b/src/gui/widgets/dropshortcutcontainer.h
new file mode 100644
index 000000000..c072f0613
--- /dev/null
+++ b/src/gui/widgets/dropshortcutcontainer.h
@@ -0,0 +1,88 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DROPSHORTCUTCONTAINER_H
+#define DROPSHORTCUTCONTAINER_H
+
+#include <guichan/mouselistener.hpp>
+
+#include "gui/widgets/shortcutcontainer.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+class Item;
+class ItemPopup;
+
+/**
+ * An item shortcut container. Used to quickly use items.
+ *
+ * \ingroup GUI
+ */
+class DropShortcutContainer : public ShortcutContainer
+{
+ public:
+ /**
+ * Constructor. Initializes the graphic.
+ */
+ DropShortcutContainer();
+
+ /**
+ * Destructor.
+ */
+ virtual ~DropShortcutContainer();
+
+ /**
+ * Draws the items.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Handles mouse when dragged.
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse when pressed.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse release.
+ */
+ void mouseReleased(gcn::MouseEvent &event);
+
+ private:
+ void mouseExited(gcn::MouseEvent &event);
+ void mouseMoved(gcn::MouseEvent &event);
+
+ bool mItemClicked;
+ Item *mItemMoved;
+
+ ItemPopup *mItemPopup;
+};
+
+#endif
diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp
new file mode 100644
index 000000000..a9e435540
--- /dev/null
+++ b/src/gui/widgets/emoteshortcutcontainer.cpp
@@ -0,0 +1,259 @@
+/*
+ * Extended support for activating emotes
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/emoteshortcutcontainer.h"
+
+#include "animatedsprite.h"
+#include "configuration.h"
+#include "emoteshortcut.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/palette.h"
+#include "gui/textpopup.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "resources/emotedb.h"
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+static const int MAX_ITEMS = 42;
+
+EmoteShortcutContainer::EmoteShortcutContainer():
+ ShortcutContainer(),
+ mEmoteClicked(false),
+ mEmoteMoved(0),
+ mEmotePopup(new TextPopup)
+{
+ addMouseListener(this);
+ addWidgetListener(this);
+
+ mBackgroundImg = Theme::getImageFromTheme("item_shortcut_bgr.png");
+
+ if (mBackgroundImg)
+ mBackgroundImg->setAlpha(Client::getGuiAlpha());
+
+ // Setup emote sprites
+ for (int i = 0; i <= EmoteDB::getLast(); i++)
+ {
+ const EmoteSprite* sprite = EmoteDB::getSprite(i, true);
+ if (sprite && sprite->sprite)
+ mEmoteImg.push_back(sprite);
+ }
+
+// mMaxItems = EmoteDB::getLast() < MAX_ITEMS ? EmoteDB::getLast() : MAX_ITEMS;
+ mMaxItems = MAX_ITEMS;
+
+ if (mBackgroundImg)
+ {
+ mBoxHeight = mBackgroundImg->getHeight();
+ mBoxWidth = mBackgroundImg->getWidth();
+ }
+ else
+ {
+ mBoxHeight = 1;
+ mBoxWidth = 1;
+ }
+}
+
+EmoteShortcutContainer::~EmoteShortcutContainer()
+{
+ delete mEmotePopup;
+
+ if (mBackgroundImg)
+ mBackgroundImg->decRef();
+}
+
+void EmoteShortcutContainer::draw(gcn::Graphics *graphics)
+{
+ if (!emoteShortcut)
+ return;
+
+ mAlpha = Client::getGuiAlpha();
+ if (Client::getGuiAlpha() != mAlpha && mBackgroundImg)
+ mBackgroundImg->setAlpha(mAlpha);
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ graphics->setFont(getFont());
+
+ for (unsigned i = 0; i < mMaxItems; i++)
+ {
+ const int emoteX = (i % mGridWidth) * mBoxWidth;
+ const int emoteY = (i / mGridWidth) * mBoxHeight;
+
+ if (mBackgroundImg)
+ g->drawImage(mBackgroundImg, emoteX, emoteY);
+
+ // Draw emote keyboard shortcut.
+ std::string key = keyboard.getKeyValueString(
+ keyboard.KEY_EMOTE_1 + i);
+
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ g->drawText(key, emoteX + 2, emoteY + 2, gcn::Graphics::LEFT);
+
+/*
+ if (emoteShortcut->getEmote(i)
+ && static_cast<unsigned>(emoteShortcut->getEmote(i)) - 1
+ < mEmoteImg.size()
+ && mEmoteImg[emoteShortcut->getEmote(i) - 1])
+ {
+ mEmoteImg[emoteShortcut->getEmote(i) - 1]->draw(g, emoteX + 2,
+ emoteY + 10);
+ }
+*/
+
+ if (i < mEmoteImg.size() && mEmoteImg[i] && mEmoteImg[i]->sprite)
+ mEmoteImg[i]->sprite->draw(g, emoteX + 2, emoteY + 10);
+ }
+
+ if (mEmoteMoved && mEmoteMoved < (unsigned)mEmoteImg.size() + 1
+ && mEmoteMoved > 0)
+ {
+ // Draw the emote image being dragged by the cursor.
+ const EmoteSprite* sprite = mEmoteImg[mEmoteMoved - 1];
+ if (sprite && sprite->sprite)
+ {
+ const AnimatedSprite *spr = sprite->sprite;
+ const int tPosX = mCursorPosX - (spr->getWidth() / 2);
+ const int tPosY = mCursorPosY - (spr->getHeight() / 2);
+
+ spr->draw(g, tPosX, tPosY);
+ }
+ }
+}
+
+void EmoteShortcutContainer::mouseDragged(gcn::MouseEvent &event)
+{
+ if (!emoteShortcut)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (!mEmoteMoved && mEmoteClicked)
+ {
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+// const unsigned char emoteId = emoteShortcut->getEmote(index);
+ const unsigned char emoteId = index + 1;
+
+ if (emoteId)
+ {
+ mEmoteMoved = emoteId;
+ emoteShortcut->removeEmote(index);
+ }
+ }
+ if (mEmoteMoved)
+ {
+ mCursorPosX = event.getX();
+ mCursorPosY = event.getY();
+ }
+ }
+}
+
+void EmoteShortcutContainer::mousePressed(gcn::MouseEvent &event)
+{
+ if (!emoteShortcut)
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ // Stores the selected emote if there is one.
+ if (emoteShortcut->isEmoteSelected())
+ {
+ emoteShortcut->setEmote(index);
+ emoteShortcut->setEmoteSelected(0);
+ }
+ else if (emoteShortcut->getEmote(index))
+ {
+ mEmoteClicked = true;
+ }
+}
+
+void EmoteShortcutContainer::mouseReleased(gcn::MouseEvent &event)
+{
+ if (!emoteShortcut)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (emoteShortcut->isEmoteSelected())
+ emoteShortcut->setEmoteSelected(0);
+
+ if (index == -1)
+ {
+ mEmoteMoved = 0;
+ return;
+ }
+
+ if (mEmoteMoved)
+ {
+ emoteShortcut->setEmotes(index, mEmoteMoved);
+ mEmoteMoved = 0;
+ }
+ else if (emoteShortcut->getEmote(index) && mEmoteClicked)
+ {
+ emoteShortcut->useEmote(index + 1);
+ }
+
+ if (mEmoteClicked)
+ mEmoteClicked = false;
+ }
+}
+
+void EmoteShortcutContainer::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!emoteShortcut || !mEmotePopup)
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ mEmotePopup->setVisible(false);
+
+ if ((unsigned)index < mEmoteImg.size() && mEmoteImg[index])
+ {
+ mEmotePopup->show(viewport->getMouseX(), viewport->getMouseY(),
+ mEmoteImg[index]->name);
+ }
+}
+
+void EmoteShortcutContainer::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ if (mEmotePopup)
+ mEmotePopup->setVisible(false);
+} \ No newline at end of file
diff --git a/src/gui/widgets/emoteshortcutcontainer.h b/src/gui/widgets/emoteshortcutcontainer.h
new file mode 100644
index 000000000..e841e6dfb
--- /dev/null
+++ b/src/gui/widgets/emoteshortcutcontainer.h
@@ -0,0 +1,84 @@
+/*
+ * Extended support for activating emotes
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EMOTESHORTCUTCONTAINER_H
+#define EMOTESHORTCUTCONTAINER_H
+
+#include "gui/widgets/shortcutcontainer.h"
+
+#include "resources/emotedb.h"
+
+#include <vector>
+
+class AnimatedSprite;
+class Image;
+class TextPopup;
+
+/**
+ * An emote shortcut container. Used to quickly use emoticons.
+ *
+ * \ingroup GUI
+ */
+class EmoteShortcutContainer : public ShortcutContainer
+{
+ public:
+ /**
+ * Constructor. Initializes the graphic.
+ */
+ EmoteShortcutContainer();
+
+ /**
+ * Destructor.
+ */
+ virtual ~EmoteShortcutContainer();
+
+ /**
+ * Draws the items.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Handles mouse when dragged.
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse when pressed.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse release.
+ */
+ void mouseReleased(gcn::MouseEvent &event);
+
+ void mouseMoved(gcn::MouseEvent &event);
+
+ void mouseExited(gcn::MouseEvent &event);
+
+ private:
+ std::vector<const EmoteSprite*> mEmoteImg;
+
+ bool mEmoteClicked;
+ unsigned char mEmoteMoved;
+ TextPopup *mEmotePopup;
+};
+
+#endif
diff --git a/src/gui/widgets/flowcontainer.cpp b/src/gui/widgets/flowcontainer.cpp
new file mode 100644
index 000000000..a93818abc
--- /dev/null
+++ b/src/gui/widgets/flowcontainer.cpp
@@ -0,0 +1,88 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "flowcontainer.h"
+
+FlowContainer::FlowContainer(int boxWidth, int boxHeight):
+ mBoxWidth(boxWidth), mBoxHeight(boxHeight),
+ mGridWidth(1), mGridHeight(1)
+{
+ addWidgetListener(this);
+ if (!mBoxWidth)
+ mBoxWidth = 1;
+ if (!mBoxHeight)
+ mBoxHeight = 1;
+}
+
+void FlowContainer::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ if (getWidth() < mBoxWidth)
+ {
+ setWidth(mBoxWidth);
+ return;
+ }
+
+ int itemCount = static_cast<int>(mWidgets.size());
+
+ if (!mBoxWidth)
+ mGridWidth = getWidth();
+ else
+ mGridWidth = getWidth() / mBoxWidth;
+
+ if (mGridWidth < 1)
+ mGridWidth = 1;
+
+ mGridHeight = itemCount / mGridWidth;
+
+ if (itemCount % mGridWidth != 0 || mGridHeight < 1)
+ ++mGridHeight;
+
+ int height = mGridHeight * mBoxHeight;
+
+ if (getHeight() != height)
+ {
+ setHeight(height);
+ return;
+ }
+
+ int i = 0;
+ height = 0;
+ for (WidgetList::iterator it = mWidgets.begin();
+ it != mWidgets.end(); it++)
+ {
+ int x = i % mGridWidth * mBoxWidth;
+ (*it)->setPosition(x, height);
+
+ i++;
+
+ if (i % mGridWidth == 0)
+ height += mBoxHeight;
+ }
+}
+
+void FlowContainer::add(gcn::Widget *widget)
+{
+ if (!widget)
+ return;
+
+ Container::add(widget);
+ widget->setSize(mBoxWidth, mBoxHeight);
+ widgetResized(NULL);
+}
diff --git a/src/gui/widgets/flowcontainer.h b/src/gui/widgets/flowcontainer.h
new file mode 100644
index 000000000..f738be209
--- /dev/null
+++ b/src/gui/widgets/flowcontainer.h
@@ -0,0 +1,73 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef FLOWCONTAINER_H
+#define FLOWCONTAINER_H
+
+#include "container.h"
+
+#include <guichan/widgetlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+/**
+ * A container that arranges its contents like words on a page.
+ *
+ * \ingroup GUI
+ */
+class FlowContainer : public Container,
+ public gcn::WidgetListener
+{
+ public:
+ /**
+ * Constructor. Initializes the shortcut container.
+ */
+ FlowContainer(int boxWidth, int boxHeight);
+
+ /**
+ * Destructor.
+ */
+ ~FlowContainer() {}
+
+ /**
+ * Invoked when a widget changes its size. This is used to determine
+ * the new height of the container.
+ */
+ void widgetResized(const gcn::Event &event);
+
+ int getBoxWidth() const
+ { return mBoxWidth; }
+
+ int getBoxHeight() const
+ { return mBoxHeight; }
+
+ void add(gcn::Widget *widget);
+
+ private:
+ int mBoxWidth;
+ int mBoxHeight;
+ int mGridWidth, mGridHeight;
+};
+
+#endif
diff --git a/src/gui/widgets/icon.cpp b/src/gui/widgets/icon.cpp
new file mode 100644
index 000000000..4e5902128
--- /dev/null
+++ b/src/gui/widgets/icon.cpp
@@ -0,0 +1,60 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/icon.h"
+
+#include "graphics.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+Icon::Icon(const std::string &file)
+ : mImage(0)
+{
+ mImage = ResourceManager::getInstance()->getImage(file);
+ if (mImage)
+ setSize(mImage->getWidth(), mImage->getHeight());
+}
+
+Icon::Icon(Image *image)
+ : mImage(image)
+{
+ if (mImage)
+ setSize(mImage->getWidth(), mImage->getHeight());
+}
+
+void Icon::setImage(Image *image)
+{
+ mImage = image;
+ if (mImage)
+ setSize(mImage->getWidth(), mImage->getHeight());
+}
+
+void Icon::draw(gcn::Graphics *g)
+{
+ if (mImage)
+ {
+ Graphics *graphics = static_cast<Graphics*>(g);
+ const int x = (getWidth() - mImage->getWidth()) / 2;
+ const int y = (getHeight() - mImage->getHeight()) / 2;
+ graphics->drawImage(mImage, x, y);
+ }
+}
diff --git a/src/gui/widgets/icon.h b/src/gui/widgets/icon.h
new file mode 100644
index 000000000..27ed0db8e
--- /dev/null
+++ b/src/gui/widgets/icon.h
@@ -0,0 +1,66 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ICON_H
+#define ICON_H
+
+#include <guichan/widget.hpp>
+
+class Image;
+
+/**
+ * An icon.
+ *
+ * \ingroup GUI
+ */
+class Icon : public gcn::Widget
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Icon(const std::string &filename);
+
+ /**
+ * Constructor, uses an existing Image.
+ */
+ Icon(Image *image);
+
+ /**
+ * Gets the current Image.
+ */
+ Image *getImage() const { return mImage; }
+
+ /**
+ * Sets the image to display.
+ */
+ void setImage(Image *image);
+
+ /**
+ * Draws the Icon.
+ */
+ void draw(gcn::Graphics *g);
+
+ private:
+ Image *mImage;
+};
+
+#endif // ICON_H
diff --git a/src/gui/widgets/inttextfield.cpp b/src/gui/widgets/inttextfield.cpp
new file mode 100644
index 000000000..d0ffaebc5
--- /dev/null
+++ b/src/gui/widgets/inttextfield.cpp
@@ -0,0 +1,112 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/inttextfield.h"
+
+#include "gui/sdlinput.h"
+
+#include "utils/stringutils.h"
+
+IntTextField::IntTextField(int def, int min, int max,
+ bool enabled, int width):
+ TextField(toString(def)),
+ mDefault(def),
+ mValue(def)
+{
+ if (min != 0 || max != 0)
+ setRange(min, max);
+
+ setEnabled(enabled);
+ if (width != 0)
+ setWidth(width);
+}
+
+void IntTextField::keyPressed(gcn::KeyEvent &event)
+{
+ const gcn::Key &key = event.getKey();
+
+ if (key.getValue() == Key::BACKSPACE ||
+ key.getValue() == Key::DELETE)
+ {
+ setText(std::string());
+ event.consume();
+ }
+
+ if (!key.isNumber())
+ return;
+
+ TextField::keyPressed(event);
+
+ std::istringstream s(getText());
+ int i;
+ s >> i;
+ setValue(i);
+}
+
+void IntTextField::setRange(int min, int max)
+{
+ mMin = min;
+ mMax = max;
+
+ if (mValue < mMin)
+ mValue = mMin;
+ else if (mValue > mMax)
+ mValue = mMax;
+
+ if (mDefault < mMin)
+ mDefault = mMin;
+ else if (mDefault > mMax)
+ mDefault = mMax;
+}
+
+int IntTextField::getValue()
+{
+ return getText().empty() ? mMin : mValue;
+}
+
+void IntTextField::setValue(int i)
+{
+ if (i < mMin)
+ mValue = mMin;
+ else if (i > mMax)
+ mValue = mMax;
+ else
+ mValue = i;
+
+ const std::string valStr = toString(mValue);
+ setText(valStr);
+ setCaretPosition(static_cast<unsigned>(valStr.length()) + 1);
+}
+
+void IntTextField::setDefaultValue(int value)
+{
+ if (value < mMin)
+ mDefault = mMin;
+ else if (value > mMax)
+ mDefault = mMax;
+ else
+ mDefault = value;
+}
+
+void IntTextField::reset()
+{
+ setValue(mDefault);
+}
diff --git a/src/gui/widgets/inttextfield.h b/src/gui/widgets/inttextfield.h
new file mode 100644
index 000000000..69c8a74d7
--- /dev/null
+++ b/src/gui/widgets/inttextfield.h
@@ -0,0 +1,76 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef INTTEXTFIELD_H
+#define INTTEXTFIELD_H
+
+#include "textfield.h"
+
+/**
+ * TextBox which only accepts numbers as input.
+ */
+class IntTextField : public TextField
+{
+ public:
+ /**
+ * Constructor, sets default value.
+ */
+ IntTextField(int def = 0, int min = 0, int max = 0,
+ bool enabled = true, int width = 0);
+
+ /**
+ * Sets the minimum and maximum values of the text box.
+ */
+ void setRange(int minimum, int maximum);
+
+ /**
+ * Returns the value in the text box.
+ */
+ int getValue();
+
+ /**
+ * Reset the field to the default value.
+ */
+ void reset();
+
+ /**
+ * Set the value of the text box to the specified value.
+ */
+ void setValue(int value);
+
+ /**
+ * Set the default value of the text box to the specified value.
+ */
+ void setDefaultValue(int value);
+
+ /**
+ * Responds to key presses.
+ */
+ void keyPressed(gcn::KeyEvent &event);
+
+ private:
+ int mMin; /**< Minimum value */
+ int mMax; /**< Maximum value */
+ int mDefault; /**< Default value */
+ int mValue; /**< Current value */
+};
+
+#endif
diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp
new file mode 100644
index 000000000..8b5b1914a
--- /dev/null
+++ b/src/gui/widgets/itemcontainer.cpp
@@ -0,0 +1,475 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/itemcontainer.h"
+
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "dropshortcut.h"
+#include "log.h"
+
+#include "gui/chat.h"
+#include "gui/itempopup.h"
+#include "gui/outfitwindow.h"
+#include "gui/palette.h"
+#include "gui/shopwindow.h"
+#include "gui/shortcutwindow.h"
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "net/net.h"
+#include "net/inventoryhandler.h"
+
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+
+#include "utils/stringutils.h"
+
+#include <guichan/mouseinput.hpp>
+#include <guichan/selectionlistener.hpp>
+
+// TODO: Add support for adding items to the item shortcut window (global
+// itemShortcut).
+
+static const int BOX_WIDTH = 35;
+static const int BOX_HEIGHT = 43;
+
+ItemContainer::ItemContainer(Inventory *inventory, bool forceQuantity):
+ mInventory(inventory),
+ mGridColumns(1),
+ mGridRows(1),
+ mSelectedIndex(-1),
+ mHighlightedIndex(-1),
+ mLastUsedSlot(-1),
+ mSelectionStatus(SEL_NONE),
+ mForceQuantity(forceQuantity),
+ mSwapItems(false),
+ mDescItems(false)
+{
+ mItemPopup = new ItemPopup;
+ setFocusable(true);
+
+ mSelImg = Theme::getImageFromTheme("selection.png");
+ if (!mSelImg)
+ logger->log1("Error: Unable to load selection.png");
+
+ addKeyListener(this);
+ addMouseListener(this);
+ addWidgetListener(this);
+}
+
+ItemContainer::~ItemContainer()
+{
+ if (mSelImg)
+ {
+ mSelImg->decRef();
+ mSelImg = 0;
+ }
+ delete mItemPopup;
+ mItemPopup = 0;
+}
+
+void ItemContainer::logic()
+{
+ gcn::Widget::logic();
+
+ if (!mInventory)
+ return;
+
+ const int lastUsedSlot = mInventory->getLastUsedSlot();
+
+ if (lastUsedSlot != mLastUsedSlot)
+ {
+ mLastUsedSlot = lastUsedSlot;
+ adjustHeight();
+ }
+}
+
+void ItemContainer::draw(gcn::Graphics *graphics)
+{
+ if (!mInventory)
+ return;
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ g->setFont(getFont());
+
+ for (int i = 0; i < mGridColumns; i++)
+ {
+ for (int j = 0; j < mGridRows; j++)
+ {
+ int itemX = i * BOX_WIDTH;
+ int itemY = j * BOX_HEIGHT;
+ int itemIndex = (j * mGridColumns) + i;
+ Item *item = mInventory->getItem(itemIndex);
+
+ if (!item || item->getId() == 0)
+ continue;
+
+ Image *image = item->getImage();
+ if (image)
+ {
+ if (itemIndex == mSelectedIndex)
+ {
+ if (mSelectionStatus == SEL_DRAGGING)
+ {
+ // Reposition the coords to that of the cursor.
+ itemX = mDragPosX - (BOX_WIDTH / 2);
+ itemY = mDragPosY - (BOX_HEIGHT / 2);
+ }
+ else
+ {
+ // Draw selection border image.
+ if (mSelImg)
+ g->drawImage(mSelImg, itemX, itemY);
+ }
+ }
+ image->setAlpha(1.0f); // ensure the image if fully drawn...
+ g->drawImage(image, itemX, itemY);
+ }
+ // Draw item caption
+ std::string caption;
+ if (item->getQuantity() > 1 || mForceQuantity)
+ caption = toString(item->getQuantity());
+ else if (item->isEquipped())
+ caption = "Eq.";
+
+ if (item->isEquipped())
+ g->setColor(Theme::getThemeColor(Theme::ITEM_EQUIPPED));
+ else
+ g->setColor(gcn::Color(0, 0, 0));
+
+ g->drawText(caption, itemX + BOX_WIDTH / 2,
+ itemY + BOX_HEIGHT - 14, gcn::Graphics::CENTER);
+ }
+ }
+
+ // Draw an orange box around the selected item
+ if (isFocused() && mHighlightedIndex != -1 && mGridColumns)
+ {
+ const int itemX = (mHighlightedIndex % mGridColumns) * BOX_WIDTH;
+ const int itemY = (mHighlightedIndex / mGridColumns) * BOX_HEIGHT;
+ g->setColor(gcn::Color(255, 128, 0));
+ g->drawRectangle(gcn::Rectangle(itemX, itemY, BOX_WIDTH, BOX_HEIGHT));
+ }
+}
+
+void ItemContainer::selectNone()
+{
+ setSelectedIndex(-1);
+ mSelectionStatus = SEL_NONE;
+ if (outfitWindow)
+ outfitWindow->setItemSelected(-1);
+ if (shopWindow)
+ shopWindow->setItemSelected(-1);
+}
+
+void ItemContainer::setSelectedIndex(int newIndex)
+{
+ if (mSelectedIndex != newIndex)
+ {
+ mSelectedIndex = newIndex;
+ distributeValueChangedEvent();
+ }
+}
+
+Item *ItemContainer::getSelectedItem() const
+{
+ if (mInventory)
+ return mInventory->getItem(mSelectedIndex);
+ else
+ return 0;
+}
+
+void ItemContainer::distributeValueChangedEvent()
+{
+ SelectionListenerIterator i, i_end;
+
+ for (i = mSelectionListeners.begin(), i_end = mSelectionListeners.end();
+ i != i_end; ++i)
+ {
+ if (*i)
+ {
+ gcn::SelectionEvent event(this);
+ (*i)->valueChanged(event);
+ }
+ }
+}
+
+void ItemContainer::keyPressed(gcn::KeyEvent &event _UNUSED_)
+{
+ /*switch (event.getKey().getValue())
+ {
+ case Key::LEFT:
+ moveHighlight(Left);
+ break;
+ case Key::RIGHT:
+ moveHighlight(Right);
+ break;
+ case Key::UP:
+ moveHighlight(Up);
+ break;
+ case Key::DOWN:
+ moveHighlight(Down);
+ break;
+ case Key::SPACE:
+ keyAction();
+ break;
+ case Key::LEFT_ALT:
+ case Key::RIGHT_ALT:
+ mSwapItems = true;
+ break;
+ case Key::RIGHT_CONTROL:
+ mDescItems = true;
+ break;
+ }*/
+}
+
+void ItemContainer::keyReleased(gcn::KeyEvent &event _UNUSED_)
+{
+ /*switch (event.getKey().getValue())
+ {
+ case Key::LEFT_ALT:
+ case Key::RIGHT_ALT:
+ mSwapItems = false;
+ break;
+ case Key::RIGHT_CONTROL:
+ mDescItems = false;
+ break;
+ }*/
+}
+
+void ItemContainer::mousePressed(gcn::MouseEvent &event)
+{
+ if (!mInventory)
+ return;
+
+ const int button = event.getButton();
+ if (button == gcn::MouseEvent::LEFT || button == gcn::MouseEvent::RIGHT)
+ {
+ const int index = getSlotIndex(event.getX(), event.getY());
+ if (index == Inventory::NO_SLOT_INDEX)
+ return;
+
+ Item *item = mInventory->getItem(index);
+
+ // put item name into chat window
+ if (item && mDescItems && chatWindow)
+ chatWindow->addItemText(item->getInfo().getName());
+
+ if (mSelectedIndex == index)
+ {
+ mSelectionStatus = SEL_DESELECTING;
+ }
+ else if (item && item->getId())
+ {
+ setSelectedIndex(index);
+ mSelectionStatus = SEL_SELECTING;
+
+ int num = itemShortcutWindow->getTabIndex();
+ if (num >= 0 && num < SHORTCUT_TABS)
+ {
+ if (itemShortcut[num])
+ itemShortcut[num]->setItemSelected(item->getId());
+ }
+ if (dropShortcut)
+ dropShortcut->setItemSelected(item->getId());
+ if (item->isEquipment() && outfitWindow)
+ outfitWindow->setItemSelected(item->getId());
+ if (shopWindow)
+ shopWindow->setItemSelected(item->getId());
+ }
+ else
+ {
+ selectNone();
+ }
+ }
+}
+
+void ItemContainer::mouseDragged(gcn::MouseEvent &event)
+{
+ if (mSelectionStatus != SEL_NONE)
+ {
+ mSelectionStatus = SEL_DRAGGING;
+ mDragPosX = event.getX();
+ mDragPosY = event.getY();
+ }
+}
+
+void ItemContainer::mouseReleased(gcn::MouseEvent &event)
+{
+ switch (mSelectionStatus)
+ {
+ case SEL_SELECTING:
+ mSelectionStatus = SEL_SELECTED;
+ return;
+ case SEL_DESELECTING:
+ selectNone();
+ return;
+ case SEL_DRAGGING:
+ mSelectionStatus = SEL_SELECTED;
+ break;
+ default:
+ return;
+ };
+
+ int index = getSlotIndex(event.getX(), event.getY());
+ if (index == Inventory::NO_SLOT_INDEX)
+ return;
+ if (index == mSelectedIndex || mSelectedIndex == -1)
+ return;
+ Net::getInventoryHandler()->moveItem(mSelectedIndex, index);
+ selectNone();
+}
+
+
+// Show ItemTooltip
+void ItemContainer::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!mInventory)
+ return;
+
+ Item *item = mInventory->getItem(getSlotIndex(event.getX(), event.getY()));
+
+ if (item && viewport)
+ {
+ mItemPopup->setItem(item);
+ mItemPopup->position(viewport->getMouseX(), viewport->getMouseY());
+ }
+ else
+ {
+ mItemPopup->setVisible(false);
+ }
+}
+
+// Hide ItemTooltip
+void ItemContainer::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ mItemPopup->setVisible(false);
+}
+
+void ItemContainer::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ mGridColumns = std::max(1, getWidth() / BOX_WIDTH);
+ adjustHeight();
+}
+
+void ItemContainer::adjustHeight()
+{
+ if (!mGridColumns)
+ return;
+
+ mGridRows = (mLastUsedSlot + 1) / mGridColumns;
+ if (mGridRows == 0 || (mLastUsedSlot + 1) % mGridColumns > 0)
+ ++mGridRows;
+
+ setHeight(mGridRows * BOX_HEIGHT);
+}
+
+int ItemContainer::getSlotIndex(int x, int y) const
+{
+ if (x < getWidth() && y < getHeight())
+ return (y / BOX_HEIGHT) * mGridColumns + (x / BOX_WIDTH);
+
+ return Inventory::NO_SLOT_INDEX;
+}
+
+void ItemContainer::keyAction()
+{
+ // If there is no highlight then return.
+ if (mHighlightedIndex == -1)
+ return;
+
+ // If the highlight is on the selected item, then deselect it.
+ if (mHighlightedIndex == mSelectedIndex)
+ {
+ selectNone();
+ }
+ // Check and swap items if necessary.
+ else if (mSwapItems && mSelectedIndex != -1 && mHighlightedIndex != -1)
+ {
+ Net::getInventoryHandler()->moveItem(
+ mSelectedIndex, mHighlightedIndex);
+ setSelectedIndex(mHighlightedIndex);
+ }
+ // If the highlight is on an item then select it.
+ else if (mHighlightedIndex != -1)
+ {
+ setSelectedIndex(mHighlightedIndex);
+ mSelectionStatus = SEL_SELECTED;
+ }
+ // If the highlight is on a blank space then move it.
+ else if (mSelectedIndex != -1)
+ {
+ Net::getInventoryHandler()->moveItem(
+ mSelectedIndex, mHighlightedIndex);
+ selectNone();
+ }
+}
+
+void ItemContainer::moveHighlight(Direction direction)
+{
+ if (mHighlightedIndex == -1)
+ {
+ if (mSelectedIndex != -1)
+ mHighlightedIndex = mSelectedIndex;
+ else
+ mHighlightedIndex = 0;
+ return;
+ }
+
+ switch (direction)
+ {
+ case Left:
+ if (mHighlightedIndex % mGridColumns == 0)
+ mHighlightedIndex += mGridColumns;
+ mHighlightedIndex--;
+ break;
+ case Right:
+ if ((mHighlightedIndex % mGridColumns) ==
+ (mGridColumns - 1))
+ {
+ mHighlightedIndex -= mGridColumns;
+ }
+ mHighlightedIndex++;
+ break;
+ case Up:
+ if (mHighlightedIndex / mGridColumns == 0)
+ mHighlightedIndex += (mGridColumns * mGridRows);
+ mHighlightedIndex -= mGridColumns;
+ break;
+ case Down:
+ if ((mHighlightedIndex / mGridColumns) ==
+ (mGridRows - 1))
+ {
+ mHighlightedIndex -= (mGridColumns * mGridRows);
+ }
+ mHighlightedIndex += mGridColumns;
+ break;
+ default:
+ logger->log("warning moveHighlight unknown direction:"
+ + toString(static_cast<unsigned>(direction)));
+ break;
+ }
+}
diff --git a/src/gui/widgets/itemcontainer.h b/src/gui/widgets/itemcontainer.h
new file mode 100644
index 000000000..8aaa236b4
--- /dev/null
+++ b/src/gui/widgets/itemcontainer.h
@@ -0,0 +1,195 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEMCONTAINER_H
+#define ITEMCONTAINER_H
+
+#include <guichan/keylistener.hpp>
+#include <guichan/mouselistener.hpp>
+#include <guichan/widget.hpp>
+#include <guichan/widgetlistener.hpp>
+
+#include <list>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+class Inventory;
+class Item;
+class ItemPopup;
+
+namespace gcn
+{
+ class SelectionListener;
+}
+
+/**
+ * An item container. Used to show items in inventory and trade dialog.
+ *
+ * \ingroup GUI
+ */
+class ItemContainer : public gcn::Widget,
+ public gcn::KeyListener,
+ public gcn::MouseListener,
+ public gcn::WidgetListener
+{
+ public:
+ /**
+ * Constructor. Initializes the graphic.
+ *
+ * @param inventory
+ * @param gridColumns Amount of columns in grid.
+ * @param gridRows Amount of rows in grid.
+ * @param offset Index offset
+ */
+ ItemContainer(Inventory *inventory, bool forceQuantity = false);
+
+ /**
+ * Destructor.
+ */
+ virtual ~ItemContainer();
+
+ /**
+ * Necessary for checking how full the inventory is.
+ */
+ void logic();
+
+ /**
+ * Draws the items.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ // KeyListener
+ void keyPressed(gcn::KeyEvent &event);
+ void keyReleased(gcn::KeyEvent &event);
+
+ // MouseListener
+ void mousePressed(gcn::MouseEvent &event);
+ void mouseDragged(gcn::MouseEvent &event);
+ void mouseReleased(gcn::MouseEvent &event);
+ void mouseMoved(gcn::MouseEvent &event);
+ void mouseExited(gcn::MouseEvent &event);
+
+ // WidgetListener
+ void widgetResized(const gcn::Event &event);
+
+ /**
+ * Returns the selected item.
+ */
+ Item *getSelectedItem() const;
+
+ /**
+ * Sets selected item to NULL.
+ */
+ void selectNone();
+
+ /**
+ * Adds a listener to the list that's notified each time a change to
+ * the selection occurs.
+ */
+ void addSelectionListener(gcn::SelectionListener *listener)
+ { mSelectionListeners.push_back(listener); }
+
+ /**
+ * Removes a listener from the list that's notified each time a change
+ * to the selection occurs.
+ */
+ void removeSelectionListener(gcn::SelectionListener *listener)
+ { mSelectionListeners.remove(listener); }
+
+ private:
+ enum Direction
+ {
+ Left = 0,
+ Right,
+ Up,
+ Down
+ };
+
+ enum SelectionState
+ {
+ SEL_NONE = 0,
+ SEL_SELECTED,
+ SEL_SELECTING,
+ SEL_DESELECTING,
+ SEL_DRAGGING
+ };
+
+ /**
+ * Execute all the functionality associated with the action key.
+ */
+ void keyAction();
+
+ /**
+ * Moves the highlight in the direction specified.
+ *
+ * @param direction The move direction of the highlighter.
+ */
+ void moveHighlight(Direction direction);
+
+ /**
+ * Sets the currently selected item.
+ */
+ void setSelectedIndex(int index);
+
+ /**
+ * Determine and set the height of the container.
+ */
+ void adjustHeight();
+
+ /**
+ * Sends out selection events to the list of selection listeners.
+ */
+ void distributeValueChangedEvent();
+
+ /**
+ * Gets the slot index based on the cursor position.
+ *
+ * @param x The X coordinate position.
+ * @param y The Y coordinate position.
+ * @return The slot index on success, -1 on failure.
+ */
+ int getSlotIndex(int x, int y) const;
+
+ Inventory *mInventory;
+ int mGridColumns, mGridRows;
+ Image *mSelImg;
+ int mSelectedIndex, mHighlightedIndex;
+ int mLastUsedSlot;
+ SelectionState mSelectionStatus;
+ bool mForceQuantity;
+ bool mSwapItems;
+ bool mDescItems;
+ int mDragPosX, mDragPosY;
+
+ ItemPopup *mItemPopup;
+
+ typedef std::list<gcn::SelectionListener*> SelectionListenerList;
+ typedef SelectionListenerList::iterator SelectionListenerIterator;
+
+ SelectionListenerList mSelectionListeners;
+};
+
+#endif
diff --git a/src/gui/widgets/itemlinkhandler.cpp b/src/gui/widgets/itemlinkhandler.cpp
new file mode 100644
index 000000000..7c0a65bcb
--- /dev/null
+++ b/src/gui/widgets/itemlinkhandler.cpp
@@ -0,0 +1,66 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <sstream>
+#include <string>
+
+#include "item.h"
+
+#include "gui/itempopup.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/itemlinkhandler.h"
+
+#include "resources/itemdb.h"
+
+ItemLinkHandler::ItemLinkHandler()
+{
+ mItemPopup = new ItemPopup;
+}
+
+ItemLinkHandler::~ItemLinkHandler()
+{
+ delete mItemPopup;
+ mItemPopup = 0;
+}
+
+void ItemLinkHandler::handleLink(const std::string &link,
+ gcn::MouseEvent *event _UNUSED_)
+{
+ if (!mItemPopup)
+ return;
+
+ int id = 0;
+ std::stringstream stream;
+ stream << link;
+ stream >> id;
+
+ if (id > 0)
+ {
+ const ItemInfo &itemInfo = ItemDB::get(id);
+ mItemPopup->setItem(itemInfo, true);
+
+ if (mItemPopup->isVisible())
+ mItemPopup->setVisible(false);
+ else if (viewport)
+ mItemPopup->position(viewport->getMouseX(), viewport->getMouseY());
+ }
+}
diff --git a/src/gui/widgets/itemlinkhandler.h b/src/gui/widgets/itemlinkhandler.h
new file mode 100644
index 000000000..57e135fed
--- /dev/null
+++ b/src/gui/widgets/itemlinkhandler.h
@@ -0,0 +1,47 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEM_LINK_HANDLER_H
+#define ITEM_LINK_HANDLER_H
+
+#include "gui/widgets/linkhandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class ItemPopup;
+
+class ItemLinkHandler : public LinkHandler
+{
+ public:
+ ItemLinkHandler();
+ ~ItemLinkHandler();
+ void handleLink(const std::string &link,
+ gcn::MouseEvent *event _UNUSED_);
+
+ private:
+ ItemPopup *mItemPopup;
+};
+
+#endif
diff --git a/src/gui/widgets/itemshortcutcontainer.cpp b/src/gui/widgets/itemshortcutcontainer.cpp
new file mode 100644
index 000000000..2ab4a7e19
--- /dev/null
+++ b/src/gui/widgets/itemshortcutcontainer.cpp
@@ -0,0 +1,375 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/itemshortcutcontainer.h"
+
+#include "configuration.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "spellshortcut.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "spellmanager.h"
+#include "textcommand.h"
+
+#include "gui/inventorywindow.h"
+#include "gui/itempopup.h"
+#include "gui/palette.h"
+#include "gui/spellpopup.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+
+#include "utils/stringutils.h"
+
+ItemShortcutContainer::ItemShortcutContainer(unsigned number):
+ ShortcutContainer(),
+ mItemClicked(false),
+ mItemMoved(NULL),
+ mNumber(number)
+{
+ addMouseListener(this);
+ addWidgetListener(this);
+
+ mItemPopup = new ItemPopup;
+ mSpellPopup = new SpellPopup;
+
+ mBackgroundImg = Theme::getImageFromTheme("item_shortcut_bgr.png");
+ if (itemShortcut[mNumber])
+ mMaxItems = itemShortcut[mNumber]->getItemCount();
+ else
+ mMaxItems = 0;
+
+ if (mBackgroundImg)
+ {
+ mBackgroundImg->setAlpha(Client::getGuiAlpha());
+ mBoxHeight = mBackgroundImg->getHeight();
+ mBoxWidth = mBackgroundImg->getWidth();
+ }
+ else
+ {
+ mBoxHeight = 1;
+ mBoxWidth = 1;
+ }
+}
+
+ItemShortcutContainer::~ItemShortcutContainer()
+{
+ if (mBackgroundImg)
+ {
+ mBackgroundImg->decRef();
+ mBackgroundImg = 0;
+ }
+ delete mItemPopup;
+ mItemPopup = 0;
+ delete mSpellPopup;
+ mSpellPopup = 0;
+}
+
+void ItemShortcutContainer::draw(gcn::Graphics *graphics)
+{
+ if (!itemShortcut[mNumber])
+ return;
+
+ mAlpha = Client::getGuiAlpha();
+ if (Client::getGuiAlpha() != mAlpha)
+ {
+ if (mBackgroundImg)
+ mBackgroundImg->setAlpha(mAlpha);
+ }
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ graphics->setFont(getFont());
+
+ for (unsigned i = 0; i < mMaxItems; i++)
+ {
+ const int itemX = (i % mGridWidth) * mBoxWidth;
+ const int itemY = (i / mGridWidth) * mBoxHeight;
+
+ if (mBackgroundImg)
+ g->drawImage(mBackgroundImg, itemX, itemY);
+
+ // Draw item keyboard shortcut.
+ std::string key = keyboard.getKeyValueString(
+ keyboard.KEY_SHORTCUT_1 + i);
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+
+ g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT);
+
+ int itemId = itemShortcut[mNumber]->getItem(i);
+
+ if (itemId < 0)
+ continue;
+
+ // this is item
+ if (itemId < SPELL_MIN_ID)
+ {
+ if (!PlayerInfo::getInventory())
+ continue;
+
+ Item *item = PlayerInfo::getInventory()->findItem(itemId);
+
+ if (item)
+ {
+ // Draw item icon.
+ Image* image = item->getImage();
+
+ if (image)
+ {
+ std::string caption;
+ if (item->getQuantity() > 1)
+ caption = toString(item->getQuantity());
+ else if (item->isEquipped())
+ caption = "Eq.";
+
+ image->setAlpha(1.0f);
+ g->drawImage(image, itemX, itemY);
+ if (item->isEquipped())
+ {
+ g->setColor(Theme::getThemeColor(
+ Theme::ITEM_EQUIPPED));
+ }
+ else
+ {
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ }
+ g->drawText(caption, itemX + mBoxWidth / 2,
+ itemY + mBoxHeight - 14, gcn::Graphics::CENTER);
+ }
+ }
+ }
+ else if (spellManager) // this is magic shortcut
+ {
+ TextCommand *spell = spellManager->getSpellByItem(itemId);
+ if (spell)
+ {
+ if (!spell->isEmpty())
+ {
+ Image* image = spell->getImage();
+
+ if (image)
+ {
+ image->setAlpha(1.0f);
+ g->drawImage(image, itemX, itemY);
+ }
+ }
+
+ g->drawText(spell->getSymbol(), itemX + 2,
+ itemY + mBoxHeight / 2, gcn::Graphics::LEFT);
+ }
+ }
+
+ }
+
+ if (mItemMoved)
+ {
+ // Draw the item image being dragged by the cursor.
+ Image* image = mItemMoved->getImage();
+ if (image)
+ {
+ const int tPosX = mCursorPosX - (image->getWidth() / 2);
+ const int tPosY = mCursorPosY - (image->getHeight() / 2);
+
+ g->drawImage(image, tPosX, tPosY);
+ g->drawText(toString(mItemMoved->getQuantity()),
+ tPosX + mBoxWidth / 2, tPosY + mBoxHeight - 14,
+ gcn::Graphics::CENTER);
+ }
+ }
+}
+
+void ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event)
+{
+ if (!itemShortcut[mNumber])
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (!mItemMoved && mItemClicked)
+ {
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ const int itemId = itemShortcut[mNumber]->getItem(index);
+
+ if (itemId < 0)
+ return;
+
+ if (itemId < SPELL_MIN_ID)
+ {
+ if (!PlayerInfo::getInventory())
+ return;
+
+ Item *item = PlayerInfo::getInventory()->findItem(itemId);
+
+ if (item)
+ {
+ mItemMoved = item;
+ itemShortcut[mNumber]->removeItem(index);
+ }
+ }
+ else if (spellManager)
+ {
+ TextCommand *spell = spellManager->getSpellByItem(itemId);
+ if (spell)
+ itemShortcut[mNumber]->removeItem(index);
+ }
+ }
+ if (mItemMoved)
+ {
+ mCursorPosX = event.getX();
+ mCursorPosY = event.getY();
+ }
+ }
+}
+
+void ItemShortcutContainer::mousePressed(gcn::MouseEvent &event)
+{
+ if (!itemShortcut[mNumber])
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ // Stores the selected item if theirs one.
+ if (itemShortcut[mNumber]->isItemSelected() &&
+ (inventoryWindow && (inventoryWindow->isVisible() ||
+ itemShortcut[mNumber]->getSelectedItem() >= SPELL_MIN_ID)))
+ {
+ itemShortcut[mNumber]->setItem(index);
+ itemShortcut[mNumber]->setItemSelected(-1);
+ if (spellShortcut)
+ spellShortcut->setItemSelected(-1);
+ }
+ else if (itemShortcut[mNumber]->getItem(index))
+ {
+ mItemClicked = true;
+ }
+ }
+ else if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+// Item *item = PlayerInfo::getInventory()->findItem(id);
+
+ if (viewport && itemShortcut[mNumber])
+ viewport->showItemPopup(itemShortcut[mNumber]->getItem(index));
+ }
+}
+
+void ItemShortcutContainer::mouseReleased(gcn::MouseEvent &event)
+{
+ if (!itemShortcut[mNumber])
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (itemShortcut[mNumber]->isItemSelected())
+ itemShortcut[mNumber]->setItemSelected(-1);
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1)
+ {
+ mItemMoved = NULL;
+ return;
+ }
+ if (mItemMoved)
+ {
+ itemShortcut[mNumber]->setItems(index, mItemMoved->getId());
+ mItemMoved = NULL;
+ }
+ else if (itemShortcut[mNumber]->getItem(index) && mItemClicked)
+ {
+ itemShortcut[mNumber]->useItem(index);
+ }
+
+ if (mItemClicked)
+ mItemClicked = false;
+ }
+}
+
+// Show ItemTooltip
+void ItemShortcutContainer::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!itemShortcut[mNumber])
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ const int itemId = itemShortcut[mNumber]->getItem(index);
+
+ if (itemId < 0)
+ return;
+
+ if (itemId < SPELL_MIN_ID)
+ {
+ mSpellPopup->setVisible(false);
+
+ if (!PlayerInfo::getInventory())
+ return;
+
+ Item *item = PlayerInfo::getInventory()->findItem(itemId);
+
+ if (item && viewport)
+ {
+ mItemPopup->setItem(item);
+ mItemPopup->position(viewport->getMouseX(), viewport->getMouseY());
+ }
+ else
+ {
+ mItemPopup->setVisible(false);
+ }
+ }
+ else if (spellManager)
+ {
+ mItemPopup->setVisible(false);
+ TextCommand *spell = spellManager->getSpellByItem(itemId);
+ if (spell && viewport)
+ {
+ mSpellPopup->setItem(spell);
+ mSpellPopup->view(viewport->getMouseX(), viewport->getMouseY());
+ }
+ else
+ {
+ mSpellPopup->setVisible(false);
+ }
+ }
+}
+
+// Hide ItemTooltip
+void ItemShortcutContainer::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ mItemPopup->setVisible(false);
+ mSpellPopup->setVisible(false);
+}
diff --git a/src/gui/widgets/itemshortcutcontainer.h b/src/gui/widgets/itemshortcutcontainer.h
new file mode 100644
index 000000000..0f7067e38
--- /dev/null
+++ b/src/gui/widgets/itemshortcutcontainer.h
@@ -0,0 +1,93 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEMSHORTCUTCONTAINER_H
+#define ITEMSHORTCUTCONTAINER_H
+
+#include "spellmanager.h"
+
+#include "gui/widgets/shortcutcontainer.h"
+
+#include <guichan/mouselistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+class Item;
+class ItemPopup;
+class SpellPopup;
+
+/**
+ * An item shortcut container. Used to quickly use items.
+ *
+ * \ingroup GUI
+ */
+class ItemShortcutContainer : public ShortcutContainer
+{
+ public:
+ /**
+ * Constructor. Initializes the graphic.
+ */
+ ItemShortcutContainer(unsigned number);
+
+ /**
+ * Destructor.
+ */
+ virtual ~ItemShortcutContainer();
+
+ /**
+ * Draws the items.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Handles mouse when dragged.
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse when pressed.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse release.
+ */
+ void mouseReleased(gcn::MouseEvent &event);
+
+ private:
+ void mouseExited(gcn::MouseEvent &event);
+ void mouseMoved(gcn::MouseEvent &event);
+
+ bool mItemClicked;
+ Item *mItemMoved;
+ unsigned mNumber;
+
+ ItemPopup *mItemPopup;
+ SpellPopup *mSpellPopup;
+};
+
+//extern SpellManager *spellManager;
+#endif
diff --git a/src/gui/widgets/label.cpp b/src/gui/widgets/label.cpp
new file mode 100644
index 000000000..e9b4cb0f6
--- /dev/null
+++ b/src/gui/widgets/label.cpp
@@ -0,0 +1,38 @@
+/*
+ * The Mana Client
+ * Copyright (c) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/label.h"
+
+#include "gui/theme.h"
+
+Label::Label()
+{
+}
+
+Label::Label(const std::string &caption) :
+ gcn::Label(caption)
+{
+ setForegroundColor(Theme::getThemeColor(Theme::TEXT));
+}
+
+void Label::draw(gcn::Graphics *graphics)
+{
+ gcn::Label::draw(static_cast<gcn::Graphics*>(graphics));
+}
diff --git a/src/gui/widgets/label.h b/src/gui/widgets/label.h
new file mode 100644
index 000000000..2dfa254c4
--- /dev/null
+++ b/src/gui/widgets/label.h
@@ -0,0 +1,52 @@
+/*
+ * The Mana Client
+ * Copyright (c) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LABEL_H
+#define LABEL_H
+
+#include <guichan/widgets/label.hpp>
+
+/**
+ * Label widget. Same as the Guichan label but modified to use the palette
+ * system.
+ *
+ * \ingroup GUI
+ */
+class Label : public gcn::Label
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Label();
+
+ /**
+ * Constructor. This version of the constructor sets the label with an
+ * inintialization string.
+ */
+ Label(const std::string &caption);
+
+ /**
+ * Draws the label.
+ */
+ void draw(gcn::Graphics *graphics);
+};
+
+#endif
diff --git a/src/gui/widgets/layout.cpp b/src/gui/widgets/layout.cpp
new file mode 100644
index 000000000..38c6bb471
--- /dev/null
+++ b/src/gui/widgets/layout.cpp
@@ -0,0 +1,362 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/layout.h"
+
+#include "log.h"
+
+#include <cassert>
+
+ContainerPlacer ContainerPlacer::at(int x, int y)
+{
+ return ContainerPlacer(mContainer, &mCell->at(x, y));
+}
+
+LayoutCell &ContainerPlacer::operator()
+ (int x, int y, gcn::Widget *wg, int w, int h)
+{
+ mContainer->add(wg);
+ return mCell->place(wg, x, y, w, h);
+}
+
+LayoutCell::~LayoutCell()
+{
+ if (mType == ARRAY)
+ {
+ delete mArray;
+ mArray = 0;
+ }
+}
+
+LayoutArray &LayoutCell::getArray()
+{
+ assert(mType != WIDGET);
+ if (mType == ARRAY)
+ return *mArray;
+
+ mArray = new LayoutArray;
+ mType = ARRAY;
+ mExtent[0] = 1;
+ mExtent[1] = 1;
+ mPadding = 0;
+ mAlign[0] = FILL;
+ mAlign[1] = FILL;
+ return *mArray;
+}
+
+void LayoutCell::reflow(int nx, int ny, int nw, int nh)
+{
+ assert(mType != NONE);
+ nx += mPadding;
+ ny += mPadding;
+ nw -= 2 * mPadding;
+ nh -= 2 * mPadding;
+ if (mType == ARRAY)
+ mArray->reflow(nx, ny, nw, nh);
+ else
+ mWidget->setDimension(gcn::Rectangle(nx, ny, nw, nh));
+}
+
+void LayoutCell::computeSizes()
+{
+ assert(mType == ARRAY);
+
+ std::vector< std::vector< LayoutCell * > >::iterator
+ i = mArray->mCells.begin();
+
+ while (i != mArray->mCells.end())
+ {
+ std::vector< LayoutCell * >::iterator j = i->begin();
+ while (j != i->end())
+ {
+ LayoutCell *cell = *j;
+ if (cell && cell->mType == ARRAY)
+ cell->computeSizes();
+
+ ++j;
+ }
+ ++i;
+ }
+
+ mSize[0] = mArray->getSize(0);
+ mSize[1] = mArray->getSize(1);
+}
+
+LayoutArray::LayoutArray(): mSpacing(4)
+{
+}
+
+LayoutArray::~LayoutArray()
+{
+ std::vector< std::vector< LayoutCell * > >::iterator i = mCells.begin();
+ while (i != mCells.end())
+ {
+ std::vector< LayoutCell * >::iterator j = i->begin();
+ while (j != i->end())
+ {
+ delete *j;
+ ++j;
+ }
+ ++i;
+ }
+}
+
+LayoutCell &LayoutArray::at(int x, int y, int w, int h)
+{
+ resizeGrid(x + w, y + h);
+ LayoutCell *&cell = mCells[y][x];
+ if (!cell)
+ cell = new LayoutCell;
+ return *cell;
+}
+
+void LayoutArray::resizeGrid(int w, int h)
+{
+ bool extW = w && w > static_cast<int>(mSizes[0].size()),
+ extH = h && h > static_cast<int>(mSizes[1].size());
+
+ if (!extW && !extH)
+ return;
+
+ if (extH)
+ {
+ mSizes[1].resize(h, Layout::AUTO_DEF);
+ mCells.resize(h);
+ if (!extW)
+ w = static_cast<int>(mSizes[0].size());
+ }
+
+ if (extW)
+ mSizes[0].resize(w, Layout::AUTO_DEF);
+
+ std::vector< std::vector< LayoutCell * > >::iterator i = mCells.begin();
+ while (i != mCells.end())
+ {
+ i->resize(w, 0);
+ ++i;
+ }
+}
+
+void LayoutArray::setColWidth(int n, int w)
+{
+ resizeGrid(n + 1, 0);
+ mSizes[0][n] = w;
+}
+
+void LayoutArray::setRowHeight(int n, int h)
+{
+ resizeGrid(0, n + 1);
+ mSizes[1][n] = h;
+}
+
+void LayoutArray::matchColWidth(int n1, int n2)
+{
+ resizeGrid(std::max(n1, n2) + 1, 0);
+ std::vector<int> widths = getSizes(0, Layout::AUTO_DEF);
+ int s = std::max(widths[n1], widths[n2]);
+ mSizes[0][n1] = s;
+ mSizes[0][n2] = s;
+}
+
+void LayoutArray::extend(int x, int y, int w, int h)
+{
+ LayoutCell &cell = at(x, y, w, h);
+ cell.mExtent[0] = w;
+ cell.mExtent[1] = h;
+}
+
+LayoutCell &LayoutArray::place(gcn::Widget *widget, int x, int y, int w, int h)
+{
+ LayoutCell &cell = at(x, y, w, h);
+ assert(cell.mType == LayoutCell::NONE);
+ cell.mType = LayoutCell::WIDGET;
+ cell.mWidget = widget;
+ if (widget)
+ {
+ cell.mSize[0] = w == 1 ? widget->getWidth() : 0;
+ cell.mSize[1] = h == 1 ? widget->getHeight() : 0;
+ }
+ else
+ {
+ cell.mSize[0] = 1;
+ cell.mSize[1] = 1;
+ }
+ cell.mExtent[0] = w;
+ cell.mExtent[1] = h;
+ cell.mPadding = 0;
+ cell.mAlign[0] = LayoutCell::FILL;
+ cell.mAlign[1] = LayoutCell::FILL;
+ int &cs = mSizes[0][x], &rs = mSizes[1][y];
+ if (cs == Layout::AUTO_DEF && w == 1)
+ cs = 0;
+ if (rs == Layout::AUTO_DEF && h == 1)
+ rs = 0;
+ return cell;
+}
+
+void LayoutArray::align(int &pos, int &size, int dim,
+ LayoutCell const &cell, int *sizes) const
+{
+ int size_max = sizes[0];
+ for (int i = 1; i < cell.mExtent[dim]; ++i)
+ size_max += sizes[i] + mSpacing;
+ size = std::min<int>(cell.mSize[dim], size_max);
+
+ switch (cell.mAlign[dim])
+ {
+ case LayoutCell::LEFT:
+ return;
+ case LayoutCell::RIGHT:
+ pos += size_max - size;
+ return;
+ case LayoutCell::CENTER:
+ pos += (size_max - size) / 2;
+ return;
+ case LayoutCell::FILL:
+ size = size_max;
+ return;
+ default:
+ logger->log1("LayoutArray::align unknown layout");
+ return;
+ }
+}
+
+std::vector<int> LayoutArray::getSizes(int dim, int upp) const
+{
+ int gridW = static_cast<int>(mSizes[0].size()),
+ gridH = static_cast<int>(mSizes[1].size());
+ std::vector<int> sizes = mSizes[dim];
+
+ // Compute minimum sizes.
+ for (int gridY = 0; gridY < gridH; ++gridY)
+ {
+ for (int gridX = 0; gridX < gridW; ++gridX)
+ {
+ LayoutCell const *cell = mCells[gridY][gridX];
+ if (!cell || cell->mType == LayoutCell::NONE)
+ continue;
+
+ if (cell->mExtent[dim] == 1)
+ {
+ int n = (dim == 0 ? gridX : gridY);
+ int s = cell->mSize[dim] + cell->mPadding * 2;
+ if (s > sizes[n]) sizes[n] = s;
+ }
+ }
+ }
+
+ if (upp == Layout::AUTO_DEF) return sizes;
+
+ // Compute the FILL sizes.
+ int nb = static_cast<int>(sizes.size());
+ int nbFill = 0;
+ for (int i = 0; i < nb; ++i)
+ {
+ if (mSizes[dim][i] <= Layout::AUTO_DEF)
+ {
+ ++nbFill;
+ if (mSizes[dim][i] == Layout::AUTO_SET ||
+ sizes[i] <= Layout::AUTO_DEF)
+ {
+ sizes[i] = 0;
+ }
+ }
+ upp -= sizes[i] + mSpacing;
+ }
+ upp = upp + mSpacing;
+
+ if (nbFill == 0)
+ return sizes;
+
+ for (int i = 0; i < nb; ++i)
+ {
+ if (mSizes[dim][i] > Layout::AUTO_DEF)
+ continue;
+
+ int s = upp / nbFill;
+ sizes[i] += s;
+ upp -= s;
+ --nbFill;
+ }
+
+ return sizes;
+}
+
+int LayoutArray::getSize(int dim) const
+{
+ std::vector<int> sizes = getSizes(dim, Layout::AUTO_DEF);
+ int size = 0;
+ int nb = static_cast<int>(sizes.size());
+ for (int i = 0; i < nb; ++i)
+ {
+ if (sizes[i] > Layout::AUTO_DEF)
+ size += sizes[i];
+ size += mSpacing;
+ }
+ return size - mSpacing;
+}
+
+void LayoutArray::reflow(int nx, int ny, int nw, int nh)
+{
+ int gridW = static_cast<int>(mSizes[0].size()),
+ gridH = static_cast<int>(mSizes[1].size());
+
+ std::vector<int> widths = getSizes(0, nw);
+ std::vector<int> heights = getSizes(1, nh);
+
+ int y = ny;
+ for (int gridY = 0; gridY < gridH; ++gridY)
+ {
+ int x = nx;
+ for (int gridX = 0; gridX < gridW; ++gridX)
+ {
+ LayoutCell *cell = mCells[gridY][gridX];
+ if (cell && cell->mType != LayoutCell::NONE)
+ {
+ int dx = x, dy = y, dw, dh;
+ align(dx, dw, 0, *cell, &widths[gridX]);
+ align(dy, dh, 1, *cell, &heights[gridY]);
+ cell->reflow(dx, dy, dw, dh);
+ }
+ x += widths[gridX] + mSpacing;
+ }
+ y += heights[gridY] + mSpacing;
+ }
+}
+
+Layout::Layout(): mComputed(false)
+{
+ getArray();
+ setPadding(6);
+}
+
+void Layout::reflow(int &nw, int &nh)
+{
+ if (!mComputed)
+ {
+ computeSizes();
+ mComputed = true;
+ }
+
+ nw = (nw == 0 ? mSize[0] + 2 * mPadding : nw);
+ nh = (nh == 0 ? mSize[1] + 2 * mPadding : nh);
+ LayoutCell::reflow(0, 0, nw, nh);
+}
diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h
new file mode 100644
index 000000000..4c1e40bb9
--- /dev/null
+++ b/src/gui/widgets/layout.h
@@ -0,0 +1,319 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WIDGET_LAYOUT_H
+#define WIDGET_LAYOUT_H
+
+#include <guichan/widgets/container.hpp>
+
+#include <vector>
+
+class LayoutCell;
+
+/**
+ * This class is a helper for adding widgets to nested tables in a window.
+ */
+class ContainerPlacer
+{
+ public:
+ ContainerPlacer(gcn::Container *c = NULL, LayoutCell *l = NULL):
+ mContainer(c), mCell(l)
+ {}
+
+ /**
+ * Gets the pointed cell.
+ */
+ LayoutCell &getCell()
+ { return *mCell; }
+
+ /**
+ * Returns a placer for the same container but to an inner cell.
+ */
+ ContainerPlacer at(int x, int y);
+
+ /**
+ * Adds the given widget to the container and places it in the layout.
+ * @see LayoutArray::place
+ */
+ LayoutCell &operator()
+ (int x, int y, gcn::Widget *, int w = 1, int h = 1);
+
+ private:
+ gcn::Container *mContainer;
+ LayoutCell *mCell;
+};
+
+/**
+ * This class contains a rectangular array of cells.
+ */
+class LayoutArray
+{
+ friend class LayoutCell;
+
+ public:
+
+ LayoutArray();
+
+ ~LayoutArray();
+
+ /**
+ * Returns a reference on the cell at given position.
+ */
+ LayoutCell &at(int x, int y, int w = 1, int h = 1);
+
+ /**
+ * Places a widget in a given cell.
+ * @param w number of columns the widget spawns.
+ * @param h number of rows the widget spawns.
+ * @note When @a w is 1, the width of column @a x is reset to zero if
+ * it was AUTO_DEF. Similarly for @a h.
+ */
+ LayoutCell &place(gcn::Widget *, int x, int y, int w = 1, int h = 1);
+
+ /**
+ * Sets the minimum width of a column.
+ */
+ void setColWidth(int n, int w);
+
+ /**
+ * Sets the minimum height of a row.
+ */
+ void setRowHeight(int n, int h);
+
+ /**
+ * Sets the widths of two columns to the maximum of their widths.
+ */
+ void matchColWidth(int n1, int n2);
+
+ /**
+ * Spawns a cell over several columns/rows.
+ */
+ void extend(int x, int y, int w, int h);
+
+ /**
+ * Computes and sets the positions of all the widgets.
+ * @param nW width of the array, used to resize the AUTO_ columns.
+ * @param nH height of the array, used to resize the AUTO_ rows.
+ */
+ void reflow(int nX, int nY, int nW, int nH);
+
+ private:
+
+ // Copy not allowed, as the array owns all its cells.
+ LayoutArray(LayoutArray const &);
+ LayoutArray &operator=(LayoutArray const &);
+
+ /**
+ * Gets the position and size of a widget along a given axis
+ */
+ void align(int &pos, int &size, int dim,
+ LayoutCell const &cell, int *sizes) const;
+
+ /**
+ * Ensures the private vectors are large enough.
+ */
+ void resizeGrid(int w, int h);
+
+ /**
+ * Gets the column/row sizes along a given axis.
+ * @param upp target size for the array. Ignored if AUTO_DEF.
+ */
+ std::vector<int> getSizes(int dim, int upp) const;
+
+ /**
+ * Gets the total size along a given axis.
+ */
+ int getSize(int dim) const;
+
+ std::vector<int> mSizes[2];
+ std::vector< std::vector < LayoutCell * > > mCells;
+
+ int mSpacing;
+};
+
+/**
+ * This class describes the formatting of a widget in the cell of a layout
+ * table. Horizontally, a widget can either fill the width of the cell (minus
+ * the cell padding), or it can retain its size and be flushed left, or flush
+ * right, or centered in the cell. The process is similar for the vertical
+ * alignment, except that top is represented by LEFT and bottom by RIGHT.
+ */
+class LayoutCell
+{
+ friend class Layout;
+ friend class LayoutArray;
+
+ public:
+ enum Alignment
+ {
+ LEFT = 0,
+ RIGHT,
+ CENTER,
+ FILL
+ };
+
+ LayoutCell(): mType(NONE) {}
+
+ ~LayoutCell();
+
+ /**
+ * Sets the padding around the cell content.
+ */
+ LayoutCell &setPadding(int p)
+ { mPadding = p; return *this; }
+
+ /**
+ * Sets the horizontal alignment of the cell content.
+ */
+ LayoutCell &setHAlign(Alignment a)
+ { mAlign[0] = a; return *this; }
+
+ /**
+ * Sets the vertical alignment of the cell content.
+ */
+ LayoutCell &setVAlign(Alignment a)
+ { mAlign[1] = a; return *this; }
+
+ /**
+ * @see LayoutArray::at
+ */
+ LayoutCell &at(int x, int y)
+ { return getArray().at(x, y); }
+
+ /**
+ * @see LayoutArray::place
+ */
+ LayoutCell &place(gcn::Widget *wg, int x, int y, int w = 1, int h = 1)
+ { return getArray().place(wg, x, y, w, h); }
+
+ /**
+ * @see LayoutArray::matchColWidth
+ */
+ void matchColWidth(int n1, int n2)
+ { getArray().matchColWidth(n1, n2); }
+
+ /**
+ * @see LayoutArray::setColWidth
+ */
+ void setColWidth(int n, int w)
+ { getArray().setColWidth(n, w); }
+
+ /**
+ * @see LayoutArray::setRowHeight
+ */
+ void setRowHeight(int n, int h)
+ { getArray().setRowHeight(n, h); }
+
+ /**
+ * @see LayoutArray::extend.
+ */
+ void extend(int x, int y, int w, int h)
+ { getArray().extend(x, y, w, h); }
+
+ /**
+ * Sets the minimum widths and heights of this cell and of all the
+ * inner cells.
+ */
+ void computeSizes();
+
+ private:
+ // Copy not allowed, as the cell may own an array.
+ LayoutCell(LayoutCell const &);
+ LayoutCell &operator=(LayoutCell const &);
+
+ union
+ {
+ gcn::Widget *mWidget;
+ LayoutArray *mArray;
+ };
+
+ enum
+ {
+ NONE = 0,
+ WIDGET,
+ ARRAY
+ };
+
+ /**
+ * Returns the embedded array. Creates it if the cell does not contain
+ * anything yet. Aborts if it contains a widget.
+ */
+ LayoutArray &getArray();
+
+ /**
+ * @see LayoutArray::reflow
+ */
+ void reflow(int nx, int ny, int nw, int nh);
+
+ int mSize[2];
+ int mPadding;
+ int mExtent[2];
+ int mAlign[2];
+ int mNbFill[2];
+ int mType;
+};
+
+/**
+ * This class is an helper for setting the position of widgets. They are
+ * positioned along the cells of some rectangular tables. The layout may either
+ * be a single table or a tree of nested tables.
+ *
+ * The size of a given table column can either be set manually or be chosen
+ * from the widest widget of the column. An empty column has a AUTO_DEF width,
+ * which means it will be extended so that the layout fits its minimum width.
+ *
+ * The process is similar for table rows. By default, there is a spacing of 4
+ * pixels between rows and between columns, and a margin of 6 pixels around the
+ * whole layout.
+ */
+class Layout : public LayoutCell
+{
+ public:
+ Layout();
+
+ /**
+ * Sets the margin around the layout.
+ */
+ void setMargin(int m)
+ { setPadding(m); }
+
+ /**
+ * Sets the positions of all the widgets.
+ * @see LayoutArray::reflow
+ */
+ void reflow(int &nW, int &nH);
+
+ /**
+ * When the minimum size of the layout is less than the available size,
+ * the remaining pixels are equally split amongst the FILL items.
+ */
+ enum
+ {
+ AUTO_DEF = -42, /**< Default value, behaves like AUTO_ADD. */
+ AUTO_SET = -43, /**< Uses the share as the new size. */
+ AUTO_ADD = -44 /**< Adds the share to the current size. */
+ };
+
+ private:
+ bool mComputed;
+};
+
+#endif // WIDGET_LAYOUT_H
diff --git a/src/gui/widgets/layouthelper.cpp b/src/gui/widgets/layouthelper.cpp
new file mode 100644
index 000000000..a12de9bff
--- /dev/null
+++ b/src/gui/widgets/layouthelper.cpp
@@ -0,0 +1,63 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/layouthelper.h"
+
+LayoutHelper::LayoutHelper(gcn::Container *container):
+ mContainer(container)
+{
+ mContainer->addWidgetListener(this);
+}
+
+LayoutHelper::~LayoutHelper()
+{
+ mContainer->removeWidgetListener(this);
+}
+
+Layout &LayoutHelper::getLayout()
+{
+ return mLayout;
+}
+
+LayoutCell &LayoutHelper::place(int x, int y, gcn::Widget *wg, int w, int h)
+{
+ mContainer->add(wg);
+ return mLayout.place(wg, x, y, w, h);
+}
+
+ContainerPlacer LayoutHelper::getPlacer(int x, int y)
+{
+ return ContainerPlacer(mContainer, &mLayout.at(x, y));
+}
+
+void LayoutHelper::reflowLayout(int w, int h)
+{
+ mLayout.reflow(w, h);
+ mContainer->setSize(w, h);
+}
+
+void LayoutHelper::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ const gcn::Rectangle area = mContainer->getChildrenArea();
+ int w = area.width;
+ int h = area.height;
+ mLayout.reflow(w, h);
+}
diff --git a/src/gui/widgets/layouthelper.h b/src/gui/widgets/layouthelper.h
new file mode 100644
index 000000000..033457429
--- /dev/null
+++ b/src/gui/widgets/layouthelper.h
@@ -0,0 +1,90 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LAYOUTHELPER_H
+#define LAYOUTHELPER_H
+
+#include "gui/widgets/layout.h"
+
+#include <guichan/widgetlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+/**
+ * A helper class for adding a layout to a Guichan container widget. The layout
+ * will register itself as a widget listener and relayout the widgets in the
+ * container dynamically on resize.
+ */
+class LayoutHelper : public gcn::WidgetListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ LayoutHelper(gcn::Container *container);
+
+ /**
+ * Destructor.
+ */
+ ~LayoutHelper();
+
+ /**
+ * Gets the layout handler.
+ */
+ Layout &getLayout();
+
+ /**
+ * Computes the position of the widgets according to the current
+ * layout. Resizes the managed container so that the layout fits.
+ *
+ * @note This function is meant to be called with fixed-size
+ * containers.
+ *
+ * @param w if non-zero, force the container to this width.
+ * @param h if non-zero, force the container to this height.
+ */
+ void reflowLayout(int w = 0, int h = 0);
+
+ /**
+ * Adds a widget to the container and sets it at given cell.
+ */
+ LayoutCell &place(int x, int y, gcn::Widget *, int w = 1, int h = 1);
+
+ /**
+ * Returns a proxy for adding widgets in an inner table of the layout.
+ */
+ ContainerPlacer getPlacer(int x, int y);
+
+ /**
+ * Called whenever the managed container changes size.
+ */
+ void widgetResized(const gcn::Event &event);
+
+ private:
+ Layout mLayout; /**< Layout handler */
+ gcn::Container *mContainer; /**< Managed container */
+};
+
+#endif // LAYOUTHELPER_H
diff --git a/src/gui/widgets/linkhandler.h b/src/gui/widgets/linkhandler.h
new file mode 100644
index 000000000..d9d0f1161
--- /dev/null
+++ b/src/gui/widgets/linkhandler.h
@@ -0,0 +1,42 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LINK_HANDLER_H
+#define LINK_HANDLER_H
+
+#include <string>
+
+#include <guichan/mouselistener.hpp>
+
+/**
+ * A simple interface to windows that need to handle links from BrowserBox
+ * widget.
+ */
+class LinkHandler
+{
+ public:
+ virtual ~LinkHandler() { }
+
+ virtual void handleLink(const std::string &link,
+ gcn::MouseEvent *event) = 0;
+};
+
+#endif
diff --git a/src/gui/widgets/listbox.cpp b/src/gui/widgets/listbox.cpp
new file mode 100644
index 000000000..8dcc4ae67
--- /dev/null
+++ b/src/gui/widgets/listbox.cpp
@@ -0,0 +1,146 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/listbox.h"
+
+#include "client.h"
+#include "configuration.h"
+
+#include "gui/palette.h"
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+
+#include <guichan/font.hpp>
+#include <guichan/graphics.hpp>
+#include <guichan/key.hpp>
+#include <guichan/listmodel.hpp>
+
+float ListBox::mAlpha = 1.0;
+
+ListBox::ListBox(gcn::ListModel *listModel):
+ gcn::ListBox(listModel)
+{
+}
+
+ListBox::~ListBox()
+{
+}
+
+void ListBox::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (mAlpha != alpha)
+ mAlpha = alpha;
+}
+
+void ListBox::draw(gcn::Graphics *graphics)
+{
+ if (!mListModel)
+ return;
+
+ updateAlpha();
+
+ graphics->setColor(Theme::getThemeColor(Theme::HIGHLIGHT,
+ static_cast<int>(mAlpha * 255.0f)));
+ graphics->setFont(getFont());
+
+ const int height = getRowHeight();
+
+ // Draw filled rectangle around the selected list element
+ if (mSelected >= 0)
+ {
+ graphics->fillRectangle(gcn::Rectangle(0, height * mSelected,
+ getWidth(), height));
+ }
+
+ // Draw the list elements
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ for (int i = 0, y = 0; i < mListModel->getNumberOfElements();
+ ++i, y += height)
+ {
+ graphics->drawText(mListModel->getElementAt(i), 1, y);
+ }
+}
+
+void ListBox::keyPressed(gcn::KeyEvent& keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ENTER || key.getValue() == Key::SPACE)
+ {
+ distributeActionEvent();
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::UP)
+ {
+ if (getSelected() > 0)
+ setSelected(mSelected - 1);
+ else if (getSelected() == 0 && mWrappingEnabled && getListModel())
+ setSelected(getListModel()->getNumberOfElements() - 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::DOWN)
+ {
+ if (getSelected() < (getListModel()->getNumberOfElements() - 1))
+ {
+ setSelected(mSelected + 1);
+ }
+ else if (getSelected() == (getListModel()->getNumberOfElements() - 1)
+ && mWrappingEnabled)
+ {
+ setSelected(0);
+ }
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::HOME)
+ {
+ setSelected(0);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::END && getListModel())
+ {
+ setSelected(getListModel()->getNumberOfElements() - 1);
+ keyEvent.consume();
+ }
+}
+
+// Don't do anything on scrollwheel. ScrollArea will deal with that.
+
+void ListBox::mouseWheelMovedUp(gcn::MouseEvent &mouseEvent _UNUSED_)
+{
+}
+
+void ListBox::mouseWheelMovedDown(gcn::MouseEvent &mouseEvent _UNUSED_)
+{
+}
+
+void ListBox::mouseDragged(gcn::MouseEvent &event)
+{
+ if (event.getButton() != gcn::MouseEvent::LEFT || getRowHeight() == 0)
+ return;
+
+ // Make list selection update on drag, but guard against negative y
+ int y = std::max(0, event.getY());
+ if (getRowHeight())
+ setSelected(y / getRowHeight());
+}
diff --git a/src/gui/widgets/listbox.h b/src/gui/widgets/listbox.h
new file mode 100644
index 000000000..721e1bd36
--- /dev/null
+++ b/src/gui/widgets/listbox.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LISTBOX_H
+#define LISTBOX_H
+
+#include <guichan/widgets/listbox.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class SelectionListener;
+
+/**
+ * A list box, meant to be used inside a scroll area. Same as the Guichan list
+ * box except this one doesn't have a background, instead completely relying
+ * on the scroll area. It also adds selection listener functionality.
+ *
+ * \ingroup GUI
+ */
+class ListBox : public gcn::ListBox
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ListBox(gcn::ListModel *listModel);
+
+ ~ListBox();
+
+ /**
+ * Draws the list box.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Update the alpha value to the graphic components.
+ */
+ void updateAlpha();
+
+ // Inherited from KeyListener
+
+ void keyPressed(gcn::KeyEvent& keyEvent);
+
+ // Inherited from MouseListener
+
+ void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent);
+
+ void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent);
+
+ void mouseDragged(gcn::MouseEvent &event);
+
+ protected:
+ static float mAlpha;
+};
+
+#endif
diff --git a/src/gui/widgets/passwordfield.cpp b/src/gui/widgets/passwordfield.cpp
new file mode 100644
index 000000000..14b924bbd
--- /dev/null
+++ b/src/gui/widgets/passwordfield.cpp
@@ -0,0 +1,36 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "passwordfield.h"
+
+PasswordField::PasswordField(const std::string &text):
+ TextField(text)
+{
+}
+
+void PasswordField::draw(gcn::Graphics *graphics)
+{
+ // std::string uses cow, thus cheap copy
+ const std::string original = mText;
+ mText.assign(mText.length(), '*');
+ TextField::draw(graphics);
+ mText = original;
+}
diff --git a/src/gui/widgets/passwordfield.h b/src/gui/widgets/passwordfield.h
new file mode 100644
index 000000000..619cd8420
--- /dev/null
+++ b/src/gui/widgets/passwordfield.h
@@ -0,0 +1,46 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PASSWORDFIELD_H
+#define PASSWORDFIELD_H
+
+#include "textfield.h"
+
+/**
+ * A password field.
+ *
+ * \ingroup GUI
+ */
+class PasswordField : public TextField
+{
+ public:
+ /**
+ * Constructor, initializes the password field with the given string.
+ */
+ PasswordField(const std::string &text = "");
+
+ /**
+ * Draws the password field.
+ */
+ void draw(gcn::Graphics *graphics);
+};
+
+#endif
diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp
new file mode 100644
index 000000000..e3a660120
--- /dev/null
+++ b/src/gui/widgets/playerbox.cpp
@@ -0,0 +1,120 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/playerbox.h"
+
+#include "animatedsprite.h"
+#include "being.h"
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+int PlayerBox::instances = 0;
+float PlayerBox::mAlpha = 1.0;
+ImageRect PlayerBox::background;
+
+PlayerBox::PlayerBox(const Being *being):
+ mBeing(being)
+{
+ setFrameSize(2);
+
+ if (instances == 0)
+ {
+ // Load the background skin
+ Image *textbox = Theme::getImageFromTheme("deepbox.png");
+ int bggridx[4] = {0, 3, 28, 31};
+ int bggridy[4] = {0, 3, 28, 31};
+ int a = 0, x, y;
+
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ if (textbox)
+ {
+ background.grid[a] = textbox->getSubImage(
+ bggridx[x], bggridy[y],
+ bggridx[x + 1] - bggridx[x] + 1,
+ bggridy[y + 1] - bggridy[y] + 1);
+ if (background.grid[a])
+ background.grid[a]->setAlpha(Client::getGuiAlpha());
+ }
+ else
+ {
+ background.grid[a] = 0;
+ }
+ a++;
+ }
+ }
+
+ if (textbox)
+ textbox->decRef();
+ }
+
+ instances++;
+}
+
+PlayerBox::~PlayerBox()
+{
+ instances--;
+
+ mBeing = 0;
+
+ if (instances == 0)
+ for_each(background.grid, background.grid + 9, dtor<Image*>());
+}
+
+void PlayerBox::draw(gcn::Graphics *graphics)
+{
+ if (mBeing)
+ {
+ // Draw character
+ const int bs = getFrameSize();
+ const int x = getWidth() / 2 + bs - 16;
+ const int y = getHeight() - bs - 32;
+ mBeing->drawSpriteAt(static_cast<Graphics*>(graphics), x, y);
+ }
+
+ if (Client::getGuiAlpha() != mAlpha)
+ {
+ for (int a = 0; a < 9; a++)
+ {
+ if (background.grid[a])
+ background.grid[a]->setAlpha(Client::getGuiAlpha());
+ }
+ }
+}
+
+void PlayerBox::drawFrame(gcn::Graphics *graphics)
+{
+ int w, h, bs;
+ bs = getFrameSize();
+ w = getWidth() + bs * 2;
+ h = getHeight() + bs * 2;
+
+ static_cast<Graphics*>(graphics)->drawImageRect(0, 0, w, h, background);
+}
diff --git a/src/gui/widgets/playerbox.h b/src/gui/widgets/playerbox.h
new file mode 100644
index 000000000..4505367f8
--- /dev/null
+++ b/src/gui/widgets/playerbox.h
@@ -0,0 +1,74 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PLAYERBOX_H
+#define PLAYERBOX_H
+
+#include <guichan/widgets/scrollarea.hpp>
+
+class Being;
+class ImageRect;
+
+/**
+ * A box showing a player character.
+ *
+ * \ingroup GUI
+ */
+class PlayerBox : public gcn::ScrollArea
+{
+ public:
+ /**
+ * Constructor. Takes the initial player character that this box should
+ * display, which defaults to <code>NULL</code>.
+ */
+ PlayerBox(const Being *being = 0);
+
+ /**
+ * Destructor.
+ */
+ ~PlayerBox();
+
+ /**
+ * Sets a new player character to be displayed by this box. Setting the
+ * player to <code>NULL</code> causes the box not to draw any
+ * character.
+ */
+ void setPlayer(const Being *being) { mBeing = being; }
+
+ /**
+ * Draws the scroll area.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Draws the background and border of the scroll area.
+ */
+ void drawFrame(gcn::Graphics *graphics);
+
+ private:
+ const Being *mBeing; /**< The character used for display */
+
+ static float mAlpha;
+ static int instances;
+ static ImageRect background;
+};
+
+#endif
diff --git a/src/gui/widgets/popup.cpp b/src/gui/widgets/popup.cpp
new file mode 100644
index 000000000..fa955c8f3
--- /dev/null
+++ b/src/gui/widgets/popup.cpp
@@ -0,0 +1,174 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/popup.h"
+
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/windowcontainer.h"
+
+#include "resources/image.h"
+
+#include <guichan/exception.hpp>
+
+Popup::Popup(const std::string &name, const std::string &skin):
+ mPopupName(name),
+ mMinWidth(100),
+ mMinHeight(40),
+ mMaxWidth(graphics->getWidth()),
+ mMaxHeight(graphics->getHeight())
+{
+ logger->log("Popup::Popup(\"%s\")", name.c_str());
+
+ if (!windowContainer)
+ throw GCN_EXCEPTION("Popup::Popup(): no windowContainer set");
+
+ setPadding(3);
+
+ // Loads the skin
+ mSkin = Theme::instance()->load(skin);
+
+ // Add this window to the window container
+ windowContainer->add(this);
+
+ // Popups are invisible by default
+ setVisible(false);
+}
+
+Popup::~Popup()
+{
+ logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str());
+
+ if (mSkin)
+ mSkin->instances--;
+}
+
+void Popup::setWindowContainer(WindowContainer *wc)
+{
+ windowContainer = wc;
+}
+
+void Popup::draw(gcn::Graphics *graphics)
+{
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder());
+
+ drawChildren(graphics);
+}
+
+gcn::Rectangle Popup::getChildrenArea()
+{
+ return gcn::Rectangle(getPadding(), 0, getWidth() - getPadding() * 2,
+ getHeight() - getPadding() * 2);
+}
+
+void Popup::setContentSize(int width, int height)
+{
+ width += 2 * getPadding();
+ height += 2 * getPadding();
+
+ if (getMinWidth() > width)
+ width = getMinWidth();
+ else if (getMaxWidth() < width)
+ width = getMaxWidth();
+ if (getMinHeight() > height)
+ height = getMinHeight();
+ else if (getMaxHeight() < height)
+ height = getMaxHeight();
+
+ setSize(width, height);
+}
+
+void Popup::setLocationRelativeTo(gcn::Widget *widget)
+{
+ if (!widget)
+ return;
+
+ int wx, wy;
+ int x, y;
+
+ widget->getAbsolutePosition(wx, wy);
+ getAbsolutePosition(x, y);
+
+ setPosition(getX() + (wx + (widget->getWidth() - getWidth()) / 2 - x),
+ getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y));
+}
+
+void Popup::setMinWidth(int width)
+{
+ mMinWidth = width > mSkin->getMinWidth() ? width : mSkin->getMinWidth();
+}
+
+void Popup::setMinHeight(int height)
+{
+ mMinHeight = height > mSkin->getMinHeight() ?
+ height : mSkin->getMinHeight();
+}
+
+void Popup::setMaxWidth(int width)
+{
+ mMaxWidth = width;
+}
+
+void Popup::setMaxHeight(int height)
+{
+ mMaxHeight = height;
+}
+
+void Popup::scheduleDelete()
+{
+ windowContainer->scheduleDelete(this);
+}
+
+void Popup::position(int x, int y)
+{
+ const int distance = 20;
+
+ int posX = std::max(0, x - getWidth() / 2);
+ int posY = y + distance;
+
+ if (posX + getWidth() > graphics->getWidth())
+ posX = graphics->getWidth() - getWidth();
+ if (posY + getHeight() > graphics->getHeight())
+ posY = y - getHeight() - distance;
+
+ setPosition(posX, posY);
+ setVisible(true);
+ requestMoveToTop();
+}
+
+void Popup::mouseMoved(gcn::MouseEvent &event _UNUSED_)
+{
+ if (viewport)
+ viewport->hideBeingPopup();
+}
+
+void Popup::hide()
+{
+ setVisible(false);
+} \ No newline at end of file
diff --git a/src/gui/widgets/popup.h b/src/gui/widgets/popup.h
new file mode 100644
index 000000000..c83368e52
--- /dev/null
+++ b/src/gui/widgets/popup.h
@@ -0,0 +1,174 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef POPUP_H
+#define POPUP_H
+
+#include "configuration.h"
+#include "guichanfwd.h"
+
+#include "gui/widgets/container.h"
+
+#include <guichan/mouselistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Skin;
+class WindowContainer;
+
+/**
+ * A light version of the Window class. Particularly suited for popup type
+ * functionality that doesn't need to be resized or moved around by the mouse
+ * once created, but only needs to display some simple content, like a static
+ * message.
+ *
+ * Popups, in general, shouldn't also need to update their content once
+ * created, although this is not an explicit requirement to use the popup
+ * class.
+ *
+ * \ingroup GUI
+ */
+class Popup : public Container, public gcn::MouseListener
+{
+ public:
+ /**
+ * Constructor. Initializes the title to the given text and hooks
+ * itself into the popup container.
+ *
+ * @param name A human readable name for the popup. Only useful for
+ * debugging purposes.
+ * @param skin The location where the Popup's skin XML can be found.
+ */
+ Popup(const std::string &name = "",
+ const std::string &skin = "window.xml");
+
+ /**
+ * Destructor. Deletes all the added widgets.
+ */
+ ~Popup();
+
+ /**
+ * Sets the window container to be used by new popups.
+ */
+ static void setWindowContainer(WindowContainer *windowContainer);
+
+ /**
+ * Draws the popup.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Sets the size of this popup.
+ */
+ void setContentSize(int width, int height);
+
+ /**
+ * Sets the location relative to the given widget.
+ */
+ void setLocationRelativeTo(gcn::Widget *widget);
+
+ void mouseMoved(gcn::MouseEvent &event);
+
+ /**
+ * Sets the minimum width of the popup.
+ */
+ void setMinWidth(int width);
+
+ int getMinWidth() const { return mMinWidth; }
+
+ /**
+ * Sets the minimum height of the popup.
+ */
+ void setMinHeight(int height);
+
+ int getMinHeight() const { return mMinHeight; }
+
+ /**
+ * Sets the maximum width of the popup.
+ */
+ void setMaxWidth(int width);
+
+ int getMaxWidth() const { return mMaxWidth; }
+
+ /**
+ * Sets the minimum height of the popup.
+ */
+ void setMaxHeight(int height);
+
+ int getMaxHeight() const { return mMaxHeight; }
+
+ /**
+ * Gets the padding of the popup. The padding is the distance between
+ * the popup border and the content.
+ *
+ * @return The padding of the popup.
+ * @see setPadding
+ */
+ int getPadding() const { return mPadding; }
+
+ void setPadding(int padding) { mPadding = padding; }
+
+ /**
+ * Sets the name of the popup. This is only useful for debug purposes.
+ */
+ void setPopupName(const std::string &name)
+ { mPopupName = name; }
+
+ const std::string &getPopupName() const
+ { return mPopupName; }
+
+ /**
+ * Schedule this popup for deletion. It will be deleted at the start
+ * of the next logic update.
+ */
+ void scheduleDelete();
+
+ // Inherited from BasicContainer
+
+ virtual gcn::Rectangle getChildrenArea();
+
+ /**
+ * Sets the location to display the popup. Tries to horizontally center
+ * the popup and provide a vertical buffer between the given point and
+ * the popup. Prevents the popup from extending off-screen, if
+ * possible.
+ */
+ void position(int x, int y);
+
+ void hide();
+
+ private:
+ std::string mPopupName; /**< Name of the popup */
+ int mMinWidth; /**< Minimum popup width */
+ int mMinHeight; /**< Minimum popup height */
+ int mMaxWidth; /**< Maximum popup width */
+ int mMaxHeight; /**< Maximum popup height */
+ int mPadding; /**< Holds the padding of the popup. */
+
+ Skin *mSkin; /**< Skin in use by this popup */
+};
+
+#endif
diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp
new file mode 100644
index 000000000..5275aacf6
--- /dev/null
+++ b/src/gui/widgets/progressbar.cpp
@@ -0,0 +1,225 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/progressbar.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "textrenderer.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+#include <guichan/font.hpp>
+
+ImageRect ProgressBar::mBorder;
+int ProgressBar::mInstances = 0;
+float ProgressBar::mAlpha = 1.0;
+
+ProgressBar::ProgressBar(float progress,
+ int width, int height,
+ int color):
+ gcn::Widget(),
+ mSmoothProgress(true),
+ mProgressPalette(color),
+ mSmoothColorChange(true)
+{
+ // The progress value is directly set at load time:
+ if (progress > 1.0f || progress < 0.0f)
+ progress = 1.0f;
+
+ mProgress = progress;
+ mProgressToGo = progress;
+
+ mColor = Theme::getProgressColor(color >= 0 ? color : 0, mProgress);
+ mColorToGo = mColor;
+
+ setSize(width, height);
+
+ if (mInstances == 0)
+ {
+ Image *dBorders = Theme::getImageFromTheme("vscroll_grey.png");
+ if (dBorders)
+ {
+ mBorder.grid[0] = dBorders->getSubImage(0, 0, 4, 4);
+ mBorder.grid[1] = dBorders->getSubImage(4, 0, 3, 4);
+ mBorder.grid[2] = dBorders->getSubImage(7, 0, 4, 4);
+ mBorder.grid[3] = dBorders->getSubImage(0, 4, 4, 10);
+ mBorder.grid[4] = dBorders->getSubImage(4, 4, 3, 10);
+ mBorder.grid[5] = dBorders->getSubImage(7, 4, 4, 10);
+ mBorder.grid[6] = dBorders->getSubImage(0, 15, 4, 4);
+ mBorder.grid[7] = dBorders->getSubImage(4, 15, 3, 4);
+ mBorder.grid[8] = dBorders->getSubImage(7, 15, 4, 4);
+
+ for (int i = 0; i < 9; i++)
+ mBorder.grid[i]->setAlpha(mAlpha);
+
+ dBorders->decRef();
+ }
+ else
+ {
+ for (int f = 0; f < 9; f ++)
+ mBorder.grid[f] = 0;
+ }
+
+ }
+
+ mInstances++;
+}
+
+ProgressBar::~ProgressBar()
+{
+ mInstances--;
+
+ if (mInstances == 0)
+ for_each(mBorder.grid, mBorder.grid + 9, dtor<Image*>());
+}
+
+void ProgressBar::logic()
+{
+ if (mSmoothColorChange && mColorToGo != mColor)
+ {
+ // Smoothly changing the color for a nicer effect.
+ if (mColorToGo.r > mColor.r)
+ mColor.r++;
+ if (mColorToGo.g > mColor.g)
+ mColor.g++;
+ if (mColorToGo.b > mColor.b)
+ mColor.b++;
+ if (mColorToGo.r < mColor.r)
+ mColor.r--;
+ if (mColorToGo.g < mColor.g)
+ mColor.g--;
+ if (mColorToGo.b < mColor.b)
+ mColor.b--;
+ }
+
+ if (mSmoothProgress && mProgressToGo != mProgress)
+ {
+ // Smoothly showing the progressbar changes.
+ if (mProgressToGo > mProgress)
+ mProgress = std::min(1.0f, mProgress + 0.005f);
+ if (mProgressToGo < mProgress)
+ mProgress = std::max(0.0f, mProgress - 0.005f);
+ }
+}
+
+void ProgressBar::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (mAlpha != alpha)
+ {
+ mAlpha = alpha;
+ for (int i = 0; i < 9; i++)
+ {
+ if (mBorder.grid[i])
+ mBorder.grid[i]->setAlpha(mAlpha);
+ }
+ }
+
+}
+
+void ProgressBar::draw(gcn::Graphics *graphics)
+{
+ updateAlpha();
+
+ mColor.a = static_cast<int>(mAlpha * 255);
+
+ gcn::Rectangle rect = getDimension();
+ rect.x = 0;
+ rect.y = 0;
+
+ render(static_cast<Graphics*>(graphics), rect, mColor,
+ mProgress, mText);
+}
+
+void ProgressBar::setProgress(float progress)
+{
+ const float p = std::min(1.0f, std::max(0.0f, progress));
+ mProgressToGo = p;
+
+ if (!mSmoothProgress)
+ mProgress = p;
+
+ if (mProgressPalette >= 0)
+ mColorToGo = Theme::getProgressColor(mProgressPalette, progress);
+}
+
+void ProgressBar::setProgressPalette(int progressPalette)
+{
+ int oldPalette = mProgressPalette;
+ mProgressPalette = progressPalette;
+
+ if (mProgressPalette != oldPalette && mProgressPalette >= 0)
+ mColorToGo = Theme::getProgressColor(mProgressPalette, mProgressToGo);
+}
+
+void ProgressBar::setColor(const gcn::Color &color)
+{
+ mColorToGo = color;
+
+ if (!mSmoothColorChange)
+ mColor = color;
+}
+
+void ProgressBar::render(Graphics *graphics, const gcn::Rectangle &area,
+ const gcn::Color &color, float progress,
+ const std::string &text)
+{
+ gcn::Font *oldFont = graphics->getFont();
+ gcn::Color oldColor = graphics->getColor();
+
+ graphics->drawImageRect(area, mBorder);
+
+ // The bar
+ if (progress > 0)
+ {
+ graphics->setColor(color);
+ graphics->fillRectangle(gcn::Rectangle(static_cast<int>(area.x + 4),
+ static_cast<int>(area.y + 4),
+ static_cast<int>(static_cast<float>(progress)
+ * static_cast<float>(area.width - 8)),
+ static_cast<int>(area.height - 8)));
+ }
+
+ // The label
+ if (!text.empty())
+ {
+ const int textX = area.x + area.width / 2;
+ const int textY = area.y + (area.height - boldFont->getHeight()) / 2;
+
+ TextRenderer::renderText(graphics, text, textX, textY,
+ gcn::Graphics::CENTER,
+ Theme::getThemeColor(Theme::PROGRESS_BAR),
+ gui->getFont(), true, false);
+ }
+
+ graphics->setFont(oldFont);
+ graphics->setColor(oldColor);
+}
diff --git a/src/gui/widgets/progressbar.h b/src/gui/widgets/progressbar.h
new file mode 100644
index 000000000..56bcb0a0f
--- /dev/null
+++ b/src/gui/widgets/progressbar.h
@@ -0,0 +1,139 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PROGRESSBAR_H
+#define PROGRESSBAR_H
+
+#include <guichan/widget.hpp>
+
+#include <string>
+
+class Graphics;
+class ImageRect;
+
+/**
+ * A progress bar.
+ *
+ * \ingroup GUI
+ */
+class ProgressBar : public gcn::Widget
+{
+ public:
+ /**
+ * Constructor, initializes the progress with the given value.
+ */
+ ProgressBar(float progress = 0.0f,
+ int width = 40, int height = 7,
+ int color = -1);
+
+ ~ProgressBar();
+
+ /**
+ * Performs progress bar logic (fading colors)
+ */
+ void logic();
+
+ /**
+ * Update the alpha value to the graphic components.
+ */
+ void updateAlpha();
+
+ /**
+ * Draws the progress bar.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Sets the current progress.
+ */
+ void setProgress(float progress);
+
+ /**
+ * Returns the current progress.
+ */
+ float getProgress() const { return mProgress; }
+
+ /**
+ * Change the ProgressPalette for this ProgressBar to follow or -1 to
+ * disable this and manage color manually.
+ */
+ void setProgressPalette(int progressPalette);
+
+ /**
+ * Change the color of the progress bar.
+ */
+ void setColor(const gcn::Color &color);
+
+ /**
+ * Returns the color of the progress bar.
+ */
+ const gcn::Color &getColor() const { return mColor; }
+
+ /**
+ * Sets the text shown on the progress bar.
+ */
+ void setText(const std::string &text)
+ { mText = text; }
+
+ /**
+ * Returns the text shown on the progress bar.
+ */
+ const std::string &text() const
+ { return mText; }
+
+ /**
+ * Set whether the progress is moved smoothly.
+ */
+ void setSmoothProgress(bool smoothProgress)
+ { mSmoothProgress = smoothProgress; }
+
+ /**
+ * Set whether the color changing is made smoothly.
+ */
+ void setSmoothColorChange(bool smoothColorChange)
+ { mSmoothColorChange = smoothColorChange; }
+
+ /**
+ * Renders a progressbar with the given properties.
+ */
+ static void render(Graphics *graphics, const gcn::Rectangle &area,
+ const gcn::Color &color, float progress,
+ const std::string &text = "");
+
+ private:
+ float mProgress, mProgressToGo;
+ bool mSmoothProgress;
+
+ int mProgressPalette; /** < Entry in ProgressPalette or -1 for none. */
+ gcn::Color mColor;
+ gcn::Color mColorToGo;
+ bool mSmoothColorChange;
+
+ std::string mText;
+
+ static ImageRect mBorder;
+ static int mInstances;
+ static float mAlpha;
+
+ static const gcn::Color TEXT_COLOR;
+};
+
+#endif
diff --git a/src/gui/widgets/progressindicator.cpp b/src/gui/widgets/progressindicator.cpp
new file mode 100644
index 000000000..9f1a8f032
--- /dev/null
+++ b/src/gui/widgets/progressindicator.cpp
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "progressindicator.h"
+
+#include "graphics.h"
+#include "simpleanimation.h"
+
+#include "gui/theme.h"
+
+#include "resources/animation.h"
+#include "resources/imageset.h"
+#include "resources/resourcemanager.h"
+
+#include <guichan/widgets/label.hpp>
+
+ProgressIndicator::ProgressIndicator()
+{
+ ImageSet *images = Theme::getImageSetFromTheme("progress-indicator.png",
+ 32, 32);
+
+ Animation *anim = new Animation;
+ if (images)
+ {
+ for (ImageSet::size_type i = 0; i < images->size(); ++i)
+ anim->addFrame(images->get(i), 100, 0, 0);
+
+ mIndicator = new SimpleAnimation(anim);
+
+ images->decRef();
+ }
+ else
+ {
+ mIndicator = 0;
+ }
+
+ setSize(32, 32);
+}
+
+ProgressIndicator::~ProgressIndicator()
+{
+ delete mIndicator;
+ mIndicator = 0;
+}
+
+void ProgressIndicator::logic()
+{
+ if (mIndicator)
+ mIndicator->update(10);
+}
+
+void ProgressIndicator::draw(gcn::Graphics *graphics)
+{
+ if (mIndicator)
+ {
+ // Draw the indicator centered on the widget
+ const int x = (getWidth() - 32) / 2;
+ const int y = (getHeight() - 32) / 2;
+ mIndicator->draw(static_cast<Graphics*>(graphics), x, y);
+ }
+}
diff --git a/src/gui/widgets/progressindicator.h b/src/gui/widgets/progressindicator.h
new file mode 100644
index 000000000..b990d8bef
--- /dev/null
+++ b/src/gui/widgets/progressindicator.h
@@ -0,0 +1,45 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PROGRESSINDICATOR_H
+#define PROGRESSINDICATOR_H
+
+#include <guichan/widget.hpp>
+
+class SimpleAnimation;
+
+/**
+ * A widget that indicates progress. Suitable to use instead of a progress bar
+ * in cases where it is unknown how long something is going to take.
+ */
+class ProgressIndicator : public gcn::Widget
+{
+public:
+ ProgressIndicator();
+ ~ProgressIndicator();
+
+ void logic();
+ void draw(gcn::Graphics *graphics);
+
+private:
+ SimpleAnimation *mIndicator;
+};
+
+#endif // PROGRESSINDICATOR_H
diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp
new file mode 100644
index 000000000..c9738e3cd
--- /dev/null
+++ b/src/gui/widgets/radiobutton.cpp
@@ -0,0 +1,163 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/radiobutton.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+int RadioButton::instances = 0;
+float RadioButton::mAlpha = 1.0;
+Image *RadioButton::radioNormal;
+Image *RadioButton::radioChecked;
+Image *RadioButton::radioDisabled;
+Image *RadioButton::radioDisabledChecked;
+Image *RadioButton::radioNormalHi;
+Image *RadioButton::radioCheckedHi;
+
+RadioButton::RadioButton(const std::string &caption, const std::string &group,
+ bool marked):
+ gcn::RadioButton(caption, group, marked),
+ mHasMouse(false)
+{
+ if (instances == 0)
+ {
+ radioNormal = Theme::getImageFromTheme("radioout.png");
+ radioChecked = Theme::getImageFromTheme("radioin.png");
+ radioDisabled = Theme::getImageFromTheme("radioout.png");
+ radioDisabledChecked = Theme::getImageFromTheme("radioin.png");
+ radioNormalHi = Theme::getImageFromTheme("radioout_highlight.png");
+ radioCheckedHi = Theme::getImageFromTheme("radioin_highlight.png");
+ if (radioNormal)
+ radioNormal->setAlpha(mAlpha);
+ if (radioChecked)
+ radioChecked->setAlpha(mAlpha);
+ if (radioDisabled)
+ radioDisabled->setAlpha(mAlpha);
+ if (radioDisabledChecked)
+ radioDisabledChecked->setAlpha(mAlpha);
+ if (radioNormalHi)
+ radioNormalHi->setAlpha(mAlpha);
+ if (radioCheckedHi)
+ radioCheckedHi->setAlpha(mAlpha);
+ }
+
+ instances++;
+}
+
+RadioButton::~RadioButton()
+{
+ instances--;
+
+ if (instances == 0)
+ {
+ if (radioNormal)
+ radioNormal->decRef();
+ if (radioChecked)
+ radioChecked->decRef();
+ if (radioDisabled)
+ radioDisabled->decRef();
+ if (radioDisabledChecked)
+ radioDisabledChecked->decRef();
+ if (radioNormalHi)
+ radioNormalHi->decRef();
+ if (radioCheckedHi)
+ radioCheckedHi->decRef();
+ }
+}
+
+void RadioButton::drawBox(gcn::Graphics* graphics)
+{
+ if (Client::getGuiAlpha() != mAlpha)
+ {
+ mAlpha = Client::getGuiAlpha();
+ if (radioNormal)
+ radioNormal->setAlpha(mAlpha);
+ if (radioChecked)
+ radioChecked->setAlpha(mAlpha);
+ if (radioDisabled)
+ radioDisabled->setAlpha(mAlpha);
+ if (radioDisabledChecked)
+ radioDisabledChecked->setAlpha(mAlpha);
+ if (radioNormalHi)
+ radioNormalHi->setAlpha(mAlpha);
+ if (radioCheckedHi)
+ radioCheckedHi->setAlpha(mAlpha);
+ }
+
+ Image *box = NULL;
+
+ if (isEnabled())
+ {
+ if (isSelected())
+ if (mHasMouse)
+ box = radioCheckedHi;
+ else
+ box = radioChecked;
+ else
+ if (mHasMouse)
+ box = radioNormalHi;
+ else
+ box = radioNormal;
+ }
+ else
+ {
+ if (isSelected())
+ box = radioDisabledChecked;
+ else
+ box = radioDisabled;
+ }
+
+ if (box)
+ static_cast<Graphics*>(graphics)->drawImage(box, 2, 2);
+}
+
+void RadioButton::draw(gcn::Graphics* graphics)
+{
+ graphics->pushClipArea(gcn::Rectangle(1, 1, getWidth() - 1,
+ getHeight() - 1));
+
+ drawBox(graphics);
+
+ graphics->popClipArea();
+
+ graphics->setFont(getFont());
+ graphics->setColor(getForegroundColor());
+
+ int h = getHeight() + getHeight() / 2;
+ graphics->drawText(getCaption(), h - 2, 0);
+}
+
+void RadioButton::mouseEntered(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = true;
+}
+
+void RadioButton::mouseExited(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = false;
+}
+
diff --git a/src/gui/widgets/radiobutton.h b/src/gui/widgets/radiobutton.h
new file mode 100644
index 000000000..b7383aa7c
--- /dev/null
+++ b/src/gui/widgets/radiobutton.h
@@ -0,0 +1,85 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef RADIOBUTTON_H
+#define RADIOBUTTON_H
+
+#include <guichan/widgets/radiobutton.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+
+/**
+ * Guichan based RadioButton with custom look
+ */
+class RadioButton : public gcn::RadioButton
+{
+ public:
+ /**
+ * Constructor.
+ */
+ RadioButton(const std::string &caption, const std::string &group,
+ bool marked = false);
+
+ /**
+ * Destructor.
+ */
+ ~RadioButton();
+
+ /**
+ * Draws the radiobutton, not the caption.
+ */
+ void drawBox(gcn::Graphics* graphics);
+
+ /**
+ * Implementation of the draw methods.
+ * Thus, avoiding the rhomb around the radio button.
+ */
+ void draw(gcn::Graphics* graphics);
+
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
+ private:
+ static int instances;
+ static float mAlpha;
+ bool mHasMouse;
+ static Image *radioNormal;
+ static Image *radioChecked;
+ static Image *radioDisabled;
+ static Image *radioDisabledChecked;
+ static Image *radioNormalHi;
+ static Image *radioCheckedHi;
+};
+
+#endif // RADIOBUTTON_H
diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp
new file mode 100644
index 000000000..e8ccd0740
--- /dev/null
+++ b/src/gui/widgets/resizegrip.cpp
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/resizegrip.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+#include <guichan/graphics.hpp>
+
+Image *ResizeGrip::gripImage = 0;
+int ResizeGrip::mInstances = 0;
+float ResizeGrip::mAlpha = 1.0;
+
+ResizeGrip::ResizeGrip(const std::string &image)
+{
+ if (mInstances == 0)
+ {
+ // Load the grip image
+ gripImage = Theme::getImageFromTheme(image);
+ if (gripImage)
+ gripImage->setAlpha(mAlpha);
+ }
+
+ mInstances++;
+
+ if (gripImage)
+ {
+ setWidth(gripImage->getWidth() + 2);
+ setHeight(gripImage->getHeight() + 2);
+ }
+ else
+ {
+ setWidth(2);
+ setHeight(2);
+ }
+}
+
+ResizeGrip::~ResizeGrip()
+{
+ mInstances--;
+
+ if (mInstances == 0 && gripImage)
+ gripImage->decRef();
+}
+
+void ResizeGrip::draw(gcn::Graphics *graphics)
+{
+ if (!gripImage)
+ return;
+
+ if (Client::getGuiAlpha() != mAlpha)
+ {
+ mAlpha = Client::getGuiAlpha();
+ gripImage->setAlpha(mAlpha);
+ }
+
+ static_cast<Graphics*>(graphics)->drawImage(gripImage, 0, 0);
+}
diff --git a/src/gui/widgets/resizegrip.h b/src/gui/widgets/resizegrip.h
new file mode 100644
index 000000000..5ef93f297
--- /dev/null
+++ b/src/gui/widgets/resizegrip.h
@@ -0,0 +1,60 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef RESIZEGRIP_H
+#define RESIZEGRIP_H
+
+#include <guichan/widget.hpp>
+
+class Image;
+
+/**
+ * Resize grip. The resize grip is part of a resizable Window. It relies on the
+ * fact that uncaught mouse events are automatically routed to the parent
+ * window.
+ *
+ * \ingroup GUI
+ */
+class ResizeGrip : public gcn::Widget
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ResizeGrip(const std::string &image = "resize.png");
+
+ /**
+ * Destructor.
+ */
+ ~ResizeGrip();
+
+ /**
+ * Draws the resize grip.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ private:
+ static Image *gripImage; /**< Resize grip image */
+ static int mInstances; /**< Number of resize grip instances */
+ static float mAlpha;
+};
+
+#endif
diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp
new file mode 100644
index 000000000..187794b1d
--- /dev/null
+++ b/src/gui/widgets/scrollarea.cpp
@@ -0,0 +1,445 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/scrollarea.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+int ScrollArea::instances = 0;
+float ScrollArea::mAlpha = 1.0;
+ImageRect ScrollArea::background;
+ImageRect ScrollArea::vMarker;
+ImageRect ScrollArea::vMarkerHi;
+Image *ScrollArea::buttons[4][2];
+
+ScrollArea::ScrollArea():
+ gcn::ScrollArea(),
+ mX(0),
+ mY(0),
+ mHasMouse(false),
+ mOpaque(true)
+{
+ addWidgetListener(this);
+ init();
+}
+
+ScrollArea::ScrollArea(gcn::Widget *widget):
+ gcn::ScrollArea(widget),
+ mX(0),
+ mY(0),
+ mHasMouse(false),
+ mOpaque(true)
+{
+ init();
+}
+
+ScrollArea::~ScrollArea()
+{
+ // Garbage collection
+ delete getContent();
+
+ instances--;
+
+ if (instances == 0)
+ {
+ for_each(background.grid, background.grid + 9, dtor<Image*>());
+ for_each(vMarker.grid, vMarker.grid + 9, dtor<Image*>());
+ for_each(vMarkerHi.grid, vMarkerHi.grid + 9, dtor<Image*>());
+
+ if (buttons[UP][0])
+ buttons[UP][0]->decRef();
+ if (buttons[UP][1])
+ buttons[UP][1]->decRef();
+ if (buttons[DOWN][0])
+ buttons[DOWN][0]->decRef();
+ if (buttons[DOWN][1])
+ buttons[DOWN][1]->decRef();
+ if (buttons[LEFT][0])
+ buttons[LEFT][0]->decRef();
+ if (buttons[LEFT][1])
+ buttons[LEFT][1]->decRef();
+ if (buttons[RIGHT][0])
+ buttons[RIGHT][0]->decRef();
+ if (buttons[RIGHT][1])
+ buttons[RIGHT][1]->decRef();
+ }
+}
+
+void ScrollArea::init()
+{
+ // Draw background by default
+ setOpaque(true);
+
+ setUpButtonScrollAmount(2);
+ setDownButtonScrollAmount(2);
+ setLeftButtonScrollAmount(2);
+ setRightButtonScrollAmount(2);
+
+ if (instances == 0)
+ {
+ // Load the background skin
+ Image *textbox = Theme::getImageFromTheme("deepbox.png");
+ const int bggridx[4] = {0, 3, 28, 31};
+ const int bggridy[4] = {0, 3, 28, 31};
+ int a = 0, x, y;
+
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ if (textbox)
+ {
+ background.grid[a] = textbox->getSubImage(
+ bggridx[x], bggridy[y],
+ bggridx[x + 1] - bggridx[x] + 1,
+ bggridy[y + 1] - bggridy[y] + 1);
+ background.grid[a]->setAlpha(
+ Client::getGuiAlpha());
+ }
+ else
+ {
+ background.grid[a] = 0;
+ }
+ a++;
+ }
+ }
+
+ textbox->decRef();
+
+ // Load vertical scrollbar skin
+ Image *vscroll = Theme::getImageFromTheme("vscroll_grey.png");
+ Image *vscrollHi = Theme::getImageFromTheme("vscroll_highlight.png");
+
+ int vsgridx[4] = {0, 4, 7, 11};
+ int vsgridy[4] = {0, 4, 15, 19};
+ a = 0;
+
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ if (vscroll)
+ {
+ vMarker.grid[a] = vscroll->getSubImage(
+ vsgridx[x], vsgridy[y],
+ vsgridx[x + 1] - vsgridx[x],
+ vsgridy[y + 1] - vsgridy[y]);
+ vMarker.grid[a]->setAlpha(
+ Client::getGuiAlpha());
+ }
+ else
+ {
+ vMarker.grid[a] = 0;
+ }
+ if (vscrollHi)
+ {
+ vMarkerHi.grid[a] = vscrollHi->getSubImage(
+ vsgridx[x], vsgridy[y],
+ vsgridx[x + 1] - vsgridx[x],
+ vsgridy[y + 1] - vsgridy[y]);
+ vMarkerHi.grid[a]->setAlpha(
+ Client::getGuiAlpha());
+ }
+ else
+ {
+ vMarkerHi.grid[a] = 0;
+ }
+ a++;
+ }
+ }
+
+ if (vscroll)
+ vscroll->decRef();
+ if (vscrollHi)
+ vscrollHi->decRef();
+
+ buttons[UP][0] =
+ Theme::getImageFromTheme("vscroll_up_default.png");
+ buttons[DOWN][0] =
+ Theme::getImageFromTheme("vscroll_down_default.png");
+ buttons[LEFT][0] =
+ Theme::getImageFromTheme("hscroll_left_default.png");
+ buttons[RIGHT][0] =
+ Theme::getImageFromTheme("hscroll_right_default.png");
+ buttons[UP][1] =
+ Theme::getImageFromTheme("vscroll_up_pressed.png");
+ buttons[DOWN][1] =
+ Theme::getImageFromTheme("vscroll_down_pressed.png");
+ buttons[LEFT][1] =
+ Theme::getImageFromTheme("hscroll_left_pressed.png");
+ buttons[RIGHT][1] =
+ Theme::getImageFromTheme("hscroll_right_pressed.png");
+ }
+
+ instances++;
+}
+
+void ScrollArea::logic()
+{
+ if (!isVisible())
+ return;
+
+ gcn::ScrollArea::logic();
+ gcn::Widget *content = getContent();
+
+ // When no scrollbar in a certain direction, adapt content size to match
+ // the content dimension exactly.
+ if (content)
+ {
+ if (getHorizontalScrollPolicy() == gcn::ScrollArea::SHOW_NEVER)
+ {
+ content->setWidth(getChildrenArea().width -
+ 2 * content->getFrameSize());
+ }
+ if (getVerticalScrollPolicy() == gcn::ScrollArea::SHOW_NEVER)
+ {
+ content->setHeight(getChildrenArea().height -
+ 2 * content->getFrameSize());
+ }
+ }
+
+ if (mUpButtonPressed)
+ {
+ setVerticalScrollAmount(getVerticalScrollAmount() -
+ mUpButtonScrollAmount);
+ }
+ else if (mDownButtonPressed)
+ {
+ setVerticalScrollAmount(getVerticalScrollAmount() +
+ mDownButtonScrollAmount);
+ }
+ else if (mLeftButtonPressed)
+ {
+ setHorizontalScrollAmount(getHorizontalScrollAmount() -
+ mLeftButtonScrollAmount);
+ }
+ else if (mRightButtonPressed)
+ {
+ setHorizontalScrollAmount(getHorizontalScrollAmount() +
+ mRightButtonScrollAmount);
+ }
+}
+
+void ScrollArea::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (alpha != mAlpha)
+ {
+ mAlpha = alpha;
+ for (int a = 0; a < 9; a++)
+ {
+ if (background.grid[a])
+ background.grid[a]->setAlpha(mAlpha);
+ if (vMarker.grid[a])
+ vMarker.grid[a]->setAlpha(mAlpha);
+ if (vMarkerHi.grid[a])
+ vMarkerHi.grid[a]->setAlpha(mAlpha);
+ }
+ }
+}
+
+void ScrollArea::draw(gcn::Graphics *graphics)
+{
+ if (mVBarVisible)
+ {
+ drawUpButton(graphics);
+ drawDownButton(graphics);
+ drawVBar(graphics);
+ drawVMarker(graphics);
+ }
+
+ if (mHBarVisible)
+ {
+ drawLeftButton(graphics);
+ drawRightButton(graphics);
+ drawHBar(graphics);
+ drawHMarker(graphics);
+ }
+
+ if (mHBarVisible && mVBarVisible)
+ {
+ graphics->setColor(getBaseColor());
+ graphics->fillRectangle(gcn::Rectangle(getWidth() - mScrollbarWidth,
+ getHeight() - mScrollbarWidth,
+ mScrollbarWidth,
+ mScrollbarWidth));
+ }
+
+ updateAlpha();
+
+ drawChildren(graphics);
+}
+
+void ScrollArea::drawFrame(gcn::Graphics *graphics)
+{
+ if (mOpaque)
+ {
+ const int bs = getFrameSize();
+ const int w = getWidth() + bs * 2;
+ const int h = getHeight() + bs * 2;
+
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(0, 0, w, h, background);
+ }
+}
+
+void ScrollArea::setOpaque(bool opaque)
+{
+ mOpaque = opaque;
+ setFrameSize(mOpaque ? 2 : 0);
+}
+
+void ScrollArea::drawButton(gcn::Graphics *graphics, BUTTON_DIR dir)
+{
+ int state = 0;
+ gcn::Rectangle dim;
+
+ switch (dir)
+ {
+ case UP:
+ state = mUpButtonPressed ? 1 : 0;
+ dim = getUpButtonDimension();
+ break;
+ case DOWN:
+ state = mDownButtonPressed ? 1 : 0;
+ dim = getDownButtonDimension();
+ break;
+ case LEFT:
+ state = mLeftButtonPressed ? 1 : 0;
+ dim = getLeftButtonDimension();
+ break;
+ case RIGHT:
+ state = mRightButtonPressed ? 1 : 0;
+ dim = getRightButtonDimension();
+ break;
+ default:
+ logger->log("ScrollArea::drawButton unknown dir: "
+ + toString(static_cast<unsigned>(dir)));
+ break;
+ }
+
+ if (buttons[dir][state])
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImage(buttons[dir][state], dim.x, dim.y);
+ }
+}
+
+void ScrollArea::drawUpButton(gcn::Graphics *graphics)
+{
+ drawButton(graphics, UP);
+}
+
+void ScrollArea::drawDownButton(gcn::Graphics *graphics)
+{
+ drawButton(graphics, DOWN);
+}
+
+void ScrollArea::drawLeftButton(gcn::Graphics *graphics)
+{
+ drawButton(graphics, LEFT);
+}
+
+void ScrollArea::drawRightButton(gcn::Graphics *graphics)
+{
+ drawButton(graphics, RIGHT);
+}
+
+void ScrollArea::drawVBar(gcn::Graphics *graphics)
+{
+ const gcn::Rectangle dim = getVerticalBarDimension();
+ graphics->setColor(gcn::Color(0, 0, 0, 32));
+ graphics->fillRectangle(dim);
+ graphics->setColor(gcn::Color(255, 255, 255));
+}
+
+void ScrollArea::drawHBar(gcn::Graphics *graphics)
+{
+ const gcn::Rectangle dim = getHorizontalBarDimension();
+ graphics->setColor(gcn::Color(0, 0, 0, 32));
+ graphics->fillRectangle(dim);
+ graphics->setColor(gcn::Color(255, 255, 255));
+}
+
+void ScrollArea::drawVMarker(gcn::Graphics *graphics)
+{
+ gcn::Rectangle dim = getVerticalMarkerDimension();
+
+ if ((mHasMouse) && (mX > (getWidth() - getScrollbarWidth())))
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarkerHi);
+ }
+ else
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker);
+ }
+}
+
+void ScrollArea::drawHMarker(gcn::Graphics *graphics)
+{
+ gcn::Rectangle dim = getHorizontalMarkerDimension();
+
+ if ((mHasMouse) && (mY > (getHeight() - getScrollbarWidth())))
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarkerHi);
+ }
+ else
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker);
+ }
+}
+
+void ScrollArea::mouseMoved(gcn::MouseEvent& event)
+{
+ mX = event.getX();
+ mY = event.getY();
+}
+
+void ScrollArea::mouseEntered(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = true;
+}
+
+void ScrollArea::mouseExited(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = false;
+}
+
+void ScrollArea::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ getContent()->setSize(getWidth() - 2 * getFrameSize(),
+ getHeight() - 2 * getFrameSize());
+}
diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h
new file mode 100644
index 000000000..4f6a07f82
--- /dev/null
+++ b/src/gui/widgets/scrollarea.h
@@ -0,0 +1,151 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SCROLLAREA_H
+#define SCROLLAREA_H
+
+#include <guichan/widgets/scrollarea.hpp>
+#include <guichan/widgetlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+class ImageRect;
+
+/**
+ * A scroll area.
+ *
+ * Contrary to Guichan's scroll area, this scroll area takes ownership over its
+ * content. However, it won't delete a previously set content widget when
+ * setContent is called!
+ *
+ * \ingroup GUI
+ */
+class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener
+{
+ public:
+ /**
+ * Constructor that takes no content. Needed for use with the DropDown
+ * class.
+ */
+ ScrollArea();
+
+ /**
+ * Constructor.
+ *
+ * @param content the initial content to show in the scroll area
+ */
+ ScrollArea(gcn::Widget *content);
+
+ /**
+ * Destructor. Also deletes the content.
+ */
+ ~ScrollArea();
+
+ /**
+ * Logic function optionally adapts width or height of contents. This
+ * depends on the scrollbar settings.
+ */
+ void logic();
+
+ /**
+ * Update the alpha value to the graphic components.
+ */
+ void updateAlpha();
+
+ /**
+ * Draws the scroll area.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Draws the background and border of the scroll area.
+ */
+ void drawFrame(gcn::Graphics *graphics);
+
+ /**
+ * Sets whether the widget should draw its background or not.
+ */
+ void setOpaque(bool opaque);
+
+ /**
+ * Returns whether the widget draws its background or not.
+ */
+ bool isOpaque() const { return mOpaque; }
+
+ /**
+ * Called when the mouse moves in the widget area.
+ */
+ void mouseMoved(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
+ void widgetResized(const gcn::Event &event);
+
+ protected:
+ enum BUTTON_DIR
+ {
+ UP = 0,
+ DOWN,
+ LEFT,
+ RIGHT
+ };
+
+ /**
+ * Initializes the scroll area.
+ */
+ void init();
+
+ void drawButton(gcn::Graphics *graphics, BUTTON_DIR dir);
+ void drawUpButton(gcn::Graphics *graphics);
+ void drawDownButton(gcn::Graphics *graphics);
+ void drawLeftButton(gcn::Graphics *graphics);
+ void drawRightButton(gcn::Graphics *graphics);
+ void drawVBar(gcn::Graphics *graphics);
+ void drawHBar(gcn::Graphics *graphics);
+ void drawVMarker(gcn::Graphics *graphics);
+ void drawHMarker(gcn::Graphics *graphics);
+
+ static int instances;
+ static float mAlpha;
+ static ImageRect background;
+ static ImageRect vMarker;
+ static ImageRect vMarkerHi;
+ static Image *buttons[4][2];
+
+ int mX, mY;
+ bool mHasMouse;
+ bool mOpaque;
+};
+
+#endif
diff --git a/src/gui/widgets/setuptab.cpp b/src/gui/widgets/setuptab.cpp
new file mode 100644
index 000000000..3c10e6d93
--- /dev/null
+++ b/src/gui/widgets/setuptab.cpp
@@ -0,0 +1,31 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/setuptab.h"
+
+SetupTab::SetupTab()
+{
+ setOpaque(false);
+}
+
+void SetupTab::externalUpdated()
+{
+} \ No newline at end of file
diff --git a/src/gui/widgets/setuptab.h b/src/gui/widgets/setuptab.h
new file mode 100644
index 000000000..2d8742123
--- /dev/null
+++ b/src/gui/widgets/setuptab.h
@@ -0,0 +1,64 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_SETUPTAB_H
+#define GUI_SETUPTAB_H
+
+#include "gui/widgets/container.h"
+
+#include <string>
+
+/**
+ * A container for the contents of a tab in the setup window.
+ */
+class SetupTab : public Container
+{
+public:
+ SetupTab();
+
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Called when the Apply button is pressed in the setup window.
+ */
+ virtual void apply() = 0;
+
+ /**
+ * Called when the Cancel button is pressed in the setup window.
+ */
+ virtual void cancel() = 0;
+
+ virtual void externalUpdated();
+
+protected:
+ /**
+ * Sets the name displayed on the tab. Should be set in the
+ * constructor of a subclass.
+ */
+ void setName(const std::string &name)
+ { mName = name; }
+
+private:
+ std::string mName;
+};
+
+#endif
diff --git a/src/gui/widgets/shopitems.cpp b/src/gui/widgets/shopitems.cpp
new file mode 100644
index 000000000..0aff3d5b9
--- /dev/null
+++ b/src/gui/widgets/shopitems.cpp
@@ -0,0 +1,118 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/shopitems.h"
+
+#include "shopitem.h"
+
+#include "utils/dtor.h"
+
+ShopItems::ShopItems(bool mergeDuplicates) :
+ mMergeDuplicates(mergeDuplicates)
+{
+}
+
+ShopItems::~ShopItems()
+{
+ clear();
+}
+
+int ShopItems::getNumberOfElements()
+{
+ return static_cast<int>(mShopItems.size());
+}
+
+std::string ShopItems::getElementAt(int i)
+{
+ if (i < 0 || (unsigned)i >= mShopItems.size() || !mShopItems.at(i))
+ return "";
+
+ return mShopItems.at(i)->getDisplayName();
+}
+
+void ShopItems::addItem(int id, int amount, int price)
+{
+ mShopItems.push_back(new ShopItem(-1, id, amount, price));
+}
+
+void ShopItems::addItemNoDup(int id, int amount, int price)
+{
+ ShopItem *item = findItem(id);
+ if (!item)
+ mShopItems.push_back(new ShopItem(-1, id, amount, price));
+}
+
+void ShopItems::addItem(int inventoryIndex, int id, int quantity, int price)
+{
+ ShopItem *item = 0;
+ if (mMergeDuplicates)
+ item = findItem(id);
+
+ if (item)
+ {
+ item->addDuplicate (inventoryIndex, quantity);
+ }
+ else
+ {
+ item = new ShopItem(inventoryIndex, id, quantity, price);
+ mShopItems.push_back(item);
+ }
+}
+
+ShopItem *ShopItems::at(unsigned int i) const
+{
+ if (i >= mShopItems.size())
+ return 0;
+
+ return mShopItems.at(i);
+}
+
+void ShopItems::erase(unsigned int i)
+{
+ if (i >= mShopItems.size())
+ return;
+
+ mShopItems.erase(mShopItems.begin() + i);
+}
+
+void ShopItems::clear()
+{
+ delete_all(mShopItems);
+ mShopItems.clear();
+}
+
+ShopItem *ShopItems::findItem(int id)
+{
+ ShopItem *item;
+
+ std::vector<ShopItem*>::iterator it = mShopItems.begin();
+ std::vector<ShopItem*>::iterator e = mShopItems.end();
+ while (it != e)
+ {
+ item = *(it);
+ if (item->getId() == id)
+ return item;
+
+ ++it;
+ }
+
+ return 0;
+}
diff --git a/src/gui/widgets/shopitems.h b/src/gui/widgets/shopitems.h
new file mode 100644
index 000000000..ba325bfa5
--- /dev/null
+++ b/src/gui/widgets/shopitems.h
@@ -0,0 +1,120 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SHOPITEMS_H
+#define SHOPITEMS_H
+
+#include <guichan/listmodel.hpp>
+
+#include <string>
+#include <vector>
+
+class ShopItem;
+
+/**
+ * This class handles the list of items available in a shop.
+ *
+ * The addItem routine can automatically check, if an item already exists and
+ * only adds duplicates to the old item, if one is found. The original
+ * distribution of the duplicates can be retrieved from the item.
+ *
+ * This functionality can be enabled in the constructor.
+ */
+class ShopItems : public gcn::ListModel
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param mergeDuplicates lets the Shop look for duplicate entries and
+ * merges them to one item.
+ */
+ ShopItems(bool mergeDuplicates = false);
+
+ ~ShopItems();
+
+ /**
+ * Adds an item to the list.
+ */
+ void addItem(int id, int amount, int price);
+
+ /**
+ * Adds an item to the list (used by sell dialog). Looks for
+ * duplicate entries, if mergeDuplicates was turned on.
+ *
+ * @param inventoryIndex the inventory index of the item
+ * @param id the id of the item
+ * @param quantity number of available copies of the item
+ * @param price price of the item
+ */
+ void addItem(int inventoryIndex, int id, int amount, int price);
+
+ void addItemNoDup(int id, int amount, int price);
+
+ /**
+ * Returns the number of items in the shop.
+ */
+ int getNumberOfElements();
+
+ /**
+ * Returns the name of item number i in the shop.
+ *
+ * @param i the index to retrieve
+ */
+ std::string getElementAt(int i);
+
+ /**
+ * Returns the item number i in the shop.
+ */
+ ShopItem *at(unsigned int i) const;
+
+ /**
+ * Removes an element from the shop.
+ *
+ * @param i index to remove
+ */
+ void erase(unsigned int i);
+
+ /**
+ * Clears the list of items in the shop.
+ */
+ void clear();
+
+ std::vector<ShopItem*> &items()
+ { return mShopItems; }
+
+ private:
+ /**
+ * Searches the current items in the shop for the specified
+ * id and returns the item if found, or 0 else.
+ *
+ * @return the item found or 0
+ */
+ ShopItem *findItem(int id);
+
+ /** The list of items in the shop. */
+ std::vector<ShopItem*> mShopItems;
+
+ /** Look for duplicate entries on addition. */
+ bool mMergeDuplicates;
+};
+
+#endif // SHOPITEMS_H
diff --git a/src/gui/widgets/shoplistbox.cpp b/src/gui/widgets/shoplistbox.cpp
new file mode 100644
index 000000000..a0577db03
--- /dev/null
+++ b/src/gui/widgets/shoplistbox.cpp
@@ -0,0 +1,185 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/shoplistbox.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "shopitem.h"
+
+#include "gui/itempopup.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/shopitems.h"
+
+#include "resources/image.h"
+
+#include <guichan/font.hpp>
+#include <guichan/listmodel.hpp>
+
+const int ITEM_ICON_SIZE = 32;
+
+float ShopListBox::mAlpha = 1.0;
+
+ShopListBox::ShopListBox(gcn::ListModel *listModel):
+ ListBox(listModel),
+ mPlayerMoney(0),
+ mShopItems(0)
+{
+ mRowHeight = getFont()->getHeight();
+ mPriceCheck = true;
+
+ mItemPopup = new ItemPopup;
+}
+
+ShopListBox::ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel):
+ ListBox(listModel),
+ mPlayerMoney(0),
+ mShopItems(shopListModel)
+{
+ mRowHeight = std::max(getFont()->getHeight(), ITEM_ICON_SIZE);
+ mPriceCheck = true;
+
+ mItemPopup = new ItemPopup;
+}
+
+void ShopListBox::setPlayersMoney(int money)
+{
+ mPlayerMoney = money;
+}
+
+void ShopListBox::draw(gcn::Graphics *gcnGraphics)
+{
+ if (!mListModel || !mShopItems)
+ return;
+
+ if (Client::getGuiAlpha() != mAlpha)
+ mAlpha = Client::getGuiAlpha();
+
+ int alpha = static_cast<int>(mAlpha * 255.0f);
+ const gcn::Color* highlightColor =
+ &Theme::getThemeColor(Theme::HIGHLIGHT, alpha);
+
+ Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
+
+ graphics->setFont(getFont());
+
+ // Draw the list elements
+ for (int i = 0, y = 0;
+ i < mListModel->getNumberOfElements();
+ ++i, y += mRowHeight)
+ {
+ gcn::Color temp;
+ const gcn::Color* backgroundColor =
+ &Theme::getThemeColor(Theme::BACKGROUND, alpha);
+
+ if (mShopItems && mShopItems->at(i) &&
+ mPlayerMoney < mShopItems->at(i)->getPrice() && mPriceCheck)
+ {
+ if (i != mSelected)
+ {
+ backgroundColor = &Theme::getThemeColor(Theme::SHOP_WARNING,
+ alpha);
+ }
+ else
+ {
+ temp = Theme::getThemeColor(Theme::SHOP_WARNING, alpha);
+ temp.r = (temp.r + highlightColor->r) / 2;
+ temp.g = (temp.g + highlightColor->g) / 2;
+ temp.b = (temp.g + highlightColor->b) / 2;
+ backgroundColor = &temp;
+ }
+ }
+ else if (i == mSelected)
+ {
+ backgroundColor = highlightColor;
+ }
+
+ graphics->setColor(*backgroundColor);
+ graphics->fillRectangle(gcn::Rectangle(0, y, getWidth(), mRowHeight));
+
+ if (mShopItems)
+ {
+ Image *icon = mShopItems->at(i)->getImage();
+ if (icon)
+ {
+ icon->setAlpha(1.0f);
+ graphics->drawImage(icon, 1, y);
+ }
+ }
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ graphics->drawText(mListModel->getElementAt(i), ITEM_ICON_SIZE + 5,
+ y + (ITEM_ICON_SIZE - getFont()->getHeight()) / 2);
+ }
+}
+
+void ShopListBox::adjustSize()
+{
+ if (mListModel)
+ setHeight(mRowHeight * mListModel->getNumberOfElements());
+}
+
+void ShopListBox::setPriceCheck(bool check)
+{
+ mPriceCheck = check;
+}
+
+void ShopListBox::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!mItemPopup)
+ return;
+
+ if (!mShopItems)
+ {
+ mItemPopup->hide();
+ return;
+ }
+
+ int index = event.getY() / mRowHeight;
+
+ if (index < 0 || index >= mShopItems->getNumberOfElements())
+ {
+ mItemPopup->hide();
+ }
+ else
+ {
+ Item *item = mShopItems->at(index);
+ if (item)
+ {
+ mItemPopup->setItem(item);
+ mItemPopup->position(viewport->getMouseX(), viewport->getMouseY());
+ }
+ else
+ {
+ mItemPopup->setVisible(false);
+ }
+ }
+}
+
+void ShopListBox::mouseExited(gcn::MouseEvent& mouseEvent _UNUSED_)
+{
+ if (!mItemPopup)
+ return;
+
+ mItemPopup->hide();
+} \ No newline at end of file
diff --git a/src/gui/widgets/shoplistbox.h b/src/gui/widgets/shoplistbox.h
new file mode 100644
index 000000000..ab77c5969
--- /dev/null
+++ b/src/gui/widgets/shoplistbox.h
@@ -0,0 +1,104 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SHOPLISTBOX_H
+#define SHOPLISTBOX_H
+
+#include "gui/widgets/listbox.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class ShopItems;
+class ItemPopup;
+
+/**
+ * A list box, meant to be used inside a scroll area. Same as the Guichan list
+ * box except this one doesn't have a background, instead completely relying
+ * on the scroll area. It also adds selection listener functionality.
+ *
+ * \ingroup GUI
+ */
+class ShopListBox : public ListBox
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ShopListBox(gcn::ListModel *listModel);
+
+ /**
+ * Constructor with shopitems
+ */
+ ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel);
+
+ /**
+ * Draws the list box.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Returns the height of a row.
+ */
+ unsigned int getRowHeight() const { return mRowHeight; }
+
+ /**
+ * gives information about the current player's money
+ */
+ void setPlayersMoney(int money);
+
+ /**
+ * Adjust List draw size
+ */
+ void adjustSize();
+
+ /**
+ * Set on/off the disabling of too expensive items.
+ * (Good for selling mode.)
+ */
+ void setPriceCheck(bool check);
+
+ void mouseMoved(gcn::MouseEvent &event);
+
+ void mouseExited(gcn::MouseEvent& mouseEvent _UNUSED_);
+
+ private:
+ int mPlayerMoney;
+
+ /**
+ * Keeps another pointer to the same listModel, permitting to
+ * use the ShopItems specific functions.
+ */
+ ShopItems *mShopItems;
+
+ ItemPopup *mItemPopup;
+
+ unsigned int mRowHeight; /**< Row Height */
+
+ static float mAlpha;
+
+ bool mPriceCheck;
+};
+
+#endif // SHOPLISTBOX_H
diff --git a/src/gui/widgets/shortcutcontainer.cpp b/src/gui/widgets/shortcutcontainer.cpp
new file mode 100644
index 000000000..167296410
--- /dev/null
+++ b/src/gui/widgets/shortcutcontainer.cpp
@@ -0,0 +1,67 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/shortcutcontainer.h"
+
+#include "configuration.h"
+
+#include "resources/image.h"
+
+#include "utils/stringutils.h"
+
+float ShortcutContainer::mAlpha = 1.0;
+
+ShortcutContainer::ShortcutContainer():
+ mGridWidth(1),
+ mGridHeight(1)
+{
+}
+
+void ShortcutContainer::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ mGridWidth = getWidth() / mBoxWidth;
+
+ if (mGridWidth < 1)
+ mGridWidth = 1;
+
+ mGridHeight = mMaxItems / mGridWidth;
+
+ if (mMaxItems % mGridWidth != 0 || mGridHeight < 1)
+ ++mGridHeight;
+
+ setHeight(mGridHeight * mBoxHeight);
+}
+
+int ShortcutContainer::getIndexFromGrid(int pointX, int pointY) const
+{
+ const gcn::Rectangle tRect = gcn::Rectangle(0, 0, mGridWidth * mBoxWidth,
+ mGridHeight * mBoxHeight);
+
+ int index = ((pointY / mBoxHeight) * mGridWidth) + pointX / mBoxWidth;
+
+ if (!tRect.isPointInRect(pointX, pointY) ||
+ index >= (int)mMaxItems || index < 0)
+ {
+ index = -1;
+ }
+
+ return index;
+}
diff --git a/src/gui/widgets/shortcutcontainer.h b/src/gui/widgets/shortcutcontainer.h
new file mode 100644
index 000000000..85d08d0b4
--- /dev/null
+++ b/src/gui/widgets/shortcutcontainer.h
@@ -0,0 +1,115 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SHORTCUTCONTAINER_H
+#define SHORTCUTCONTAINER_H
+
+#include <guichan/mouselistener.hpp>
+#include <guichan/widget.hpp>
+#include <guichan/widgetlistener.hpp>
+
+#include "gui/widgets/tab.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+
+/**
+ * A generic shortcut container.
+ *
+ * \ingroup GUI
+ */
+class ShortcutContainer : public gcn::Widget,
+ public gcn::WidgetListener,
+ public gcn::MouseListener
+{
+ public:
+ /**
+ * Constructor. Initializes the shortcut container.
+ */
+ ShortcutContainer();
+
+ /**
+ * Destructor.
+ */
+ ~ShortcutContainer() {}
+
+ /**
+ * Draws the shortcuts
+ */
+ virtual void draw(gcn::Graphics *graphics) = 0;
+
+ /**
+ * Invoked when a widget changes its size. This is used to determine
+ * the new height of the container.
+ */
+ virtual void widgetResized(const gcn::Event &event);
+
+ /**
+ * Handles mouse when dragged.
+ */
+ virtual void mouseDragged(gcn::MouseEvent &event) = 0;
+
+ /**
+ * Handles mouse when pressed.
+ */
+ virtual void mousePressed(gcn::MouseEvent &event) = 0;
+
+ /**
+ * Handles mouse release.
+ */
+ virtual void mouseReleased(gcn::MouseEvent &event) = 0;
+
+ int getMaxItems() const
+ { return mMaxItems; }
+
+ int getBoxWidth() const
+ { return mBoxWidth; }
+
+ int getBoxHeight() const
+ { return mBoxHeight; }
+
+ protected:
+ /**
+ * Gets the index from the grid provided the point is in an item box.
+ *
+ * @param pointX X coordinate of the point.
+ * @param pointY Y coordinate of the point.
+ * @return index on success, -1 on failure.
+ */
+ int getIndexFromGrid(int pointX, int pointY) const;
+
+ Image *mBackgroundImg;
+
+ static float mAlpha;
+
+ unsigned mMaxItems;
+ int mBoxWidth;
+ int mBoxHeight;
+ int mCursorPosX, mCursorPosY;
+ int mGridWidth, mGridHeight;
+};
+
+#endif
diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp
new file mode 100644
index 000000000..9513d5308
--- /dev/null
+++ b/src/gui/widgets/slider.cpp
@@ -0,0 +1,298 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/slider.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+Image *Slider::hStart, *Slider::hMid, *Slider::hEnd, *Slider::hGrip;
+Image *Slider::vStart, *Slider::vMid, *Slider::vEnd, *Slider::vGrip;
+Image *Slider::hStartHi, *Slider::hMidHi, *Slider::hEndHi, *Slider::hGripHi;
+Image *Slider::vStartHi, *Slider::vMidHi, *Slider::vEndHi, *Slider::vGripHi;
+float Slider::mAlpha = 1.0;
+int Slider::mInstances = 0;
+
+Slider::Slider(double scaleEnd):
+ gcn::Slider(scaleEnd),
+ mHasMouse(false)
+{
+ init();
+}
+
+Slider::Slider(double scaleStart, double scaleEnd):
+ gcn::Slider(scaleStart, scaleEnd),
+ mHasMouse(false)
+{
+ init();
+}
+
+Slider::~Slider()
+{
+ mInstances--;
+
+ if (mInstances == 0)
+ {
+ delete hStart;
+ delete hMid;
+ delete hEnd;
+ delete hGrip;
+ delete vStart;
+ delete vMid;
+ delete vEnd;
+ delete vGrip;
+ delete hStartHi;
+ delete hMidHi;
+ delete hEndHi;
+ delete hGripHi;
+ delete vStartHi;
+ delete vMidHi;
+ delete vEndHi;
+ delete vGripHi;
+ }
+}
+
+void Slider::init()
+{
+ setFrameSize(0);
+
+ // Load resources
+ if (mInstances == 0)
+ {
+ int x, y, w, h, o1, o2;
+
+ Image *slider = Theme::getImageFromTheme("slider.png");
+ Image *sliderHi = Theme::getImageFromTheme("slider_hilight.png");
+
+ x = 0; y = 0;
+ w = 15; h = 6;
+ o1 = 4; o2 = 11;
+ if (slider)
+ {
+ hStart = slider->getSubImage(x, y, o1 - x, h);
+ hMid = slider->getSubImage(o1, y, o2 - o1, h);
+ hEnd = slider->getSubImage(o2, y, w - o2 + x, h);
+ }
+ else
+ {
+ hStart = 0;
+ hMid = 0;
+ hEnd = 0;
+ }
+ if (sliderHi)
+ {
+ hStartHi = sliderHi->getSubImage(x, y, o1 - x, h);
+ hMidHi = sliderHi->getSubImage(o1, y, o2 - o1, h);
+ hEndHi = sliderHi->getSubImage(o2, y, w - o2 + x, h);
+ }
+ else
+ {
+ hStartHi = 0;
+ hMidHi = 0;
+ hEndHi = 0;
+ }
+
+ x = 6; y = 8;
+ w = 9; h = 10;
+ if (slider)
+ hGrip = slider->getSubImage(x, y, w, h);
+ else
+ hGrip = 0;
+ if (sliderHi)
+ hGripHi = sliderHi->getSubImage(x, y, w, h);
+ else
+ hGripHi = 0;
+
+ x = 0; y = 6;
+ w = 6; h = 21;
+ o1 = 10; o2 = 18;
+ if (slider)
+ {
+ vStart = slider->getSubImage(x, y, w, o1 - y);
+ vMid = slider->getSubImage(x, o1, w, o2 - o1);
+ vEnd = slider->getSubImage(x, o2, w, h - o2 + y);
+ }
+ else
+ {
+ vStart = 0;
+ vMid = 0;
+ vEnd = 0;
+ }
+ if (sliderHi)
+ {
+ vStartHi = sliderHi->getSubImage(x, y, w, o1 - y);
+ vMidHi = sliderHi->getSubImage(x, o1, w, o2 - o1);
+ vEndHi = sliderHi->getSubImage(x, o2, w, h - o2 + y);
+ }
+ else
+ {
+ vStartHi = 0;
+ vMidHi = 0;
+ vEndHi = 0;
+ }
+
+ x = 6; y = 8;
+ w = 9; h = 10;
+ if (slider)
+ vGrip = slider->getSubImage(x, y, w, h);
+ else
+ vGrip = 0;
+
+ if (sliderHi)
+ vGripHi = sliderHi->getSubImage(x, y, w, h);
+ else
+ vGripHi = 0;
+
+ if (slider)
+ slider->decRef();
+ if (sliderHi)
+ sliderHi->decRef();
+ }
+
+ mInstances++;
+
+ if (hGrip)
+ setMarkerLength(hGrip->getWidth());
+}
+
+void Slider::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (alpha != mAlpha)
+ {
+ mAlpha = alpha;
+ if (hStart)
+ hStart->setAlpha(mAlpha);
+ if (hMid)
+ hMid->setAlpha(mAlpha);
+ if (hEnd)
+ hEnd->setAlpha(mAlpha);
+ if (hGrip)
+ hGrip->setAlpha(mAlpha);
+ if (hStartHi)
+ hStartHi->setAlpha(mAlpha);
+ if (hMidHi)
+ hMidHi->setAlpha(mAlpha);
+ if (hEndHi)
+ hEndHi->setAlpha(mAlpha);
+ if (hGripHi)
+ hGripHi->setAlpha(mAlpha);
+
+ if (vStart)
+ vStart->setAlpha(mAlpha);
+ if (vMid)
+ vMid->setAlpha(mAlpha);
+ if (vEnd)
+ vEnd->setAlpha(mAlpha);
+ if (vGrip)
+ vGrip->setAlpha(mAlpha);
+ if (vStartHi)
+ vStartHi->setAlpha(mAlpha);
+ if (vMidHi)
+ vMidHi->setAlpha(mAlpha);
+ if (vEndHi)
+ vEndHi->setAlpha(mAlpha);
+ if (vGripHi)
+ vGripHi->setAlpha(mAlpha);
+ }
+
+}
+
+void Slider::draw(gcn::Graphics *graphics)
+{
+ if (!hStart || !hStartHi)
+ return;
+
+ int w = getWidth();
+ int h = getHeight();
+ int x = 0;
+ int y = mHasMouse ? (h - hStartHi->getHeight()) / 2 :
+ (h - hStart->getHeight()) / 2;
+
+ updateAlpha();
+
+ if (!mHasMouse)
+ {
+ static_cast<Graphics*>(graphics)->drawImage(hStart, x, y);
+
+ w -= hStart->getWidth() + hEnd->getWidth();
+ x += hStart->getWidth();
+
+ if (hMid)
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImagePattern(hMid, x, y, w, hMid->getHeight());
+ }
+
+ x += w;
+ if (hEnd)
+ static_cast<Graphics*>(graphics)->drawImage(hEnd, x, y);
+ }
+ else
+ {
+ static_cast<Graphics*>(graphics)->drawImage(hStartHi, x, y);
+
+ w -= hStartHi->getWidth();
+ if (hEndHi)
+ w -= hEndHi->getWidth();
+ x += hStartHi->getWidth();
+
+ if (hMidHi)
+ {
+ static_cast<Graphics*>(graphics)->
+ drawImagePattern(hMidHi, x, y, w, hMidHi->getHeight());
+ }
+
+ x += w;
+ if (hEndHi)
+ static_cast<Graphics*>(graphics)->drawImage(hEndHi, x, y);
+ }
+
+ drawMarker(graphics);
+}
+
+void Slider::drawMarker(gcn::Graphics *graphics)
+{
+ if (!(mHasMouse?hGripHi:hGrip))
+ return;
+
+ static_cast<Graphics*>(graphics)->
+ drawImage(mHasMouse?hGripHi:hGrip, getMarkerPosition(),
+ (getHeight() - (mHasMouse?hGripHi:hGrip)->getHeight()) / 2);
+}
+
+void Slider::mouseEntered(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = true;
+}
+
+void Slider::mouseExited(gcn::MouseEvent& event _UNUSED_)
+{
+ mHasMouse = false;
+}
+
diff --git a/src/gui/widgets/slider.h b/src/gui/widgets/slider.h
new file mode 100644
index 000000000..be27b73f1
--- /dev/null
+++ b/src/gui/widgets/slider.h
@@ -0,0 +1,98 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SLIDER_H
+#define SLIDER_H
+
+#include <guichan/widgets/slider.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+
+/**
+ * Slider widget. Same as the Guichan slider but with custom look.
+ *
+ * \ingroup GUI
+ */
+class Slider : public gcn::Slider
+{
+ public:
+ /**
+ * Constructor with scale start equal to 0.
+ */
+ Slider(double scaleEnd = 1.0);
+
+ /**
+ * Constructor.
+ */
+ Slider(double scaleStart, double scaleEnd);
+
+ /**
+ * Destructor.
+ */
+ ~Slider();
+
+ /**
+ * Update the alpha value to the graphic components.
+ */
+ void updateAlpha();
+
+ /**
+ * Draws the slider.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Draws the marker.
+ */
+ void drawMarker(gcn::Graphics *graphics);
+
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
+ private:
+ /**
+ * Used to initialize instances.
+ */
+ void init();
+
+ static Image *hStart, *hMid, *hEnd, *hGrip;
+ static Image *vStart, *vMid, *vEnd, *vGrip;
+ static Image *hStartHi, *hMidHi, *hEndHi, *hGripHi;
+ static Image *vStartHi, *vMidHi, *vEndHi, *vGripHi;
+ bool mHasMouse;
+ static float mAlpha;
+ static int mInstances;
+};
+
+#endif
diff --git a/src/gui/widgets/spellshortcutcontainer.cpp b/src/gui/widgets/spellshortcutcontainer.cpp
new file mode 100644
index 000000000..18482369d
--- /dev/null
+++ b/src/gui/widgets/spellshortcutcontainer.cpp
@@ -0,0 +1,285 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/widgets/spellshortcutcontainer.h"
+
+#include "gui/inventorywindow.h"
+#include "gui/okdialog.h"
+#include "gui/palette.h"
+#include "gui/shortcutwindow.h"
+#include "gui/spellpopup.h"
+#include "gui/viewport.h"
+#include "gui/textcommandeditor.h"
+#include "gui/theme.h"
+
+#include "configuration.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "spellshortcut.h"
+#include "itemshortcut.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "spellmanager.h"
+#include "log.h"
+
+#include "resources/image.h"
+#include "textcommand.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+SpellShortcutContainer::SpellShortcutContainer():
+ ShortcutContainer(),
+ mSpellClicked(false),
+ mSpellMoved(NULL)
+{
+ mBoxWidth = mBoxWidth;
+
+ addMouseListener(this);
+ addWidgetListener(this);
+
+ mSpellPopup = new SpellPopup;
+
+ mBackgroundImg = Theme::getImageFromTheme("item_shortcut_bgr.png");
+ if (spellShortcut)
+ mMaxItems = spellShortcut->getSpellsCount();
+ else
+ mMaxItems = 0;
+
+ if (mBackgroundImg)
+ {
+ mBackgroundImg->setAlpha(Client::getGuiAlpha());
+ mBoxHeight = mBackgroundImg->getHeight();
+ mBoxWidth = mBackgroundImg->getWidth();
+ }
+ else
+ {
+ mBoxHeight = 1;
+ mBoxWidth = 1;
+ }
+}
+
+SpellShortcutContainer::~SpellShortcutContainer()
+{
+ if (mBackgroundImg)
+ mBackgroundImg->decRef();
+ mBackgroundImg = 0;
+ delete mSpellPopup;
+ mSpellPopup = 0;
+}
+
+void SpellShortcutContainer::draw(gcn::Graphics *graphics)
+{
+ if (!spellShortcut)
+ return;
+
+ if (Client::getGuiAlpha() != mAlpha)
+ {
+ mAlpha = Client::getGuiAlpha();
+ if (mBackgroundImg)
+ mBackgroundImg->setAlpha(mAlpha);
+ }
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ graphics->setColor(gcn::Color(0, 0, 0, 255));
+ graphics->setFont(getFont());
+
+ int selectedId = spellShortcut->getSelectedItem();
+ g->setColor(Theme::getThemeColor(Theme::TEXT));
+
+ for (unsigned i = 0; i < mMaxItems; i++)
+ {
+ const int itemX = (i % mGridWidth) * mBoxWidth;
+ const int itemY = (i / mGridWidth) * mBoxHeight;
+
+ g->drawImage(mBackgroundImg, itemX, itemY);
+
+ int itemId = spellShortcut->getItem(i);
+ if (selectedId >= 0 && itemId == selectedId)
+ {
+ g->drawRectangle(gcn::Rectangle(
+ itemX + 1, itemY + 1,
+ mBoxWidth - 1, mBoxHeight - 1));
+ }
+
+ if (!spellManager)
+ continue;
+
+ TextCommand *spell = spellManager->getSpell(itemId);
+ if (spell)
+ {
+ if (!spell->isEmpty())
+ {
+ Image* image = spell->getImage();
+
+ if (image)
+ {
+ image->setAlpha(1.0f);
+ g->drawImage(image, itemX, itemY);
+ }
+ }
+
+ g->drawText(spell->getSymbol(), itemX + 2,
+ itemY + mBoxHeight / 2, gcn::Graphics::LEFT);
+ }
+ }
+
+ if (mSpellMoved)
+ {
+ // Draw the item image being dragged by the cursor.
+ }
+
+}
+
+void SpellShortcutContainer::mouseDragged(gcn::MouseEvent &event)
+{
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (!mSpellMoved && mSpellClicked)
+ {
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ const int itemId = spellShortcut->getItem(index);
+
+ if (itemId < 0)
+ return;
+ }
+ if (mSpellMoved)
+ {
+ mCursorPosX = event.getX();
+ mCursorPosY = event.getY();
+ }
+ }
+}
+
+void SpellShortcutContainer::mousePressed(gcn::MouseEvent &event)
+{
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ // Stores the selected item if theirs one.
+ }
+ else if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ }
+ else if (event.getButton() == gcn::MouseEvent::MIDDLE)
+ {
+ if (!spellShortcut || !spellManager)
+ return;
+
+ const int itemId = spellShortcut->getItem(index);
+ spellManager->invoke(itemId);
+ }
+}
+
+void SpellShortcutContainer::mouseReleased(gcn::MouseEvent &event)
+{
+ if (!spellShortcut || !spellManager)
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ const int itemId = spellShortcut->getItem(index);
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (itemId < 0)
+ return;
+
+ const int selectedId = spellShortcut->getSelectedItem();
+
+ if (selectedId != itemId)
+ {
+ TextCommand *spell = spellManager->getSpell(itemId);
+ if (spell && !spell->isEmpty())
+ {
+ int num = itemShortcutWindow->getTabIndex();
+ if (num >= 0 && num < SHORTCUT_TABS && itemShortcut[num])
+ {
+ itemShortcut[num]->setItemSelected(
+ spell->getId() + SPELL_MIN_ID);
+ }
+ spellShortcut->setItemSelected(spell->getId());
+ }
+ }
+ else
+ {
+ int num = itemShortcutWindow->getTabIndex();
+ if (num >= 0 && num < SHORTCUT_TABS && itemShortcut[num])
+ itemShortcut[num]->setItemSelected(-1);
+ spellShortcut->setItemSelected(-1);
+ }
+ }
+ else if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ TextCommand *spell = NULL;
+ if (itemId >= 0)
+ spell = spellManager->getSpell(itemId);
+
+ if (spell && viewport)
+ viewport->showSpellPopup(spell);
+ }
+}
+
+// Show ItemTooltip
+void SpellShortcutContainer::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!mSpellPopup || !spellShortcut || !spellManager)
+ return;
+
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+
+ if (index == -1)
+ return;
+
+ const int itemId = spellShortcut->getItem(index);
+
+ mSpellPopup->setVisible(false);
+ TextCommand *spell = spellManager->getSpell(itemId);
+ if (spell && !spell->isEmpty())
+ {
+ mSpellPopup->setItem(spell);
+ mSpellPopup->view(viewport->getMouseX(), viewport->getMouseY());
+ }
+ else
+ {
+ mSpellPopup->setVisible(false);
+ }
+}
+
+// Hide SpellTooltip
+void SpellShortcutContainer::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ mSpellPopup->setVisible(false);
+}
diff --git a/src/gui/widgets/spellshortcutcontainer.h b/src/gui/widgets/spellshortcutcontainer.h
new file mode 100644
index 000000000..8f1c4b221
--- /dev/null
+++ b/src/gui/widgets/spellshortcutcontainer.h
@@ -0,0 +1,88 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SPELLSHORTCUTCONTAINER_H
+#define SPELLSHORTCUTCONTAINER_H
+
+#include <guichan/mouselistener.hpp>
+
+#include "gui/widgets/shortcutcontainer.h"
+//#include "textcommand.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Image;
+class SpellPopup;
+class TextCommand;
+
+/**
+ * An item shortcut container. Used to quickly use items.
+ *
+ * \ingroup GUI
+ */
+class SpellShortcutContainer : public ShortcutContainer
+{
+ public:
+ /**
+ * Constructor. Initializes the graphic.
+ */
+ SpellShortcutContainer();
+
+ /**
+ * Destructor.
+ */
+ virtual ~SpellShortcutContainer();
+
+ /**
+ * Draws the items.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Handles mouse when dragged.
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse when pressed.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse release.
+ */
+ void mouseReleased(gcn::MouseEvent &event);
+
+ private:
+ void mouseExited(gcn::MouseEvent &event);
+ void mouseMoved(gcn::MouseEvent &event);
+
+ bool mSpellClicked;
+ TextCommand *mSpellMoved;
+ SpellPopup *mSpellPopup;
+};
+
+#endif
diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp
new file mode 100644
index 000000000..43b1d154e
--- /dev/null
+++ b/src/gui/widgets/tab.cpp
@@ -0,0 +1,196 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/tab.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+
+#include "gui/palette.h"
+#include "gui/theme.h"
+
+#include "gui/widgets/tabbedarea.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+#include <guichan/widgets/label.hpp>
+
+int Tab::mInstances = 0;
+float Tab::mAlpha = 1.0;
+
+enum
+{
+ TAB_STANDARD = 0, // 0
+ TAB_HIGHLIGHTED, // 1
+ TAB_SELECTED, // 2
+ TAB_UNUSED, // 3
+ TAB_COUNT // 4 - Must be last.
+};
+
+struct TabData
+{
+ char const *file;
+ int gridX;
+ int gridY;
+};
+
+static TabData const data[TAB_COUNT] =
+{
+ { "tab.png", 0, 0 },
+ { "tab_hilight.png", 9, 4 },
+ { "tabselected.png", 16, 19 },
+ { "tab.png", 25, 23 }
+};
+
+ImageRect Tab::tabImg[TAB_COUNT];
+
+Tab::Tab() : gcn::Tab(),
+ mTabColor(&Theme::getThemeColor(Theme::TAB))
+{
+ init();
+}
+
+Tab::~Tab()
+{
+ mInstances--;
+
+ if (mInstances == 0)
+ {
+ for (int mode = 0; mode < TAB_COUNT; mode++)
+ for_each(tabImg[mode].grid, tabImg[mode].grid + 9, dtor<Image*>());
+ }
+}
+
+void Tab::init()
+{
+ setFocusable(false);
+ setFrameSize(0);
+ mFlash = 0;
+
+ if (mInstances == 0)
+ {
+ // Load the skin
+ Image *tab[TAB_COUNT];
+
+ int a, x, y, mode;
+
+ for (mode = 0; mode < TAB_COUNT; mode++)
+ {
+ tab[mode] = Theme::getImageFromTheme(data[mode].file);
+ a = 0;
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ tabImg[mode].grid[a] = tab[mode]->getSubImage(
+ data[x].gridX, data[y].gridY,
+ data[x + 1].gridX - data[x].gridX + 1,
+ data[y + 1].gridY - data[y].gridY + 1);
+ if (tabImg[mode].grid[a])
+ tabImg[mode].grid[a]->setAlpha(mAlpha);
+ a++;
+ }
+ }
+ if (tab[mode])
+ tab[mode]->decRef();
+ }
+ }
+ mInstances++;
+}
+
+void Tab::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ // TODO We don't need to do this for every tab on every draw
+ // Maybe use a config listener to do it as the value changes.
+ if (alpha != mAlpha)
+ {
+ mAlpha = alpha;
+ for (int a = 0; a < 9; a++)
+ {
+ for (int t = 0; t < TAB_COUNT; t++)
+ {
+ if (tabImg[t].grid[a])
+ tabImg[t].grid[a]->setAlpha(mAlpha);
+ }
+ }
+ }
+}
+
+void Tab::draw(gcn::Graphics *graphics)
+{
+ int mode = TAB_STANDARD;
+
+ // check which type of tab to draw
+ if (mTabbedArea)
+ {
+ mLabel->setForegroundColor(*mTabColor);
+ if (mTabbedArea->isTabSelected(this))
+ {
+ mode = TAB_SELECTED;
+ // if tab is selected, it doesnt need to highlight activity
+ mFlash = 0;
+ }
+ else if (mHasMouse)
+ {
+ mode = TAB_HIGHLIGHTED;
+ }
+
+ switch (mFlash)
+ {
+ case 1:
+ mLabel->setForegroundColor(Theme::getThemeColor(
+ Theme::TAB_FLASH));
+ break;
+ case 2:
+ mLabel->setForegroundColor(Theme::getThemeColor(
+ Theme::TAB_PLAYER_FLASH));
+ break;
+ default:
+ break;
+ }
+ }
+
+ updateAlpha();
+
+ // draw tab
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(0, 0, getWidth(), getHeight(), tabImg[mode]);
+
+ // draw label
+ drawChildren(graphics);
+}
+
+void Tab::setTabColor(const gcn::Color *color)
+{
+ mTabColor = color;
+}
+
+void Tab::setFlash(int flash)
+{
+ mFlash = flash;
+}
diff --git a/src/gui/widgets/tab.h b/src/gui/widgets/tab.h
new file mode 100644
index 000000000..b76717bcd
--- /dev/null
+++ b/src/gui/widgets/tab.h
@@ -0,0 +1,80 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TAB_H
+#define TAB_H
+
+#include <guichan/widgets/tab.hpp>
+
+class ImageRect;
+class TabbedArea;
+
+/**
+ * A tab, the same as the Guichan tab in 0.8, but extended to allow
+ * transparency.
+ */
+class Tab : public gcn::Tab
+{
+ public:
+ Tab();
+ ~Tab();
+
+ /**
+ * Update the alpha value to the graphic components.
+ */
+ void updateAlpha();
+
+ /**
+ * Draw the tabbed area.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Set the normal color fo the tab's text.
+ */
+ void setTabColor(const gcn::Color *color);
+
+ /**
+ * Set tab flashing state
+ */
+ void setFlash(int flash);
+
+ int getFlash()
+ { return mFlash; }
+
+ protected:
+ friend class TabbedArea;
+ virtual void setCurrent()
+ { }
+
+ private:
+ /** Load images if no other instances exist yet */
+ void init();
+
+ static ImageRect tabImg[4]; /**< Tab state graphics */
+ static int mInstances; /**< Number of tab instances */
+ static float mAlpha;
+
+ const gcn::Color *mTabColor;
+ int mFlash;
+};
+
+#endif
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp
new file mode 100644
index 000000000..232664860
--- /dev/null
+++ b/src/gui/widgets/tabbedarea.cpp
@@ -0,0 +1,221 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/tabbedarea.h"
+
+#include "gui/widgets/tab.h"
+
+#include "log.h"
+
+#include <guichan/widgets/container.hpp>
+
+TabbedArea::TabbedArea() : gcn::TabbedArea()
+{
+ mWidgetContainer->setOpaque(false);
+ addWidgetListener(this);
+
+ widgetResized(NULL);
+}
+
+int TabbedArea::getNumberOfTabs() const
+{
+ return static_cast<int>(mTabs.size());
+}
+
+Tab *TabbedArea::getTab(const std::string &name) const
+{
+ TabContainer::const_iterator itr = mTabs.begin(), itr_end = mTabs.end();
+ while (itr != itr_end)
+ {
+ if ((*itr).first->getCaption() == name)
+ return static_cast<Tab*>((*itr).first);
+
+ ++itr;
+ }
+ return NULL;
+}
+
+void TabbedArea::draw(gcn::Graphics *graphics)
+{
+ if (mTabs.empty())
+ return;
+
+ drawChildren(graphics);
+}
+
+gcn::Widget *TabbedArea::getWidget(const std::string &name) const
+{
+ TabContainer::const_iterator itr = mTabs.begin(), itr_end = mTabs.end();
+ while (itr != itr_end)
+ {
+ if ((*itr).first->getCaption() == name)
+ return (*itr).second;
+
+ ++itr;
+ }
+
+ return NULL;
+}
+
+gcn::Widget *TabbedArea::getCurrentWidget()
+{
+ gcn::Tab *tab = getSelectedTab();
+
+ if (tab)
+ return getWidget(tab->getCaption());
+ else
+ return NULL;
+}
+
+void TabbedArea::addTab(gcn::Tab* tab, gcn::Widget* widget)
+{
+ if (!tab || !widget)
+ return;
+
+ gcn::TabbedArea::addTab(tab, widget);
+
+ int width = getWidth() - 2 * getFrameSize();
+ int height = getHeight() - 2 * getFrameSize() - mTabContainer->getHeight();
+ widget->setSize(width, height);
+}
+
+void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget)
+{
+ Tab *tab = new Tab;
+ tab->setCaption(caption);
+ mTabsToDelete.push_back(tab);
+
+ addTab(tab, widget);
+}
+
+void TabbedArea::removeTab(Tab *tab)
+{
+ int tabIndexToBeSelected = -1;
+
+ if (tab == mSelectedTab)
+ {
+ int index = getSelectedTabIndex();
+
+ if (index == static_cast<int>(mTabs.size()) - 1 && mTabs.size() == 1)
+ tabIndexToBeSelected = -1;
+ else
+ tabIndexToBeSelected = index - 1;
+ }
+
+ TabContainer::iterator iter;
+ for (iter = mTabs.begin(); iter != mTabs.end(); iter++)
+ {
+ if (iter->first == tab)
+ {
+ mTabContainer->remove(tab);
+ mTabs.erase(iter);
+ break;
+ }
+ }
+
+ std::vector<gcn::Tab*>::iterator iter2;
+ for (iter2 = mTabsToDelete.begin(); iter2 != mTabsToDelete.end(); iter2++)
+ {
+ if (*iter2 == tab)
+ {
+ mTabsToDelete.erase(iter2);
+ delete tab;
+ break;
+ }
+ }
+
+ if (tabIndexToBeSelected >= (signed)mTabs.size())
+ tabIndexToBeSelected = mTabs.size() - 1;
+ if (tabIndexToBeSelected < -1)
+ tabIndexToBeSelected = -1;
+
+ if (tabIndexToBeSelected == -1)
+ {
+ mSelectedTab = 0;
+ mWidgetContainer->clear();
+ }
+ else
+ {
+ setSelectedTab(tabIndexToBeSelected);
+ }
+
+ adjustSize();
+ adjustTabPositions();
+}
+
+void TabbedArea::logic()
+{
+ logicChildren();
+}
+
+void TabbedArea::mousePressed(gcn::MouseEvent &mouseEvent)
+{
+ if (mouseEvent.isConsumed())
+ return;
+
+ if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
+ {
+ gcn::Widget *widget = mTabContainer->getWidgetAt(mouseEvent.getX(),
+ mouseEvent.getY());
+ gcn::Tab *tab = dynamic_cast<gcn::Tab*>(widget);
+
+ if (tab)
+ {
+ setSelectedTab(tab);
+ requestFocus();
+ }
+ }
+}
+
+void TabbedArea::setSelectedTab(gcn::Tab *tab)
+{
+ gcn::TabbedArea::setSelectedTab(tab);
+
+ Tab *newTab = dynamic_cast<Tab*>(tab);
+
+ if (newTab)
+ newTab->setCurrent();
+
+ widgetResized(NULL);
+}
+
+void TabbedArea::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ int width = getWidth() - 2 * getFrameSize()
+ - 2 * mWidgetContainer->getFrameSize();
+ int height = getHeight() - 2 * getFrameSize() - mWidgetContainer->getY()
+ - 2 * mWidgetContainer->getFrameSize();
+ mWidgetContainer->setSize(width, height);
+
+ gcn::Widget *w = getCurrentWidget();
+ if (w)
+ w->setSize(width, height);
+}
+
+/*
+void TabbedArea::moveLeft(gcn::Tab *tab)
+{
+}
+
+void TabbedArea::moveRight(gcn::Tab *tab)
+{
+}
+*/
diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h
new file mode 100644
index 000000000..de2ae4b0a
--- /dev/null
+++ b/src/gui/widgets/tabbedarea.h
@@ -0,0 +1,129 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TABBEDAREA_H
+#define TABBEDAREA_H
+
+#include <guichan/widget.hpp>
+#include <guichan/widgetlistener.hpp>
+#include <guichan/widgets/container.hpp>
+#include <guichan/widgets/tabbedarea.hpp>
+
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Tab;
+
+/**
+ * A tabbed area, the same as the guichan tabbed area in 0.8, but extended
+ */
+class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ TabbedArea();
+
+ /**
+ * Draw the tabbed area.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Return how many tabs have been created.
+ *
+ * @todo Remove this method when upgrading to Guichan 0.9.0
+ */
+ int getNumberOfTabs() const;
+
+ /**
+ * Return tab with specified name as caption.
+ */
+ Tab *getTab(const std::string &name) const;
+
+ /**
+ * Returns the widget with the tab that has specified caption
+ */
+ gcn::Widget *getWidget(const std::string &name) const;
+
+ /**
+ * Returns the widget for the current tab
+ */
+ gcn::Widget *getCurrentWidget();
+
+ using gcn::TabbedArea::addTab;
+
+ /**
+ * Add a tab. Overridden since it needs to size the widget.
+ *
+ * @param tab The tab widget for the tab.
+ * @param widget The widget to view when the tab is selected.
+ */
+ void addTab(gcn::Tab* tab, gcn::Widget* widget);
+
+ /**
+ * Add a tab. Overridden since it needs to create an instance of Tab
+ * instead of gcn::Tab.
+ *
+ * @param caption The Caption to display
+ * @param widget The widget to show when tab is selected
+ */
+ void addTab(const std::string &caption, gcn::Widget *widget);
+
+ /**
+ * Overload the remove tab function as it's broken in guichan 0.8.
+ */
+ void removeTab(Tab *tab);
+
+ /**
+ * Overload the logic function since it's broken in guichan 0.8.
+ */
+ void logic();
+
+ int getContainerHeight() const
+ { return mWidgetContainer->getHeight(); }
+
+ using gcn::TabbedArea::setSelectedTab;
+
+ void setSelectedTab(gcn::Tab *tab);
+
+ void widgetResized(const gcn::Event &event);
+
+/*
+ void moveLeft(gcn::Tab *tab);
+
+ void moveRight(gcn::Tab *tab);
+*/
+ // Inherited from MouseListener
+
+ void mousePressed(gcn::MouseEvent &mouseEvent);
+
+ private:
+ typedef std::vector< std::pair<gcn::Tab*, gcn::Widget*> > TabContainer;
+};
+
+#endif
diff --git a/src/gui/widgets/table.cpp b/src/gui/widgets/table.cpp
new file mode 100644
index 000000000..39ef719ef
--- /dev/null
+++ b/src/gui/widgets/table.cpp
@@ -0,0 +1,585 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/table.h"
+
+#include "client.h"
+#include "configuration.h"
+
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+
+#include "utils/dtor.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/graphics.hpp>
+#include <guichan/key.hpp>
+
+float GuiTable::mAlpha = 1.0;
+
+class GuiTableActionListener : public gcn::ActionListener
+{
+public:
+ GuiTableActionListener(GuiTable *_table, gcn::Widget *_widget,
+ int _row, int _column);
+
+ virtual ~GuiTableActionListener();
+
+ virtual void action(const gcn::ActionEvent& actionEvent);
+
+protected:
+ GuiTable *mTable;
+ int mRow;
+ int mColumn;
+ gcn::Widget *mWidget;
+};
+
+
+GuiTableActionListener::GuiTableActionListener(GuiTable *table,
+ gcn::Widget *widget, int row,
+ int column) :
+ mTable(table),
+ mRow(row),
+ mColumn(column),
+ mWidget(widget)
+{
+ if (widget)
+ {
+ widget->addActionListener(this);
+ widget->_setParent(table);
+ }
+}
+
+GuiTableActionListener::~GuiTableActionListener()
+{
+ if (mWidget)
+ {
+ mWidget->removeActionListener(this);
+ mWidget->_setParent(NULL);
+ }
+}
+
+void GuiTableActionListener::action(const gcn::ActionEvent
+ &actionEvent _UNUSED_)
+{
+ mTable->setSelected(mRow, mColumn);
+ mTable->distributeActionEvent();
+}
+
+
+GuiTable::GuiTable(TableModel *initial_model, gcn::Color background,
+ bool opacity) :
+ mLinewiseMode(false),
+ mWrappingEnabled(false),
+ mOpaque(opacity),
+ mBackgroundColor(background),
+ mModel(NULL),
+ mSelectedRow(0),
+ mSelectedColumn(0),
+ mTopWidget(NULL)
+{
+ setModel(initial_model);
+ setFocusable(true);
+
+ addMouseListener(this);
+ addKeyListener(this);
+}
+
+GuiTable::~GuiTable()
+{
+ uninstallActionListeners();
+ delete mModel;
+ mModel = 0;
+}
+
+TableModel *GuiTable::getModel() const
+{
+ return mModel;
+}
+
+void GuiTable::setModel(TableModel *new_model)
+{
+ if (mModel)
+ {
+ uninstallActionListeners();
+ mModel->removeListener(this);
+ }
+
+ mModel = new_model;
+ installActionListeners();
+
+ if (new_model)
+ {
+ new_model->installListener(this);
+ recomputeDimensions();
+ }
+}
+
+void GuiTable::recomputeDimensions()
+{
+ if (!mModel)
+ return;
+
+ int rows_nr = mModel->getRows();
+ int columns_nr = mModel->getColumns();
+ int width = 0;
+ int height = 0;
+
+ if (mSelectedRow >= rows_nr)
+ mSelectedRow = rows_nr - 1;
+
+ if (mSelectedColumn >= columns_nr)
+ mSelectedColumn = columns_nr - 1;
+
+ for (int i = 0; i < columns_nr; i++)
+ width += getColumnWidth(i);
+
+ height = getRowHeight() * rows_nr;
+
+ setWidth(width);
+ setHeight(height);
+}
+
+void GuiTable::setSelected(int row, int column)
+{
+ mSelectedColumn = column;
+ mSelectedRow = row;
+}
+
+int GuiTable::getSelectedRow() const
+{
+ return mSelectedRow;
+}
+
+int GuiTable::getSelectedColumn() const
+{
+ return mSelectedColumn;
+}
+
+void GuiTable::setLinewiseSelection(bool linewise)
+{
+ mLinewiseMode = linewise;
+}
+
+int GuiTable::getRowHeight() const
+{
+ if (mModel)
+ return mModel->getRowHeight() + 1; // border
+ else
+ return 0;
+}
+
+int GuiTable::getColumnWidth(int i) const
+{
+ if (mModel)
+ return mModel->getColumnWidth(i) + 1; // border
+ else
+ return 0;
+}
+
+void GuiTable::setSelectedRow(int selected)
+{
+ if (!mModel)
+ {
+ mSelectedRow = -1;
+ }
+ else
+ {
+ if (selected < 0 && !mWrappingEnabled)
+ {
+ mSelectedRow = -1;
+ }
+ else if (selected >= mModel->getRows() && mWrappingEnabled)
+ {
+ mSelectedRow = 0;
+ }
+ else if ((selected >= mModel->getRows() && !mWrappingEnabled) ||
+ (selected < 0 && mWrappingEnabled))
+ {
+ mSelectedRow = mModel->getRows() - 1;
+ }
+ else
+ {
+ mSelectedRow = selected;
+ }
+ }
+}
+
+void GuiTable::setSelectedColumn(int selected)
+{
+ if (!mModel)
+ {
+ mSelectedColumn = -1;
+ }
+ else
+ {
+ if ((selected >= mModel->getColumns() && mWrappingEnabled) ||
+ (selected < 0 && !mWrappingEnabled))
+ {
+ mSelectedColumn = 0;
+ }
+ else if ((selected >= mModel->getColumns() && !mWrappingEnabled) ||
+ (selected < 0 && mWrappingEnabled))
+ {
+ mSelectedColumn = mModel->getColumns() - 1;
+ }
+ else
+ {
+ mSelectedColumn = selected;
+ }
+ }
+}
+
+void GuiTable::uninstallActionListeners()
+{
+ delete_all(mActionListeners);
+ mActionListeners.clear();
+}
+
+void GuiTable::installActionListeners()
+{
+ if (!mModel)
+ return;
+
+ int rows = mModel->getRows();
+ int columns = mModel->getColumns();
+
+ for (int row = 0; row < rows; ++row)
+ {
+ for (int column = 0; column < columns; ++column)
+ {
+ gcn::Widget *widget = mModel->getElementAt(row, column);
+ if (widget)
+ {
+ mActionListeners.push_back(new GuiTableActionListener(
+ this, widget, row, column));
+ }
+ }
+ }
+
+ _setFocusHandler(_getFocusHandler()); // propagate focus handler to widgets
+}
+
+// -- widget ops
+void GuiTable::draw(gcn::Graphics* graphics)
+{
+ if (!mModel || !getRowHeight())
+ return;
+
+ if (Client::getGuiAlpha() != mAlpha)
+ mAlpha = Client::getGuiAlpha();
+
+ if (mOpaque)
+ {
+ graphics->setColor(Theme::getThemeColor(Theme::BACKGROUND,
+ static_cast<int>(mAlpha * 255.0f)));
+ graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
+ // First, determine how many rows we need to draw, and where we should start.
+ int first_row = -(getY() / getRowHeight());
+
+ if (first_row < 0)
+ first_row = 0;
+
+ int rows_nr = 1 + (getHeight() / getRowHeight()); // May overestimate
+ // by one.
+
+ int max_rows_nr = mModel->getRows() - first_row; // clip if neccessary:
+ if (max_rows_nr < rows_nr)
+ rows_nr = max_rows_nr;
+
+ // Now determine the first and last column
+ // Take the easy way out; these are usually bounded and all visible.
+ int first_column = 0;
+ int last_column1 = mModel->getColumns();
+
+ // Set up everything for drawing
+ int height = getRowHeight();
+ int y_offset = first_row * height;
+
+ for (int r = first_row; r < first_row + rows_nr; ++r)
+ {
+ int x_offset = 0;
+
+ for (int c = first_column; c + 1 <= last_column1; ++c)
+ {
+ gcn::Widget *widget = mModel->getElementAt(r, c);
+ int width = getColumnWidth(c);
+ if (widget)
+ {
+ gcn::Rectangle bounds(x_offset, y_offset, width, height);
+
+ if (widget == mTopWidget)
+ {
+ bounds.height = widget->getHeight();
+ bounds.width = widget->getWidth();
+ }
+
+ widget->setDimension(bounds);
+
+ graphics->setColor(Theme::getThemeColor(Theme::HIGHLIGHT,
+ static_cast<int>(mAlpha * 255.0f)));
+
+ if (mLinewiseMode && r == mSelectedRow && c == 0)
+ {
+ graphics->fillRectangle(gcn::Rectangle(0, y_offset,
+ getWidth(), height));
+ }
+ else if (!mLinewiseMode &&
+ c == mSelectedColumn && r == mSelectedRow)
+ {
+ graphics->fillRectangle(gcn::Rectangle(x_offset, y_offset,
+ width, height));
+ }
+
+ graphics->pushClipArea(bounds);
+ widget->draw(graphics);
+ graphics->popClipArea();
+ }
+
+ x_offset += width;
+ }
+
+ y_offset += height;
+ }
+
+ if (mTopWidget)
+ {
+ gcn::Rectangle bounds = mTopWidget->getDimension();
+ graphics->pushClipArea(bounds);
+ mTopWidget->draw(graphics);
+ graphics->popClipArea();
+ }
+}
+
+void GuiTable::moveToTop(gcn::Widget *widget)
+{
+ gcn::Widget::moveToTop(widget);
+ mTopWidget = widget;
+}
+
+void GuiTable::moveToBottom(gcn::Widget *widget)
+{
+ gcn::Widget::moveToBottom(widget);
+ if (widget == mTopWidget)
+ mTopWidget = NULL;
+}
+
+gcn::Rectangle GuiTable::getChildrenArea() const
+{
+ return gcn::Rectangle(0, 0, getWidth(), getHeight());
+}
+
+// -- KeyListener notifications
+void GuiTable::keyPressed(gcn::KeyEvent& keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ENTER || key.getValue() == Key::SPACE)
+ {
+ distributeActionEvent();
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::UP)
+ {
+ setSelectedRow(mSelectedRow - 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::DOWN)
+ {
+ setSelectedRow(mSelectedRow + 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::LEFT)
+ {
+ setSelectedColumn(mSelectedColumn - 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::RIGHT)
+ {
+ setSelectedColumn(mSelectedColumn + 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::HOME)
+ {
+ setSelectedRow(0);
+ setSelectedColumn(0);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == Key::END && mModel)
+ {
+ setSelectedRow(mModel->getRows() - 1);
+ setSelectedColumn(mModel->getColumns() - 1);
+ keyEvent.consume();
+ }
+}
+
+// -- MouseListener notifications
+void GuiTable::mousePressed(gcn::MouseEvent& mouseEvent)
+{
+ if (!mModel)
+ return;
+
+ if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
+ {
+ int row = getRowForY(mouseEvent.getY());
+ int column = getColumnForX(mouseEvent.getX());
+
+ if (row > -1 && column > -1 &&
+ row < mModel->getRows() && column < mModel->getColumns())
+ {
+ mSelectedColumn = column;
+ mSelectedRow = row;
+ }
+
+ distributeActionEvent();
+ }
+}
+
+void GuiTable::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent)
+{
+ if (isFocused())
+ {
+ if (getSelectedRow() > 0 || (getSelectedRow() == 0
+ && mWrappingEnabled))
+ {
+ setSelectedRow(getSelectedRow() - 1);
+ }
+
+ mouseEvent.consume();
+ }
+}
+
+void GuiTable::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent)
+{
+ if (isFocused())
+ {
+ setSelectedRow(getSelectedRow() + 1);
+
+ mouseEvent.consume();
+ }
+}
+
+void GuiTable::mouseDragged(gcn::MouseEvent& mouseEvent)
+{
+ if (mouseEvent.getButton() != gcn::MouseEvent::LEFT)
+ return;
+
+ // Make table selection update on drag
+ const int x = std::max(0, mouseEvent.getX());
+ const int y = std::max(0, mouseEvent.getY());
+
+ setSelectedRow(getRowForY(y));
+ setSelectedColumn(getColumnForX(x));
+}
+
+// -- TableModelListener notifications
+void GuiTable::modelUpdated(bool completed)
+{
+ if (completed)
+ {
+ recomputeDimensions();
+ installActionListeners();
+ }
+ else
+ { // before the update?
+ mTopWidget = NULL; // No longer valid in general
+ uninstallActionListeners();
+ }
+}
+
+gcn::Widget *GuiTable::getWidgetAt(int x, int y) const
+{
+ int row = getRowForY(y);
+ int column = getColumnForX(x);
+
+ if (mTopWidget && mTopWidget->getDimension().isPointInRect(x, y))
+ return mTopWidget;
+
+ if (mModel && row > -1 && column > -1)
+ {
+ gcn::Widget *w = mModel->getElementAt(row, column);
+ if (w && w->isFocusable())
+ return w;
+ else
+ return NULL; // Grab the event locally
+ }
+ else
+ return NULL;
+}
+
+int GuiTable::getRowForY(int y) const
+{
+ int row = -1;
+
+ if (getRowHeight() > 0)
+ row = y / getRowHeight();
+
+ if (!mModel || row < 0 || row >= mModel->getRows())
+ return -1;
+ else
+ return row;
+}
+
+int GuiTable::getColumnForX(int x) const
+{
+ if (!mModel)
+ return -1;
+
+ int column;
+ int delta = 0;
+
+ for (column = 0; column < mModel->getColumns(); column++)
+ {
+ delta += getColumnWidth(column);
+ if (x <= delta)
+ break;
+ }
+
+ if (column < 0 || column >= mModel->getColumns())
+ return -1;
+ else
+ return column;
+}
+
+void GuiTable::_setFocusHandler(gcn::FocusHandler* focusHandler)
+{
+// add check for focusHandler. may be need remove it?
+
+ if (!mModel || !focusHandler)
+ return;
+
+ gcn::Widget::_setFocusHandler(focusHandler);
+
+ if (mModel)
+ {
+ for (int r = 0; r < mModel->getRows(); ++r)
+ {
+ for (int c = 0; c < mModel->getColumns(); ++c)
+ {
+ gcn::Widget *w = mModel->getElementAt(r, c);
+ if (w)
+ w->_setFocusHandler(focusHandler);
+ }
+ }
+ }
+}
diff --git a/src/gui/widgets/table.h b/src/gui/widgets/table.h
new file mode 100644
index 000000000..61c7302b2
--- /dev/null
+++ b/src/gui/widgets/table.h
@@ -0,0 +1,195 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TABLE_H
+#define TABLE_H
+
+#include "tablemodel.h"
+
+#include <guichan/keylistener.hpp>
+#include <guichan/mouselistener.hpp>
+#include <guichan/widget.hpp>
+
+#include <vector>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class GuiTableActionListener;
+
+/**
+ * A table, with rows and columns made out of sub-widgets. Largely inspired by
+ * (and can be thought of as a generalisation of) the guichan listbox
+ * implementation.
+ *
+ * Normally you want this within a ScrollArea.
+ *
+ * \ingroup GUI
+ */
+class GuiTable : public gcn::Widget,
+ public gcn::MouseListener,
+ public gcn::KeyListener,
+ public TableModelListener
+{
+ // so that the action listener can call distributeActionEvent
+ friend class GuiTableActionListener;
+
+public:
+ GuiTable(TableModel * initial_model = NULL,
+ gcn::Color background = 0xffffff,
+ bool opacity = true);
+
+ virtual ~GuiTable();
+
+ /**
+ * Retrieves the active table model
+ */
+ TableModel *getModel() const;
+
+ /**
+ * Sets the table model
+ *
+ * Note that actions issued by widgets returned from the model will update
+ * the table selection, but only AFTER any event handlers installed within
+ * the widget have been triggered. To be notified after such an update, add
+ * an action listener to the table instead.
+ */
+ void setModel(TableModel *m);
+
+ void setSelected(int row, int column);
+
+ int getSelectedRow() const;
+
+ int getSelectedColumn() const;
+
+ void setSelectedRow(int selected);
+
+ void setSelectedColumn(int selected);
+
+ bool isWrappingEnabled() const
+ { return mWrappingEnabled; }
+
+ void setWrappingEnabled(bool wrappingEnabled)
+ { mWrappingEnabled = wrappingEnabled; }
+
+ gcn::Rectangle getChildrenArea() const;
+
+ /**
+ * Toggle whether to use linewise selection mode, in which the table selects
+ * an entire line at a time, rather than a single cell.
+ *
+ * Note that column information is tracked even in linewise selection mode;
+ * this mode therefore only affects visualisation.
+ *
+ * Disabled by default.
+ *
+ * \param linewise: Whether to enable linewise selection mode
+ */
+ void setLinewiseSelection(bool linewise);
+
+ // Inherited from Widget
+ virtual void draw(gcn::Graphics* graphics);
+
+ virtual gcn::Widget *getWidgetAt(int x, int y) const;
+
+ virtual void moveToTop(gcn::Widget *child);
+
+ virtual void moveToBottom(gcn::Widget *child);
+
+ virtual void _setFocusHandler(gcn::FocusHandler* focusHandler);
+
+ // Inherited from KeyListener
+ virtual void keyPressed(gcn::KeyEvent& keyEvent);
+
+ /**
+ * Sets the table to be opaque, that is sets the table
+ * to display its background.
+ *
+ * @param opaque True if the table should be opaque, false otherwise.
+ */
+ virtual void setOpaque(bool opaque)
+ { mOpaque = opaque; }
+
+ /**
+ * Checks if the table is opaque, that is if the table area displays its
+ * background.
+ *
+ * @return True if the table is opaque, false otherwise.
+ */
+ virtual bool isOpaque() const
+ { return mOpaque; }
+
+ // Inherited from MouseListener
+ virtual void mousePressed(gcn::MouseEvent& mouseEvent);
+
+ virtual void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent);
+
+ virtual void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent);
+
+ virtual void mouseDragged(gcn::MouseEvent& mouseEvent);
+
+ // Constraints inherited from TableModelListener
+ virtual void modelUpdated(bool);
+
+protected:
+ /** Frees all action listeners on inner widgets. */
+ virtual void uninstallActionListeners();
+ /** Installs all action listeners on inner widgets. */
+ virtual void installActionListeners();
+
+ virtual int getRowHeight() const;
+ virtual int getColumnWidth(int i) const;
+
+private:
+ int getRowForY(int y) const; // -1 on error
+ int getColumnForX(int x) const; // -1 on error
+ void recomputeDimensions();
+ bool mLinewiseMode;
+ bool mWrappingEnabled;
+ bool mOpaque;
+
+ static float mAlpha;
+
+ /**
+ * Holds the background color of the table.
+ */
+ gcn::Color mBackgroundColor;
+
+ TableModel *mModel;
+
+ int mSelectedRow;
+ int mSelectedColumn;
+
+ /** Number of frames to skip upwards when drawing the selected widget. */
+ int mPopFramesNr;
+
+ /** If someone moves a fresh widget to the top, we must display it. */
+ gcn::Widget *mTopWidget;
+
+ /** Vector for compactness; used as a list in practice. */
+ std::vector<GuiTableActionListener *> mActionListeners;
+};
+
+
+#endif // TABLE_H
diff --git a/src/gui/widgets/tablemodel.cpp b/src/gui/widgets/tablemodel.cpp
new file mode 100644
index 000000000..f1d583ef6
--- /dev/null
+++ b/src/gui/widgets/tablemodel.cpp
@@ -0,0 +1,173 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/tablemodel.h"
+
+#include "utils/dtor.h"
+
+#include <guichan/widget.hpp>
+
+void TableModel::installListener(TableModelListener *listener)
+{
+ if (listener)
+ listeners.insert(listener);
+}
+
+void TableModel::removeListener(TableModelListener *listener)
+{
+ if (listener)
+ listeners.erase(listener);
+}
+
+void TableModel::signalBeforeUpdate()
+{
+ for (std::set<TableModelListener *>::const_iterator it = listeners.begin();
+ it != listeners.end(); it++)
+ {
+ (*it)->modelUpdated(false);
+ }
+}
+
+void TableModel::signalAfterUpdate()
+{
+ for (std::set<TableModelListener *>::const_iterator it = listeners.begin();
+ it != listeners.end(); it++)
+ {
+ if (*it)
+ (*it)->modelUpdated(true);
+ }
+}
+
+
+#define WIDGET_AT(row, column) (((row) * mColumns) + (column))
+#define DYN_SIZE(h) ((h) >= 0)
+
+StaticTableModel::StaticTableModel(int row, int column) :
+ mRows(row),
+ mColumns(column),
+ mHeight(1)
+{
+ mTableModel.resize(row * column, NULL);
+ mWidths.resize(column, 1);
+}
+
+StaticTableModel::~StaticTableModel()
+{
+ delete_all(mTableModel);
+ mTableModel.clear();
+}
+
+void StaticTableModel::resize()
+{
+ mRows = getRows();
+ mColumns = getColumns();
+ mTableModel.resize(mRows * mColumns, NULL);
+}
+
+void StaticTableModel::set(int row, int column, gcn::Widget *widget)
+{
+ if (!widget || row >= mRows || row < 0
+ || column >= mColumns || column < 0)
+ {
+ // raise exn?
+ return;
+ }
+
+ if (DYN_SIZE(mHeight)
+ && widget->getHeight() > mHeight)
+ {
+ mHeight = widget->getHeight();
+ }
+
+ if (DYN_SIZE(mWidths[column])
+ && widget->getWidth() > mWidths[column])
+ {
+ mWidths[column] = widget->getWidth();
+ }
+
+ signalBeforeUpdate();
+
+ delete mTableModel[WIDGET_AT(row, column)];
+
+ mTableModel[WIDGET_AT(row, column)] = widget;
+
+ signalAfterUpdate();
+}
+
+gcn::Widget *StaticTableModel::getElementAt(int row, int column) const
+{
+ return mTableModel[WIDGET_AT(row, column)];
+}
+
+void StaticTableModel::fixColumnWidth(int column, int width)
+{
+ if (width < 0 || column < 0 || column >= mColumns)
+ return;
+
+ mWidths[column] = -width; // Negate to tag as fixed
+}
+
+void StaticTableModel::fixRowHeight(int height)
+{
+ if (height < 0)
+ return;
+
+ mHeight = -height;
+}
+
+int StaticTableModel::getRowHeight() const
+{
+ return abs(mHeight);
+}
+
+int StaticTableModel::getColumnWidth(int column) const
+{
+ if (column < 0 || column >= mColumns)
+ return 0;
+
+ return abs(mWidths[column]);
+}
+
+int StaticTableModel::getRows() const
+{
+ return mRows;
+}
+
+int StaticTableModel::getColumns() const
+{
+ return mColumns;
+}
+
+int StaticTableModel::getWidth() const
+{
+ int width = 0;
+
+ for (unsigned int i = 0; i < mWidths.size(); i++)
+ width += mWidths[i];
+
+ return width;
+}
+
+int StaticTableModel::getHeight() const
+{
+ return mColumns * mHeight;
+}
+
diff --git a/src/gui/widgets/tablemodel.h b/src/gui/widgets/tablemodel.h
new file mode 100644
index 000000000..2b8729341
--- /dev/null
+++ b/src/gui/widgets/tablemodel.h
@@ -0,0 +1,149 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TABLE_MODEL_H
+#define TABLE_MODEL_H
+
+#include <guichanfwd.h>
+
+#include <set>
+#include <vector>
+
+class TableModelListener
+{
+public:
+ /**
+ * Must be invoked by the TableModel whenever a global change is about to
+ * occur or has occurred (e.g., when a row or column is being removed or
+ * added).
+ *
+ * This method is triggered twice, once before and once after the update.
+ *
+ * \param completed whether we are signalling the end of the update
+ */
+ virtual void modelUpdated(bool completed) = 0;
+
+ virtual ~TableModelListener() {}
+};
+
+/**
+ * A model for a regular table of widgets.
+ */
+class TableModel
+{
+public:
+ virtual ~TableModel()
+ { }
+
+ /**
+ * Determines the number of rows (lines) in the table
+ */
+ virtual int getRows() const = 0;
+
+ /**
+ * Determines the number of columns in each row
+ */
+ virtual int getColumns() const = 0;
+
+ /**
+ * Determines the height for each row
+ */
+ virtual int getRowHeight() const = 0;
+
+ /**
+ * Determines the width of each individual column
+ */
+ virtual int getColumnWidth(int index) const = 0;
+
+ /**
+ * Retrieves the widget stored at the specified location within the table.
+ */
+ virtual gcn::Widget *getElementAt(int row, int column) const = 0;
+
+ virtual void installListener(TableModelListener *listener);
+
+ virtual void removeListener(TableModelListener *listener);
+
+protected:
+ /**
+ * Tells all listeners that the table is about to see an update
+ */
+ virtual void signalBeforeUpdate();
+
+ /**
+ * Tells all listeners that the table has seen an update
+ */
+ virtual void signalAfterUpdate();
+
+private:
+ std::set<TableModelListener *> listeners;
+};
+
+
+class StaticTableModel : public TableModel
+{
+public:
+ StaticTableModel(int width, int height);
+ virtual ~StaticTableModel();
+
+ /**
+ * Inserts a widget into the table model.
+ * The model is resized to accomodate the widget's width and height,
+ * unless column width / row height have been fixed.
+ */
+ virtual void set(int row, int column, gcn::Widget *widget);
+
+ /**
+ * Fixes the column width for a given column; this overrides dynamic width
+ * inference.
+ *
+ * Semantics are undefined for width 0.
+ */
+ virtual void fixColumnWidth(int column, int width);
+
+ /**
+ * Fixes the row height; this overrides dynamic height inference.
+ *
+ * Semantics are undefined for width 0.
+ */
+ virtual void fixRowHeight(int height);
+
+ /**
+ * Resizes the table model
+ */
+ virtual void resize();
+
+ virtual int getRows() const;
+ virtual int getColumns() const;
+ virtual int getRowHeight() const;
+ virtual int getWidth() const;
+ virtual int getHeight() const;
+ virtual int getColumnWidth(int index) const;
+ virtual gcn::Widget *getElementAt(int row, int column) const;
+
+protected:
+ int mRows, mColumns;
+ int mHeight;
+ std::vector<gcn::Widget *> mTableModel;
+ std::vector<int> mWidths;
+};
+
+#endif // TABLE_MODEL_H
diff --git a/src/gui/widgets/textbox.cpp b/src/gui/widgets/textbox.cpp
new file mode 100644
index 000000000..f248f35d2
--- /dev/null
+++ b/src/gui/widgets/textbox.cpp
@@ -0,0 +1,149 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/textbox.h"
+
+#include "gui/theme.h"
+
+#include <guichan/font.hpp>
+
+#include <sstream>
+
+TextBox::TextBox() :
+ mTextColor(&Theme::getThemeColor(Theme::TEXT))
+{
+ setOpaque(false);
+ setFrameSize(0);
+ mMinWidth = getWidth();
+}
+
+void TextBox::setTextWrapped(const std::string &text, int minDimension)
+{
+ // Make sure parent scroll area sets width of this widget
+ if (getParent())
+ getParent()->logic();
+
+ // Take the supplied minimum dimension as a starting point and try to beat it
+ mMinWidth = minDimension;
+
+ std::stringstream wrappedStream;
+ std::string::size_type spacePos, newlinePos, lastNewlinePos = 0;
+ int minWidth = 0;
+ int xpos;
+
+ spacePos = text.rfind(" ", text.size());
+
+ if (spacePos != std::string::npos)
+ {
+ const std::string word = text.substr(spacePos + 1);
+ const int length = getFont()->getWidth(word);
+
+ if (length > mMinWidth)
+ mMinWidth = length;
+ }
+
+ do
+ {
+ // Determine next piece of string to wrap
+ newlinePos = text.find("\n", lastNewlinePos);
+
+ if (newlinePos == std::string::npos)
+ newlinePos = text.size();
+
+ std::string line =
+ text.substr(lastNewlinePos, newlinePos - lastNewlinePos);
+ std::string::size_type lastSpacePos = 0;
+ xpos = 0;
+
+ do
+ {
+ spacePos = line.find(" ", lastSpacePos);
+
+ if (spacePos == std::string::npos)
+ spacePos = line.size();
+
+ std::string word =
+ line.substr(lastSpacePos, spacePos - lastSpacePos);
+
+ int width = getFont()->getWidth(word);
+
+ if (xpos == 0 && width > mMinWidth)
+ {
+ mMinWidth = width;
+ xpos = width;
+ wrappedStream << word;
+ }
+ else if (xpos != 0 && xpos + getFont()->getWidth(" ") + width <=
+ mMinWidth)
+ {
+ xpos += getFont()->getWidth(" ") + width;
+ wrappedStream << " " << word;
+ }
+ else if (lastSpacePos == 0)
+ {
+ xpos += width;
+ wrappedStream << word;
+ }
+ else
+ {
+ if (xpos > minWidth)
+ minWidth = xpos;
+
+ // The window wasn't big enough. Resize it and try again.
+ if (minWidth > mMinWidth)
+ {
+ mMinWidth = minWidth;
+ wrappedStream.clear();
+ wrappedStream.str("");
+ spacePos = 0;
+ lastNewlinePos = 0;
+ newlinePos = text.find("\n", lastNewlinePos);
+ if (newlinePos == std::string::npos)
+ newlinePos = text.size();
+ line = text.substr(lastNewlinePos, newlinePos -
+ lastNewlinePos);
+ width = 0;
+ break;
+ }
+ else
+ {
+ wrappedStream << "\n" << word;
+ }
+ xpos = width;
+ }
+ lastSpacePos = spacePos + 1;
+ }
+ while (spacePos != line.size());
+
+ if (text.find("\n", lastNewlinePos) != std::string::npos)
+ wrappedStream << "\n";
+
+ lastNewlinePos = newlinePos + 1;
+ }
+ while (newlinePos != text.size());
+
+ if (xpos > minWidth)
+ minWidth = xpos;
+
+ mMinWidth = minWidth;
+
+ gcn::TextBox::setText(wrappedStream.str());
+}
diff --git a/src/gui/widgets/textbox.h b/src/gui/widgets/textbox.h
new file mode 100644
index 000000000..dffaf2736
--- /dev/null
+++ b/src/gui/widgets/textbox.h
@@ -0,0 +1,70 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TEXTBOX_H
+#define TEXTBOX_H
+
+#include <guichan/widgets/textbox.hpp>
+
+/**
+ * A text box, meant to be used inside a scroll area. Same as the Guichan text
+ * box except this one doesn't have a background or border, instead completely
+ * relying on the scroll area.
+ *
+ * \ingroup GUI
+ */
+class TextBox : public gcn::TextBox
+{
+ public:
+ /**
+ * Constructor.
+ */
+ TextBox();
+
+ inline void setTextColor(const gcn::Color *color)
+ { mTextColor = color; }
+
+ /**
+ * Sets the text after wrapping it to the current width of the widget.
+ */
+ void setTextWrapped(const std::string &text, int minDimension);
+
+ /**
+ * Get the minimum text width for the text box.
+ */
+ int getMinWidth() const
+ { return mMinWidth; }
+
+ /**
+ * Draws the text.
+ */
+ inline void draw(gcn::Graphics *graphics)
+ {
+ setForegroundColor(*mTextColor);
+ gcn::TextBox::draw(graphics);
+ }
+
+ private:
+ int mMinWidth;
+ const gcn::Color *mTextColor;
+};
+
+#endif
diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp
new file mode 100644
index 000000000..9a5b2de33
--- /dev/null
+++ b/src/gui/widgets/textfield.cpp
@@ -0,0 +1,306 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/textfield.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+
+#include "gui/palette.h"
+#include "gui/sdlinput.h"
+#include "gui/theme.h"
+
+#include "resources/image.h"
+
+#include "utils/copynpaste.h"
+#include "utils/dtor.h"
+
+#include <guichan/font.hpp>
+
+#undef DELETE //Win32 compatibility hack
+
+int TextField::instances = 0;
+float TextField::mAlpha = 1.0;
+ImageRect TextField::skin;
+
+TextField::TextField(const std::string &text, bool loseFocusOnTab,
+ gcn::ActionListener* listener, std::string eventId):
+ gcn::TextField(text),
+ mNumeric(false)
+{
+ setFrameSize(2);
+
+ mLoseFocusOnTab = loseFocusOnTab;
+
+ if (instances == 0)
+ {
+ // Load the skin
+ Image *textbox = Theme::getImageFromTheme("deepbox.png");
+ int gridx[4] = {0, 3, 28, 31};
+ int gridy[4] = {0, 3, 28, 31};
+ int a = 0, x, y;
+
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ if (textbox)
+ {
+ skin.grid[a] = textbox->getSubImage(
+ gridx[x], gridy[y],
+ gridx[x + 1] - gridx[x] + 1,
+ gridy[y + 1] - gridy[y] + 1);
+ if (skin.grid[a])
+ skin.grid[a]->setAlpha(Client::getGuiAlpha());
+ }
+ else
+ {
+ skin.grid[a] = 0;
+ }
+ a++;
+ }
+ }
+
+ if (textbox)
+ textbox->decRef();
+ }
+
+ instances++;
+
+ if (!eventId.empty())
+ setActionEventId(eventId);
+
+ if (listener)
+ addActionListener(listener);
+}
+
+TextField::~TextField()
+{
+ instances--;
+
+ if (instances == 0)
+ for_each(skin.grid, skin.grid + 9, dtor<Image*>());
+}
+
+void TextField::updateAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+
+ if (alpha != mAlpha)
+ {
+ mAlpha = alpha;
+ for (int a = 0; a < 9; a++)
+ {
+ if (skin.grid[a])
+ skin.grid[a]->setAlpha(mAlpha);
+ }
+ }
+}
+
+void TextField::draw(gcn::Graphics *graphics)
+{
+ updateAlpha();
+
+ if (isFocused())
+ {
+ drawCaret(graphics,
+ getFont()->getWidth(mText.substr(0, mCaretPosition)) -
+ mXScroll);
+ }
+
+ graphics->setColor(Theme::getThemeColor(Theme::TEXT));
+ graphics->setFont(getFont());
+ graphics->drawText(mText, 1 - mXScroll, 1);
+}
+
+void TextField::drawFrame(gcn::Graphics *graphics)
+{
+ //updateAlpha(); -> Not useful...
+
+ int w, h, bs;
+ bs = getFrameSize();
+ w = getWidth() + bs * 2;
+ h = getHeight() + bs * 2;
+
+ static_cast<Graphics*>(graphics)->drawImageRect(0, 0, w, h, skin);
+}
+
+void TextField::setNumeric(bool numeric)
+{
+ mNumeric = numeric;
+ if (!numeric)
+ return;
+
+ const char *text = mText.c_str();
+ for (const char *textPtr = text; *textPtr; ++textPtr)
+ {
+ if (*textPtr < '0' || *textPtr > '9')
+ {
+ setText(mText.substr(0, textPtr - text));
+ return;
+ }
+ }
+}
+
+int TextField::getValue() const
+{
+ if (!mNumeric)
+ return 0;
+
+ int value = atoi(mText.c_str());
+ if (value < mMinimum)
+ return mMinimum;
+
+ if (value > mMaximum)
+ return mMaximum;
+
+ return value;
+}
+
+void TextField::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ int val = keyEvent.getKey().getValue();
+
+ if (val >= 32)
+ {
+ int l;
+ if (val < 128)
+ l = 1; // 0xxxxxxx
+ else if (val < 0x800)
+ l = 2; // 110xxxxx 10xxxxxx
+ else if (val < 0x10000)
+ l = 3; // 1110xxxx 10xxxxxx 10xxxxxx
+ else
+ l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+ char buf[4];
+ for (int i = 0; i < l; ++i)
+ {
+ buf[i] = static_cast<char>(val >> (6 * (l - i - 1)));
+ if (i > 0)
+ buf[i] = static_cast<char>((buf[i] & 63) | 128);
+ }
+
+ if (l > 1)
+ buf[0] |= static_cast<char>(255 << (8 - l));
+
+ mText.insert(mCaretPosition, std::string(buf, buf + l));
+ mCaretPosition += l;
+ }
+
+ /* In UTF-8, 10xxxxxx is only used for inner parts of characters. So skip
+ them when processing key presses. */
+
+ switch (val)
+ {
+ case Key::LEFT:
+ {
+ while (mCaretPosition > 0)
+ {
+ --mCaretPosition;
+ if ((mText[mCaretPosition] & 192) != 128)
+ break;
+ }
+ } break;
+
+ case Key::RIGHT:
+ {
+ unsigned sz = static_cast<unsigned>(mText.size());
+ while (mCaretPosition < sz)
+ {
+ ++mCaretPosition;
+ if (mCaretPosition == sz ||
+ (mText[mCaretPosition] & 192) != 128)
+ {
+ break;
+ }
+ }
+ } break;
+
+ case Key::DELETE:
+ {
+ unsigned sz = static_cast<unsigned>(mText.size());
+ while (mCaretPosition < sz)
+ {
+ --sz;
+ mText.erase(mCaretPosition, 1);
+ if (mCaretPosition == sz ||
+ (mText[mCaretPosition] & 192) != 128)
+ {
+ break;
+ }
+ }
+ } break;
+
+ case Key::BACKSPACE:
+ {
+ while (mCaretPosition > 0)
+ {
+ --mCaretPosition;
+ int v = mText[mCaretPosition];
+ mText.erase(mCaretPosition, 1);
+ if ((v & 192) != 128)
+ break;
+ }
+ } break;
+
+ case Key::ENTER:
+ distributeActionEvent();
+ break;
+
+ case Key::HOME:
+ mCaretPosition = 0;
+ break;
+
+ case Key::END:
+ mCaretPosition = static_cast<unsigned>(mText.size());
+ break;
+
+ case Key::TAB:
+ if (mLoseFocusOnTab)
+ return;
+ break;
+
+ case 22: // Control code 22, SYNCHRONOUS IDLE, sent on Ctrl+v
+ handlePaste();
+ break;
+ default:
+ break;
+ }
+
+ keyEvent.consume();
+ fixScroll();
+}
+
+void TextField::handlePaste()
+{
+ std::string text = getText();
+ std::string::size_type caretPos = getCaretPosition();
+
+ if (RetrieveBuffer(text, caretPos))
+ {
+ setText(text);
+ setCaretPosition(static_cast<unsigned>(caretPos));
+ }
+}
diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h
new file mode 100644
index 000000000..b894fdc85
--- /dev/null
+++ b/src/gui/widgets/textfield.h
@@ -0,0 +1,110 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TEXTFIELD_H
+#define TEXTFIELD_H
+
+#include <guichan/widgets/textfield.hpp>
+
+class ImageRect;
+class TextField;
+
+/**
+ * A text field.
+ *
+ * \ingroup GUI
+ */
+class TextField : public gcn::TextField
+{
+ public:
+ /**
+ * Constructor, initializes the text field with the given string.
+ */
+ TextField(const std::string &text = "", bool loseFocusOnTab = true,
+ gcn::ActionListener* listener = NULL,
+ std::string eventId = "");
+
+ ~TextField();
+
+ /**
+ * Draws the text field.
+ */
+ virtual void draw(gcn::Graphics *graphics);
+
+ /**
+ * Update the alpha value to the graphic components.
+ */
+ void updateAlpha();
+
+ /**
+ * Draws the background and border.
+ */
+ void drawFrame(gcn::Graphics *graphics);
+
+ /**
+ * Determine whether the field should be numeric or not
+ */
+ void setNumeric(bool numeric);
+
+ /**
+ * Set the range on the field if it is numeric
+ */
+ void setRange(int min, int max)
+ {
+ mMinimum = min;
+ mMaximum = max;
+ }
+
+ /**
+ * Processes one keypress.
+ */
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ /**
+ * Set the minimum value for a range
+ */
+ void setMinimum(int min)
+ { mMinimum = min; }
+
+ /**
+ * Set the maximum value for a range
+ */
+ void setMaximum(int max)
+ { mMaximum = max; }
+
+ /**
+ * Return the value for a numeric field
+ */
+ int getValue() const;
+
+ private:
+ void handlePaste();
+
+ static int instances;
+ static float mAlpha;
+ static ImageRect skin;
+ bool mNumeric;
+ int mMinimum;
+ int mMaximum;
+ bool mLoseFocusOnTab;
+};
+
+#endif
diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp
new file mode 100644
index 000000000..bd38d8a80
--- /dev/null
+++ b/src/gui/widgets/textpreview.cpp
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/textpreview.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "textrenderer.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+#include "gui/truetypefont.h"
+
+#include <typeinfo>
+
+float TextPreview::mAlpha = 1.0;
+
+TextPreview::TextPreview(const std::string &text):
+ mText(text)
+{
+ mTextAlpha = false;
+ mFont = gui->getFont();
+ mTextColor = &Theme::getThemeColor(Theme::TEXT);
+ mTextBGColor = NULL;
+ mBGColor = &Theme::getThemeColor(Theme::BACKGROUND);
+ mOpaque = false;
+}
+
+void TextPreview::draw(gcn::Graphics* graphics)
+{
+ if (Client::getGuiAlpha() != mAlpha)
+ mAlpha = Client::getGuiAlpha();
+
+ int alpha = static_cast<int>(mAlpha * 255.0f);
+
+ if (!mTextAlpha)
+ alpha = 255;
+
+ if (mOpaque)
+ {
+ graphics->setColor(gcn::Color(static_cast<int>(mBGColor->r),
+ static_cast<int>(mBGColor->g),
+ static_cast<int>(mBGColor->b),
+ static_cast<int>(mAlpha * 255.0f)));
+ graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
+ if (mTextBGColor && typeid(*mFont) == typeid(TrueTypeFont))
+ {
+ TrueTypeFont *font = static_cast<TrueTypeFont*>(mFont);
+ int x = font->getWidth(mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0);
+ int y = font->getHeight() + 1 + 2 * ((mOutline || mShadow) ? 1 : 0);
+ graphics->setColor(gcn::Color(static_cast<int>(mTextBGColor->r),
+ static_cast<int>(mTextBGColor->g),
+ static_cast<int>(mTextBGColor->b),
+ static_cast<int>(mAlpha * 255.0f)));
+ graphics->fillRectangle(gcn::Rectangle(1, 1, x, y));
+ }
+
+ TextRenderer::renderText(graphics, mText, 2, 2, gcn::Graphics::LEFT,
+ gcn::Color(mTextColor->r, mTextColor->g,
+ mTextColor->b, alpha),
+ mFont, mOutline, mShadow);
+}
diff --git a/src/gui/widgets/textpreview.h b/src/gui/widgets/textpreview.h
new file mode 100644
index 000000000..a34ab3853
--- /dev/null
+++ b/src/gui/widgets/textpreview.h
@@ -0,0 +1,130 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TEXTPREVIEW_H
+#define TEXTPREVIEW_H
+
+#include <guichan/color.hpp>
+#include <guichan/font.hpp>
+#include <guichan/widget.hpp>
+
+/**
+ * Preview widget for particle colors, etc.
+ */
+class TextPreview : public gcn::Widget
+{
+ public:
+ TextPreview(const std::string &text);
+
+ /**
+ * Sets the color the text is printed in.
+ *
+ * @param color the color to set
+ */
+ inline void setTextColor(const gcn::Color *color)
+ { mTextColor = color; }
+
+ /**
+ * Sets the text to use the set alpha value.
+ *
+ * @param alpha whether to use alpha values for the text or not
+ */
+ inline void useTextAlpha(bool alpha)
+ { mTextAlpha = alpha; }
+
+ /**
+ * Sets the color the text background is drawn in. This is only the
+ * rectangle directly behind the text, not to full widget.
+ *
+ * @param color the color to set
+ */
+ inline void setTextBGColor(const gcn::Color *color)
+ { mTextBGColor = color; }
+
+ /**
+ * Sets the background color of the widget.
+ *
+ * @param color the color to set
+ */
+ inline void setBGColor(const gcn::Color *color)
+ { mBGColor = color; }
+
+ /**
+ * Sets the font to render the text in.
+ *
+ * @param font the font to use.
+ */
+ inline void setFont(gcn::Font *font)
+ { mFont = font; }
+
+ /**
+ * Sets whether to use a shadow while rendering.
+ *
+ * @param shadow true, if a shadow is wanted, false else
+ */
+ inline void setShadow(bool shadow)
+ { mShadow = shadow; }
+
+ /**
+ * Sets whether to use an outline while rendering.
+ *
+ * @param outline true, if an outline is wanted, false else
+ */
+ inline void setOutline(bool outline)
+ { mOutline = outline; }
+
+ /**
+ * Widget's draw method. Does the actual job.
+ *
+ * @param graphics graphics to draw into
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Set opacity for this widget (whether or not to show the background
+ * color)
+ *
+ * @param opaque Whether the widget should be opaque or not
+ */
+ void setOpaque(bool opaque)
+ { mOpaque = opaque; }
+
+ /**
+ * Gets opacity for this widget (whether or not the background color
+ * is shown below the widget)
+ */
+ bool isOpaque() const
+ { return mOpaque; }
+
+ private:
+ gcn::Font *mFont;
+ std::string mText;
+ const gcn::Color *mTextColor;
+ const gcn::Color *mBGColor;
+ const gcn::Color *mTextBGColor;
+ static float mAlpha;
+ bool mTextAlpha;
+ bool mOpaque;
+ bool mShadow;
+ bool mOutline;
+};
+
+#endif
diff --git a/src/gui/widgets/tradetab.cpp b/src/gui/widgets/tradetab.cpp
new file mode 100644
index 000000000..fb4a57fd5
--- /dev/null
+++ b/src/gui/widgets/tradetab.cpp
@@ -0,0 +1,59 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/tradetab.h"
+
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/theme.h"
+
+#include "net/net.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+TradeTab::TradeTab() :
+ ChatTab(_("Trade"))
+{
+}
+
+TradeTab::~TradeTab()
+{
+}
+
+void TradeTab::handleInput(const std::string &msg)
+{
+ std::string str = "\302\202" + msg;
+ ChatTab::handleInput(str);
+}
+
+void TradeTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log(std::string("#Trade"), std::string(msg));
+}
diff --git a/src/gui/widgets/tradetab.h b/src/gui/widgets/tradetab.h
new file mode 100644
index 000000000..fceeb1e40
--- /dev/null
+++ b/src/gui/widgets/tradetab.h
@@ -0,0 +1,50 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TRADETAB_H
+#define TRADETAB_H
+
+#include "gui/widgets/chattab.h"
+
+/**
+ * A tab for a party chat channel.
+ */
+class TradeTab : public ChatTab
+{
+ public:
+ TradeTab();
+
+ ~TradeTab();
+
+ int getType() const
+ { return ChatTab::TAB_TRADE; }
+
+ void saveToLogFile(std::string &msg);
+
+ protected:
+ void handleInput(const std::string &msg);
+};
+
+extern TradeTab *tradeChatTab;
+#endif
+
+
+
diff --git a/src/gui/widgets/vertcontainer.cpp b/src/gui/widgets/vertcontainer.cpp
new file mode 100644
index 000000000..4dac2a617
--- /dev/null
+++ b/src/gui/widgets/vertcontainer.cpp
@@ -0,0 +1,53 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/vertcontainer.h"
+
+VertContainer::VertContainer(int spacing):
+ mSpacing(spacing),
+ mCount(0)
+{
+ addWidgetListener(this);
+}
+
+void VertContainer::add(gcn::Widget *widget)
+{
+ if (!widget)
+ return;
+
+ Container::add(widget);
+ widget->setPosition(0, mCount * mSpacing);
+ widget->setSize(getWidth(), mSpacing);
+ mCount++;
+ setHeight(mCount * mSpacing);
+}
+
+void VertContainer::clear()
+{
+ Container::clear();
+
+ mCount = 0;
+}
+
+void VertContainer::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ for (WidgetListIterator it = mWidgets.begin(); it != mWidgets.end(); it++)
+ (*it)->setWidth(getWidth());
+}
diff --git a/src/gui/widgets/vertcontainer.h b/src/gui/widgets/vertcontainer.h
new file mode 100644
index 000000000..fe62d8c0e
--- /dev/null
+++ b/src/gui/widgets/vertcontainer.h
@@ -0,0 +1,52 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUI_VERTCONTAINER_H
+#define GUI_VERTCONTAINER_H
+
+#include "gui/widgets/container.h"
+
+#include <guichan/widgetlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+/**
+ * A widget container.
+ *
+ * This container places it's contents veritcally.
+ */
+class VertContainer : public Container, public gcn::WidgetListener
+{
+ public:
+ VertContainer(int spacing);
+ virtual void add(gcn::Widget *widget);
+ virtual void clear();
+ void widgetResized(const gcn::Event &event);
+
+ private:
+ int mSpacing;
+ int mCount;
+};
+
+#endif
diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp
new file mode 100644
index 000000000..f0c347b59
--- /dev/null
+++ b/src/gui/widgets/whispertab.cpp
@@ -0,0 +1,164 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "whispertab.h"
+
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/theme.h"
+
+#include "net/chathandler.h"
+#include "net/net.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+WhisperTab::WhisperTab(const std::string &nick) :
+ ChatTab(nick),
+ mNick(nick)
+{
+ setTabColor(&Theme::getThemeColor(Theme::WHISPER));
+}
+
+WhisperTab::~WhisperTab()
+{
+ if (chatWindow)
+ chatWindow->removeWhisper(mNick);
+}
+
+void WhisperTab::handleInput(const std::string &msg)
+{
+// if (msg.empty())
+// {
+// chatLog(_("Cannot send empty chat!"), BY_SERVER, false);
+// return;
+// }
+
+ if (chatWindow)
+ {
+ Net::getChatHandler()->privateMessage(mNick,
+ chatWindow->doReplace(msg));
+ }
+ else
+ {
+ Net::getChatHandler()->privateMessage(mNick, msg);
+ }
+
+ if (player_node)
+ chatLog(player_node->getName(), msg);
+ else
+ chatLog("?", msg);
+}
+
+void WhisperTab::handleCommand(const std::string &msg)
+{
+ if (msg == "close")
+ {
+ delete this;
+ return;
+ }
+
+ std::string::size_type pos = msg.find(' ');
+ std::string type(msg, 0, pos);
+ std::string args(msg, pos == std::string::npos
+ ? msg.size() : pos + 1);
+
+ if (type == "me")
+ {
+ std::string str = strprintf("*%s*", args.c_str());
+ Net::getChatHandler()->privateMessage(mNick, str);
+ if (player_node)
+ chatLog(player_node->getName(), str);
+ else
+ chatLog("?", str);
+ }
+ else
+ {
+ ChatTab::handleCommand(msg);
+ }
+}
+
+void WhisperTab::showHelp()
+{
+ chatLog(_("/ignore > Ignore the other player"));
+ chatLog(_("/unignore > Stop ignoring the other player"));
+ chatLog(_("/close > Close the whisper tab"));
+}
+
+bool WhisperTab::handleCommand(const std::string &type,
+ const std::string &args)
+{
+ if (type == "help")
+ {
+ if (args == "close")
+ {
+ chatLog(_("Command: /close"));
+ chatLog(_("This command closes the current whisper tab."));
+ }
+ else if (args == "ignore")
+ {
+ chatLog(_("Command: /ignore"));
+ chatLog(_("This command ignores the other player regardless of "
+ "current relations."));
+ }
+ else if (args == "unignore")
+ {
+ chatLog(_("Command: /unignore <player>"));
+ chatLog(_("This command stops ignoring the other player if they "
+ "are being ignored."));
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (type == "close")
+ {
+ delete this;
+ if (chatWindow)
+ chatWindow->defaultTab();
+ }
+ else if (type == "ignore")
+ {
+ if (commandHandler)
+ commandHandler->handleIgnore(mNick, this);
+ }
+ else if (type == "unignore")
+ {
+ if (commandHandler)
+ commandHandler->handleUnignore(mNick, this);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void WhisperTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log(getNick(), msg);
+}
diff --git a/src/gui/widgets/whispertab.h b/src/gui/widgets/whispertab.h
new file mode 100644
index 000000000..89e70695b
--- /dev/null
+++ b/src/gui/widgets/whispertab.h
@@ -0,0 +1,67 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WHISPERTAB_H
+#define WHISPERTAB_H
+
+#include "chattab.h"
+
+class Channel;
+
+/**
+ * A tab for whispers from a single player.
+ */
+class WhisperTab : public ChatTab
+{
+ public:
+ const std::string &getNick() const { return mNick; }
+
+ void showHelp();
+
+ bool handleCommand(const std::string &type,
+ const std::string &args);
+
+ int getType() const
+ { return ChatTab::TAB_WHISPER; }
+
+ void saveToLogFile(std::string &msg);
+
+ protected:
+ friend class ChatWindow;
+
+ /**
+ * Constructor.
+ *
+ * @param nick the name of the player this tab is whispering to
+ */
+ WhisperTab(const std::string &nick);
+
+ ~WhisperTab();
+
+ void handleInput(const std::string &msg);
+
+ void handleCommand(const std::string &msg);
+
+ private:
+ std::string mNick;
+};
+
+#endif // CHANNELTAB_H
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp
new file mode 100644
index 000000000..6564a8d3f
--- /dev/null
+++ b/src/gui/widgets/window.cpp
@@ -0,0 +1,924 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/window.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "log.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+#include "gui/theme.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/layout.h"
+#include "gui/widgets/resizegrip.h"
+#include "gui/widgets/windowcontainer.h"
+
+#include "resources/image.h"
+
+#include <guichan/exception.hpp>
+#include <guichan/focushandler.hpp>
+
+int Window::instances = 0;
+int Window::mouseResize = 0;
+
+Window::Window(const std::string &caption, bool modal, Window *parent,
+ const std::string &skin):
+ gcn::Window(caption),
+ mGrip(0),
+ mParent(parent),
+ mLayout(NULL),
+ mWindowName("window"),
+ mShowTitle(true),
+ mModal(modal),
+ mCloseButton(false),
+ mDefaultVisible(false),
+ mSaveVisible(false),
+ mStickyButton(false),
+ mSticky(false),
+ mMinWinWidth(100),
+ mMinWinHeight(40),
+ mMaxWinWidth(graphics->getWidth()),
+ mMaxWinHeight(graphics->getHeight())
+{
+ logger->log("Window::Window(\"%s\")", caption.c_str());
+
+ if (!windowContainer)
+ throw GCN_EXCEPTION("Window::Window(): no windowContainer set");
+
+ instances++;
+
+ setFrameSize(0);
+ setPadding(3);
+ setTitleBarHeight(20);
+
+ // Loads the skin
+ mSkin = Theme::instance()->load(skin);
+
+ // Add this window to the window container
+ windowContainer->add(this);
+
+ if (mModal)
+ {
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ requestModalFocus();
+ }
+
+ // Windows are invisible by default
+ setVisible(false);
+
+ addWidgetListener(this);
+}
+
+Window::~Window()
+{
+ logger->log("Window::~Window(\"%s\")", getCaption().c_str());
+
+ saveWindowState();
+
+ delete mLayout;
+ mLayout = 0;
+
+ while (!mWidgets.empty())
+ delete mWidgets.front();
+
+// need mWidgets.clean ?
+
+ removeWidgetListener(this);
+
+ instances--;
+
+ if (mSkin)
+ mSkin->instances--;
+}
+
+void Window::setWindowContainer(WindowContainer *wc)
+{
+ windowContainer = wc;
+}
+
+void Window::draw(gcn::Graphics *graphics)
+{
+ if (!mSkin)
+ return;
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder());
+
+ // Draw title
+ if (mShowTitle)
+ {
+ g->setColor(Theme::getThemeColor(Theme::TEXT));
+ g->setFont(getFont());
+ g->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT);
+ }
+
+ // Draw Close Button
+ if (mCloseButton && mSkin->getCloseImage())
+ {
+ g->drawImage(mSkin->getCloseImage(),
+ getWidth() - mSkin->getCloseImage()->getWidth() - getPadding(),
+ getPadding());
+ }
+
+ // Draw Sticky Button
+ if (mStickyButton)
+ {
+ Image *button = mSkin->getStickyImage(mSticky);
+ if (button)
+ {
+ int x = getWidth() - button->getWidth() - getPadding();
+ if (mCloseButton && mSkin->getCloseImage())
+ x -= mSkin->getCloseImage()->getWidth();
+
+ g->drawImage(button, x, getPadding());
+ }
+ }
+
+ drawChildren(graphics);
+}
+
+void Window::setContentSize(int width, int height)
+{
+ width = width + 2 * getPadding();
+ height = height + getPadding() + getTitleBarHeight();
+
+ if (getMinWidth() > width)
+ width = getMinWidth();
+ else if (getMaxWidth() < width)
+ width = getMaxWidth();
+ if (getMinHeight() > height)
+ height = getMinHeight();
+ else if (getMaxHeight() < height)
+ height = getMaxHeight();
+
+ setSize(width, height);
+}
+
+void Window::setLocationRelativeTo(gcn::Widget *widget)
+{
+ if (!widget)
+ return;
+
+ int wx, wy;
+ int x, y;
+
+ widget->getAbsolutePosition(wx, wy);
+ getAbsolutePosition(x, y);
+
+ setPosition(getX() + (wx + (widget->getWidth() - getWidth()) / 2 - x),
+ getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y));
+}
+
+void Window::setLocationHorisontallyRelativeTo(gcn::Widget *widget)
+{
+ if (!widget)
+ return;
+
+ int wx, wy;
+ int x, y;
+
+ widget->getAbsolutePosition(wx, wy);
+ getAbsolutePosition(x, y);
+
+ setPosition(getX() + (wx + (widget->getWidth() - getWidth()) / 2 - x), 0);
+}
+
+void Window::setLocationRelativeTo(ImageRect::ImagePosition position,
+ int offsetX, int offsetY)
+{
+ if (position == ImageRect::UPPER_LEFT)
+ {
+ }
+ else if (position == ImageRect::UPPER_CENTER)
+ {
+ offsetX += (graphics->getWidth() - getWidth()) / 2;
+ }
+ else if (position == ImageRect::UPPER_RIGHT)
+ {
+ offsetX += graphics->getWidth() - getWidth();
+ }
+ else if (position == ImageRect::LEFT)
+ {
+ offsetY += (graphics->getHeight() - getHeight()) / 2;
+ }
+ else if (position == ImageRect::CENTER)
+ {
+ offsetX += (graphics->getWidth() - getWidth()) / 2;
+ offsetY += (graphics->getHeight() - getHeight()) / 2;
+ }
+ else if (position == ImageRect::RIGHT)
+ {
+ offsetX += graphics->getWidth() - getWidth();
+ offsetY += (graphics->getHeight() - getHeight()) / 2;
+ }
+ else if (position == ImageRect::LOWER_LEFT)
+ {
+ offsetY += graphics->getHeight() - getHeight();
+ }
+ else if (position == ImageRect::LOWER_CENTER)
+ {
+ offsetX += (graphics->getWidth() - getWidth()) / 2;
+ offsetY += graphics->getHeight() - getHeight();
+ }
+ else if (position == ImageRect::LOWER_RIGHT)
+ {
+ offsetX += graphics->getWidth() - getWidth();
+ offsetY += graphics->getHeight() - getHeight();
+ }
+
+ setPosition(offsetX, offsetY);
+}
+
+void Window::setMinWidth(int width)
+{
+ mMinWinWidth = width > mSkin->getMinWidth() ? width : mSkin->getMinWidth();
+}
+
+void Window::setMinHeight(int height)
+{
+ mMinWinHeight = height > mSkin->getMinHeight() ?
+ height : mSkin->getMinHeight();
+}
+
+void Window::setMaxWidth(int width)
+{
+ mMaxWinWidth = width;
+}
+
+void Window::setMaxHeight(int height)
+{
+ mMaxWinHeight = height;
+}
+
+void Window::setResizable(bool r)
+{
+ if (static_cast<bool>(mGrip) == r)
+ return;
+
+ if (r)
+ {
+ mGrip = new ResizeGrip;
+ mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
+ mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
+ add(mGrip);
+ }
+ else
+ {
+ remove(mGrip);
+ delete mGrip;
+ mGrip = 0;
+ }
+}
+
+void Window::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ const gcn::Rectangle area = getChildrenArea();
+
+ if (mGrip)
+ {
+ mGrip->setPosition(getWidth() - mGrip->getWidth() - area.x,
+ getHeight() - mGrip->getHeight() - area.y);
+ }
+
+ if (mLayout)
+ {
+ int w = area.width;
+ int h = area.height;
+ mLayout->reflow(w, h);
+ }
+}
+
+void Window::widgetHidden(const gcn::Event &event _UNUSED_)
+{
+ if (gui)
+ gui->setCursorType(Gui::CURSOR_POINTER);
+
+ WidgetListIterator it;
+
+ if (!mFocusHandler)
+ return;
+
+ for (it = mWidgets.begin(); it != mWidgets.end(); it++)
+ {
+ if (mFocusHandler->isFocused(*it))
+ mFocusHandler->focusNone();
+ }
+}
+
+void Window::setCloseButton(bool flag)
+{
+ mCloseButton = flag;
+}
+
+bool Window::isResizable() const
+{
+ return mGrip;
+}
+
+void Window::setStickyButton(bool flag)
+{
+ mStickyButton = flag;
+}
+
+void Window::setSticky(bool sticky)
+{
+ mSticky = sticky;
+}
+
+void Window::setVisible(bool visible)
+{
+ setVisible(visible, false);
+}
+
+void Window::setVisible(bool visible, bool forceSticky)
+{
+ if (visible == isVisible())
+ return; // Nothing to do
+
+ // Check if the window is off screen...
+ if (visible)
+ checkIfIsOffScreen();
+
+ gcn::Window::setVisible((!forceSticky && isSticky()) || visible);
+}
+
+void Window::scheduleDelete()
+{
+ windowContainer->scheduleDelete(this);
+}
+
+void Window::mousePressed(gcn::MouseEvent &event)
+{
+ // Let Guichan move window to top and figure out title bar drag
+ gcn::Window::mousePressed(event);
+
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ const int x = event.getX();
+ const int y = event.getY();
+
+ // Handle close button
+ if (mCloseButton)
+ {
+ Image *img = mSkin->getCloseImage();
+ if (img)
+ {
+ gcn::Rectangle closeButtonRect(
+ getWidth() - img->getWidth()
+ - getPadding(), getPadding(),
+ img->getWidth(), img->getHeight());
+
+ if (closeButtonRect.isPointInRect(x, y))
+ {
+ mouseResize = 0;
+ mMoved = 0;
+ close();
+ return;
+ }
+ }
+ }
+
+ // Handle sticky button
+ if (mStickyButton)
+ {
+ Image *button = mSkin->getStickyImage(mSticky);
+ if (button)
+ {
+ int rx = getWidth() - button->getWidth() - getPadding();
+ if (mCloseButton)
+ {
+ Image *img = mSkin->getCloseImage();
+ if (img)
+ rx -= img->getWidth();
+ }
+ gcn::Rectangle stickyButtonRect(rx, getPadding(),
+ button->getWidth(), button->getHeight());
+ if (stickyButtonRect.isPointInRect(x, y))
+ {
+ setSticky(!isSticky());
+ mouseResize = 0;
+ mMoved = 0;
+ return;
+ }
+ }
+ }
+
+ // Handle window resizing
+ mouseResize = getResizeHandles(event);
+ mMoved = !mouseResize;
+ }
+}
+
+void Window::close()
+{
+ setVisible(false);
+}
+
+void Window::mouseReleased(gcn::MouseEvent &event _UNUSED_)
+{
+ if (mGrip && mouseResize)
+ {
+ mouseResize = 0;
+ if (gui)
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ }
+
+ // This should be the responsibility of Guichan (and is from 0.8.0 on)
+ mMoved = false;
+}
+
+void Window::mouseExited(gcn::MouseEvent &event _UNUSED_)
+{
+ if (mGrip && !mouseResize && gui)
+ gui->setCursorType(Gui::CURSOR_POINTER);
+}
+
+void Window::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!gui)
+ return;
+
+ int resizeHandles = getResizeHandles(event);
+
+ // Changes the custom mouse cursor based on it's current position.
+ switch (resizeHandles)
+ {
+ case BOTTOM | RIGHT:
+ case TOP | LEFT:
+ gui->setCursorType(Gui::CURSOR_RESIZE_DOWN_RIGHT);
+ break;
+ case TOP | RIGHT:
+ case BOTTOM | LEFT:
+ gui->setCursorType(Gui::CURSOR_RESIZE_DOWN_LEFT);
+ break;
+ case BOTTOM:
+ case TOP:
+ gui->setCursorType(Gui::CURSOR_RESIZE_DOWN);
+ break;
+ case RIGHT:
+ case LEFT:
+ gui->setCursorType(Gui::CURSOR_RESIZE_ACROSS);
+ break;
+ default:
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ }
+
+ if (viewport)
+ viewport->hideBeingPopup();
+}
+
+void Window::mouseDragged(gcn::MouseEvent &event)
+{
+ // Let Guichan handle title bar drag
+ gcn::Window::mouseDragged(event);
+
+ // Keep guichan window inside screen when it may be moved
+ if (isMovable() && mMoved)
+ {
+ int newX = std::max(0, getX());
+ int newY = std::max(0, getY());
+ newX = std::min(graphics->getWidth() - getWidth(), newX);
+ newY = std::min(graphics->getHeight() - getHeight(), newY);
+ setPosition(newX, newY);
+ }
+
+ if (mouseResize && !mMoved)
+ {
+ const int dx = event.getX() - mDragOffsetX;
+ const int dy = event.getY() - mDragOffsetY;
+ gcn::Rectangle newDim = getDimension();
+
+ if (mouseResize & (TOP | BOTTOM))
+ {
+ int newHeight = newDim.height + ((mouseResize & TOP) ? -dy : dy);
+ newDim.height = std::min(mMaxWinHeight,
+ std::max(mMinWinHeight, newHeight));
+
+ if (mouseResize & TOP)
+ newDim.y -= newDim.height - getHeight();
+ }
+
+ if (mouseResize & (LEFT | RIGHT))
+ {
+ int newWidth = newDim.width + ((mouseResize & LEFT) ? -dx : dx);
+ newDim.width = std::min(mMaxWinWidth,
+ std::max(mMinWinWidth, newWidth));
+
+ if (mouseResize & LEFT)
+ newDim.x -= newDim.width - getWidth();
+ }
+
+ // Keep guichan window inside screen (supports resizing any side)
+ if (newDim.x < 0)
+ {
+ newDim.width += newDim.x;
+ newDim.x = 0;
+ }
+ if (newDim.y < 0)
+ {
+ newDim.height += newDim.y;
+ newDim.y = 0;
+ }
+ if (newDim.x + newDim.width > graphics->getWidth())
+ {
+ newDim.width = graphics->getWidth() - newDim.x;
+ }
+ if (newDim.y + newDim.height > graphics->getHeight())
+ {
+ newDim.height = graphics->getHeight() - newDim.y;
+ }
+
+ // Update mouse offset when dragging bottom or right border
+ if (mouseResize & BOTTOM)
+ mDragOffsetY += newDim.height - getHeight();
+
+ if (mouseResize & RIGHT)
+ mDragOffsetX += newDim.width - getWidth();
+
+ // Set the new window and content dimensions
+ setDimension(newDim);
+ }
+}
+
+void Window::setModal(bool modal)
+{
+ if (mModal != modal)
+ {
+ mModal = modal;
+ if (mModal)
+ {
+ if (gui)
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ requestModalFocus();
+ }
+ else
+ {
+ releaseModalFocus();
+ }
+ }
+}
+
+void Window::loadWindowState()
+{
+ const std::string &name = mWindowName;
+ assert(!name.empty());
+
+ setPosition(config.getValueInt(name + "WinX", mDefaultX),
+ config.getValueInt(name + "WinY", mDefaultY));
+
+ if (mSaveVisible)
+ {
+ setVisible(config.getValueBool(name
+ + "Visible", mDefaultVisible));
+ }
+
+ if (mStickyButton)
+ {
+ setSticky(config.getValueBool(name
+ + "Sticky", isSticky()));
+ }
+
+ if (mGrip)
+ {
+ int width = config.getValueInt(name + "WinWidth", mDefaultWidth);
+ int height = config.getValueInt(name + "WinHeight", mDefaultHeight);
+
+ if (getMinWidth() > width)
+ width = getMinWidth();
+ else if (getMaxWidth() < width)
+ width = getMaxWidth();
+ if (getMinHeight() > height)
+ height = getMinHeight();
+ else if (getMaxHeight() < height)
+ height = getMaxHeight();
+
+ setSize(width, height);
+ }
+ else
+ {
+ setSize(mDefaultWidth, mDefaultHeight);
+ }
+
+ // Check if the window is off screen...
+ checkIfIsOffScreen();
+}
+
+void Window::saveWindowState()
+{
+ // Saving X, Y and Width and Height for resizables in the config
+ if (!mWindowName.empty() && mWindowName != "window")
+ {
+ config.setValue(mWindowName + "WinX", getX());
+ config.setValue(mWindowName + "WinY", getY());
+
+ if (mSaveVisible)
+ config.setValue(mWindowName + "Visible", isVisible());
+
+ if (mStickyButton)
+ config.setValue(mWindowName + "Sticky", isSticky());
+
+ if (mGrip)
+ {
+ if (getMinWidth() > getWidth())
+ setWidth(getMinWidth());
+ else if (getMaxWidth() < getWidth())
+ setWidth(getMaxWidth());
+ if (getMinHeight() > getHeight())
+ setHeight(getMinHeight());
+ else if (getMaxHeight() < getHeight())
+ setHeight(getMaxHeight());
+
+ config.setValue(mWindowName + "WinWidth", getWidth());
+ config.setValue(mWindowName + "WinHeight", getHeight());
+ }
+ }
+}
+
+void Window::setDefaultSize(int defaultX, int defaultY,
+ int defaultWidth, int defaultHeight)
+{
+ if (getMinWidth() > defaultWidth)
+ defaultWidth = getMinWidth();
+ else if (getMaxWidth() < defaultWidth)
+ defaultWidth = getMaxWidth();
+ if (getMinHeight() > defaultHeight)
+ defaultHeight = getMinHeight();
+ else if (getMaxHeight() < defaultHeight)
+ defaultHeight = getMaxHeight();
+
+ mDefaultX = defaultX;
+ mDefaultY = defaultY;
+ mDefaultWidth = defaultWidth;
+ mDefaultHeight = defaultHeight;
+}
+
+void Window::setDefaultSize()
+{
+ mDefaultX = getX();
+ mDefaultY = getY();
+ mDefaultWidth = getWidth();
+ mDefaultHeight = getHeight();
+}
+
+void Window::setDefaultSize(int defaultWidth, int defaultHeight,
+ ImageRect::ImagePosition position,
+ int offsetX, int offsetY)
+{
+ int x = 0, y = 0;
+
+ if (position == ImageRect::UPPER_LEFT)
+ {
+ }
+ else if (position == ImageRect::UPPER_CENTER)
+ {
+ x = (graphics->getWidth() - defaultWidth) / 2;
+ }
+ else if (position == ImageRect::UPPER_RIGHT)
+ {
+ x = graphics->getWidth() - defaultWidth;
+ }
+ else if (position == ImageRect::LEFT)
+ {
+ y = (graphics->getHeight() - defaultHeight) / 2;
+ }
+ else if (position == ImageRect::CENTER)
+ {
+ x = (graphics->getWidth() - defaultWidth) / 2;
+ y = (graphics->getHeight() - defaultHeight) / 2;
+ }
+ else if (position == ImageRect::RIGHT)
+ {
+ x = graphics->getWidth() - defaultWidth;
+ y = (graphics->getHeight() - defaultHeight) / 2;
+ }
+ else if (position == ImageRect::LOWER_LEFT)
+ {
+ y = graphics->getHeight() - defaultHeight;
+ }
+ else if (position == ImageRect::LOWER_CENTER)
+ {
+ x = (graphics->getWidth() - defaultWidth) / 2;
+ y = graphics->getHeight() - defaultHeight;
+ }
+ else if (position == ImageRect::LOWER_RIGHT)
+ {
+ x = graphics->getWidth() - defaultWidth;
+ y = graphics->getHeight() - defaultHeight;
+ }
+
+ mDefaultX = x - offsetX;
+ mDefaultY = y - offsetY;
+ mDefaultWidth = defaultWidth;
+ mDefaultHeight = defaultHeight;
+}
+
+void Window::resetToDefaultSize()
+{
+ setPosition(mDefaultX, mDefaultY);
+ setSize(mDefaultWidth, mDefaultHeight);
+ saveWindowState();
+}
+
+int Window::getResizeHandles(gcn::MouseEvent &event)
+{
+ int resizeHandles = 0;
+ const int y = event.getY();
+
+ if (mGrip && (y > static_cast<int>(mTitleBarHeight)
+ || (y < (int)getPadding() && mTitleBarHeight > getPadding())))
+ {
+ const int x = event.getX();
+
+ if (!getWindowArea().isPointInRect(x, y) && event.getSource() == this)
+ {
+ resizeHandles |= (x > getWidth() - resizeBorderWidth) ? RIGHT :
+ (x < resizeBorderWidth) ? LEFT : 0;
+ resizeHandles |= (y > getHeight() - resizeBorderWidth) ? BOTTOM :
+ (y < resizeBorderWidth) ? TOP : 0;
+ }
+
+ if (event.getSource() == mGrip)
+ {
+ mDragOffsetX = x;
+ mDragOffsetY = y;
+ resizeHandles |= BOTTOM | RIGHT;
+ }
+ }
+
+ return resizeHandles;
+}
+
+bool Window::isResizeAllowed(gcn::MouseEvent &event)
+{
+ const int y = event.getY();
+
+ if (mGrip && (y > static_cast<int>(mTitleBarHeight)
+ || y < (int)getPadding()))
+ {
+ const int x = event.getX();
+
+ if (!getWindowArea().isPointInRect(x, y) && event.getSource() == this)
+ return true;
+
+ if (event.getSource() == mGrip)
+ return true;
+ }
+
+ return false;
+}
+
+int Window::getGuiAlpha()
+{
+ float alpha = std::max(Client::getGuiAlpha(),
+ Theme::instance()->getMinimumOpacity());
+ return static_cast<int>(alpha * 255.0f);
+}
+
+Layout &Window::getLayout()
+{
+ if (!mLayout)
+ mLayout = new Layout;
+ return *mLayout;
+}
+
+void Window::clearLayout()
+{
+ clear();
+
+ // Restore the resize grip
+ if (mGrip)
+ add(mGrip);
+
+ // Recreate layout instance when one is present
+ if (mLayout)
+ {
+ delete mLayout;
+ mLayout = new Layout;
+ }
+}
+
+LayoutCell &Window::place(int x, int y, gcn::Widget *wg, int w, int h)
+{
+ add(wg);
+ return getLayout().place(wg, x, y, w, h);
+}
+
+ContainerPlacer Window::getPlacer(int x, int y)
+{
+ return ContainerPlacer(this, &getLayout().at(x, y));
+}
+
+void Window::reflowLayout(int w, int h)
+{
+ if (!mLayout)
+ return;
+
+ mLayout->reflow(w, h);
+ delete mLayout;
+ mLayout = 0;
+ setContentSize(w, h);
+}
+
+void Window::redraw()
+{
+ if (mLayout)
+ {
+ const gcn::Rectangle area = getChildrenArea();
+ int w = area.width;
+ int h = area.height;
+ mLayout->reflow(w, h);
+ }
+}
+
+void Window::center()
+{
+ setLocationRelativeTo(getParent());
+}
+
+void Window::centerHorisontally()
+{
+ setLocationHorisontallyRelativeTo(getParent());
+}
+
+void Window::checkIfIsOffScreen(bool partially, bool entirely)
+{
+ // Move the window onto screen if it has become off screen
+ // For instance, because of resolution change...
+
+ // First of all, don't deal when a window hasn't got
+ // any size initialized yet...
+ if (getWidth() == 0 && getHeight() == 0)
+ return;
+
+ // Made partially the default behaviour
+ if (!partially && !entirely)
+ partially = true;
+
+ // Keep guichan window inside screen (supports resizing any side)
+
+ gcn::Rectangle winDimension = getDimension();
+
+ if (winDimension.x < 0)
+ {
+ winDimension.width += winDimension.x;
+ winDimension.x = 0;
+ }
+ if (winDimension.y < 0)
+ {
+ winDimension.height += winDimension.y;
+ winDimension.y = 0;
+ }
+
+ // Look if the window is partially off-screen limits...
+ if (partially)
+ {
+ if (winDimension.x + winDimension.width > graphics->getWidth())
+ winDimension.x = graphics->getWidth() - winDimension.width;
+
+ if (winDimension.y + winDimension.height > graphics->getHeight())
+ winDimension.y = graphics->getHeight() - winDimension.height;
+
+ setDimension(winDimension);
+ return;
+ }
+
+ if (entirely)
+ {
+ if (winDimension.x > graphics->getWidth())
+ winDimension.x = graphics->getWidth() - winDimension.width;
+
+ if (winDimension.y > graphics->getHeight())
+ winDimension.y = graphics->getHeight() - winDimension.height;
+ }
+ setDimension(winDimension);
+}
+
+gcn::Rectangle Window::getWindowArea()
+{
+ return gcn::Rectangle(getPadding(),
+ getPadding(),
+ getWidth() - getPadding() * 2,
+ getHeight() - getPadding() * 2);
+} \ No newline at end of file
diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h
new file mode 100644
index 000000000..09e15d3f4
--- /dev/null
+++ b/src/gui/widgets/window.h
@@ -0,0 +1,441 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include "graphics.h"
+#include "guichanfwd.h"
+
+#include <guichan/widgetlistener.hpp>
+
+#include <guichan/widgets/window.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class ContainerPlacer;
+class Layout;
+class LayoutCell;
+class ResizeGrip;
+class Skin;
+class WindowContainer;
+
+/**
+ * A window. This window can be dragged around and has a title bar. Windows are
+ * invisible by default.
+ *
+ * \ingroup GUI
+ */
+class Window : public gcn::Window, gcn::WidgetListener
+{
+ public:
+ /**
+ * Constructor. Initializes the title to the given text and hooks
+ * itself into the window container.
+ *
+ * @param caption The initial window title, "Window" by default.
+ * @param modal Block input to other windows.
+ * @param parent The parent window. This is the window standing above
+ * this one in the window hiearchy. When reordering,
+ * a window will never go below its parent window.
+ * @param skin The location where the window's skin XML can be found.
+ */
+ Window(const std::string &caption = "Window", bool modal = false,
+ Window *parent = NULL, const std::string &skin = "window.xml");
+
+ /**
+ * Destructor. Deletes all the added widgets.
+ */
+ ~Window();
+
+ /**
+ * Sets the window container to be used by new windows.
+ */
+ static void setWindowContainer(WindowContainer *windowContainer);
+
+ /**
+ * Draws the window.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Sets the size of this window.
+ */
+ void setContentSize(int width, int height);
+
+ /**
+ * Sets the location relative to the given widget.
+ */
+ void setLocationRelativeTo(gcn::Widget *widget);
+
+ /**
+ * Sets the location relative to the given widget (only horisontally)
+ */
+ void setLocationHorisontallyRelativeTo(gcn::Widget *widget);
+
+ /**
+ * Sets the location relative to the given enumerated position.
+ */
+ void setLocationRelativeTo(ImageRect::ImagePosition position,
+ int offsetX = 0, int offsetY = 0);
+
+ /**
+ * Sets whether or not the window can be resized.
+ */
+ void setResizable(bool resize);
+
+ void redraw();
+
+ /**
+ * Called whenever the widget changes size.
+ */
+ void widgetResized(const gcn::Event &event);
+
+ /**
+ * Called whenever the widget is hidden.
+ */
+ virtual void widgetHidden(const gcn::Event& event);
+
+ /**
+ * Sets whether or not the window has a close button.
+ */
+ void setCloseButton(bool flag);
+
+ /**
+ * Returns whether the window can be resized.
+ */
+ bool isResizable() const;
+
+ /**
+ * Sets the minimum width of the window.
+ */
+ void setMinWidth(int width);
+
+ int getMinWidth() const
+ { return mMinWinWidth; }
+
+ /**
+ * Sets the minimum height of the window.
+ */
+ void setMinHeight(int height);
+
+ int getMinHeight() const
+ { return mMinWinHeight; }
+
+ /**
+ * Sets the maximum width of the window.
+ */
+ void setMaxWidth(int width);
+
+ int getMaxWidth() const
+ { return mMaxWinWidth; }
+
+ /**
+ * Sets the minimum height of the window.
+ */
+ void setMaxHeight(int height);
+
+ int getMaxHeight() const
+ { return mMaxWinHeight; }
+
+ /**
+ * Sets flag to show a title or not.
+ */
+ void setShowTitle(bool flag)
+ { mShowTitle = flag; }
+
+ /**
+ * Sets whether or not the window has a sticky button.
+ */
+ void setStickyButton(bool flag);
+
+ /**
+ * Sets whether the window is sticky. A sticky window will not have
+ * its visibility set to false on a general setVisible(false) call.
+ * Use this to set the default before you call loadWindowState().
+ */
+ void setSticky(bool sticky);
+
+ /**
+ * Returns whether the window is sticky.
+ */
+ bool isSticky() const
+ { return mSticky; }
+
+ /**
+ * Overloads window setVisible by Guichan to allow sticky window
+ * handling.
+ */
+ virtual void setVisible(bool visible);
+
+ /**
+ * Overloads window setVisible by Guichan to allow sticky window
+ * handling, or not, if you force the sticky state.
+ */
+ void setVisible(bool visible, bool forceSticky);
+
+ /**
+ * Returns whether the window is visible by default.
+ */
+ bool isDefaultVisible() const
+ { return mDefaultVisible; }
+
+ /**
+ * Sets whether the window is visible by default.
+ */
+ void setDefaultVisible(bool save)
+ { mDefaultVisible = save; }
+
+ /**
+ * Returns whether the window will save it's visibility.
+ */
+ bool willSaveVisible() const
+ { return mSaveVisible; }
+
+ /**
+ * Sets whether the window will save it's visibility.
+ */
+ void setSaveVisible(bool save)
+ { mSaveVisible = save; }
+
+ /**
+ * Returns the parent window.
+ *
+ * @return The parent window or <code>NULL</code> if there is none.
+ */
+ Window *getParentWindow() const
+ { return mParent; }
+
+ /**
+ * Schedule this window for deletion. It will be deleted at the start
+ * of the next logic update.
+ */
+ void scheduleDelete();
+
+ /**
+ * Starts window resizing when appropriate.
+ */
+ void mousePressed(gcn::MouseEvent &event);
+
+ /**
+ * Implements window resizing and makes sure the window is not
+ * dragged/resized outside of the screen.
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Implements custom cursor image changing context, based on mouse
+ * relative position.
+ */
+ void mouseMoved(gcn::MouseEvent &event);
+
+ /**
+ * When the mouse button has been let go, this ensures that the mouse
+ * custom cursor is restored back to it's standard image.
+ */
+ void mouseReleased(gcn::MouseEvent &event);
+
+ /**
+ * When the mouse leaves the window this ensures that the custom cursor
+ * is restored back to it's standard image.
+ */
+ void mouseExited(gcn::MouseEvent &event);
+
+ /**
+ * Sets the name of the window. This is not the window title.
+ */
+ void setWindowName(const std::string &name)
+ { mWindowName = name; }
+
+ /**
+ * Returns the name of the window. This is not the window title.
+ */
+ const std::string &getWindowName() const
+ { return mWindowName; }
+
+ /**
+ * Reads the position (and the size for resizable windows) in the
+ * configuration based on the given string.
+ * Uses the default values when config values are missing.
+ * Don't forget to set these default values and resizable before
+ * calling this function.
+ */
+ void loadWindowState();
+
+ /**
+ * Saves the window state so that when the window is reloaded, it'll
+ * maintain its previous state and location.
+ */
+ void saveWindowState();
+
+ /**
+ * Set the default win pos and size.
+ * (which can be different of the actual ones.)
+ */
+ void setDefaultSize(int defaultX, int defaultY,
+ int defaultWidth, int defaultHeight);
+
+ /**
+ * Set the default win pos and size to the current ones.
+ */
+ void setDefaultSize();
+
+ /**
+ * Set the default win pos and size.
+ * (which can be different of the actual ones.)
+ * This version of setDefaultSize sets the window's position based
+ * on a relative enumerated position, rather than a coordinate position.
+ */
+ void setDefaultSize(int defaultWidth, int defaultHeight,
+ ImageRect::ImagePosition position,
+ int offsetx = 0, int offsetY = 0);
+
+ /**
+ * Reset the win pos and size to default. Don't forget to set defaults
+ * first.
+ */
+ virtual void resetToDefaultSize();
+
+ /**
+ * Gets the layout handler for this window.
+ */
+ Layout &getLayout();
+
+ /**
+ * Clears the window's layout (useful for redesigning the window). Does
+ * not delete the widgets!
+ */
+ void clearLayout();
+
+ /**
+ * Computes the position of the widgets according to the current
+ * layout. Resizes the window so that the layout fits. Deletes the
+ * layout.
+ * @param w if non-zero, force the window to this width.
+ * @param h if non-zero, force the window to this height.
+ * @note This function is meant to be called with fixed-size windows.
+ */
+ void reflowLayout(int w = 0, int h = 0);
+
+ /**
+ * Adds a widget to the window and sets it at given cell.
+ */
+ LayoutCell &place(int x, int y, gcn::Widget *, int w = 1, int h = 1);
+
+ /**
+ * Returns a proxy for adding widgets in an inner table of the layout.
+ */
+ ContainerPlacer getPlacer(int x, int y);
+
+ /**
+ * Positions the window in the center of it's parent.
+ */
+ void center();
+
+ /**
+ * Positions the window in the horisontal center of it's parent.
+ */
+ void centerHorisontally();
+
+ /**
+ * Overrideable functionality for when the window is to close. This
+ * allows for class implementations to clean up or do certain actions
+ * on window close they couldn't do otherwise.
+ */
+ virtual void close();
+
+ /**
+ * Allows the windows modal status to change
+ */
+ void setModal(bool modal);
+
+ /**
+ * Gets the alpha value used by the window, in a GUIChan usable format.
+ */
+ int getGuiAlpha();
+
+ gcn::Rectangle getWindowArea();
+
+ bool isResizeAllowed(gcn::MouseEvent &event);
+
+ private:
+ enum ResizeHandles
+ {
+ TOP = 0x01,
+ RIGHT = 0x02,
+ BOTTOM = 0x04,
+ LEFT = 0x08
+ };
+
+ /**
+ * Check if the window is off-screen and then move it to be visible
+ * again. This is internally used by loadWindowState
+ * and setVisible(true) members.
+ */
+ void checkIfIsOffScreen(bool partially = true, bool entirely = true);
+
+ /**
+ * Determines if the mouse is in a resize area and returns appropriate
+ * resize handles. Also initializes drag offset in case the resize
+ * grip is used.
+ *
+ * @see ResizeHandles
+ */
+ int getResizeHandles(gcn::MouseEvent &event);
+
+ ResizeGrip *mGrip; /**< Resize grip */
+ Window *mParent; /**< The parent window */
+ Layout *mLayout; /**< Layout handler */
+ std::string mWindowName; /**< Name of the window */
+ bool mShowTitle; /**< Window has a title bar */
+ bool mModal; /**< Window is modal */
+ bool mCloseButton; /**< Window has a close button */
+ bool mDefaultVisible; /**< Window's default visibility */
+ bool mSaveVisible; /**< Window will save visibility */
+ bool mStickyButton; /**< Window has a sticky button */
+ bool mSticky; /**< Window resists hiding*/
+ int mMinWinWidth; /**< Minimum window width */
+ int mMinWinHeight; /**< Minimum window height */
+ int mMaxWinWidth; /**< Maximum window width */
+ int mMaxWinHeight; /**< Maximum window height */
+ int mDefaultX; /**< Default window X position */
+ int mDefaultY; /**< Default window Y position */
+ int mDefaultWidth; /**< Default window width */
+ int mDefaultHeight; /**< Default window height */
+
+ static int mouseResize; /**< Active resize handles */
+ static int instances; /**< Number of Window instances */
+
+ Skin *mSkin; /**< Skin in use by this window */
+
+ /**
+ * The width of the resize border. Is independent of the actual window
+ * border width, and determines mostly the size of the corner area
+ * where two borders are moved at the same time.
+ */
+ static const int resizeBorderWidth = 10;
+};
+
+#endif
diff --git a/src/gui/widgets/windowcontainer.cpp b/src/gui/widgets/windowcontainer.cpp
new file mode 100644
index 000000000..0fff491e4
--- /dev/null
+++ b/src/gui/widgets/windowcontainer.cpp
@@ -0,0 +1,40 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/widgets/windowcontainer.h"
+
+#include "utils/dtor.h"
+
+WindowContainer *windowContainer = NULL;
+
+void WindowContainer::logic()
+{
+ delete_all(mDeathList);
+ mDeathList.clear();
+
+ gcn::Container::logic();
+}
+
+void WindowContainer::scheduleDelete(gcn::Widget *widget)
+{
+ if (widget)
+ mDeathList.push_back(widget);
+}
diff --git a/src/gui/widgets/windowcontainer.h b/src/gui/widgets/windowcontainer.h
new file mode 100644
index 000000000..2ec65d15a
--- /dev/null
+++ b/src/gui/widgets/windowcontainer.h
@@ -0,0 +1,59 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WINDOWCONTAINER_H
+#define WINDOWCONTAINER_H
+
+#include "gui/widgets/container.h"
+
+/**
+ * A window container. This container adds functionality for more convenient
+ * widget (windows in particular) destruction.
+ *
+ * \ingroup GUI
+ */
+class WindowContainer : public Container
+{
+ public:
+ /**
+ * Do GUI logic. This functions adds automatic deletion of objects that
+ * volunteered to be deleted.
+ */
+ void logic();
+
+ /**
+ * Schedule a widget for deletion. It will be deleted at the start of
+ * the next logic update.
+ */
+ void scheduleDelete(gcn::Widget *widget);
+
+ private:
+ /**
+ * List of widgets that are scheduled to be deleted.
+ */
+ typedef std::list<gcn::Widget*> Widgets;
+ typedef Widgets::iterator WidgetIterator;
+ Widgets mDeathList;
+};
+
+extern WindowContainer *windowContainer;
+
+#endif
diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp
new file mode 100644
index 000000000..eb146f700
--- /dev/null
+++ b/src/gui/windowmenu.cpp
@@ -0,0 +1,285 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/windowmenu.h"
+
+#include "emoteshortcut.h"
+#include "graphics.h"
+#include "keyboardconfig.h"
+
+#include "gui/emotepopup.h"
+#include "gui/skilldialog.h"
+#include "gui/specialswindow.h"
+#include "gui/textpopup.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/window.h"
+#include "gui/widgets/windowcontainer.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+
+#include "utils/gettext.h"
+
+#include <string>
+
+extern Window *equipmentWindow;
+extern Window *inventoryWindow;
+extern Window *itemShortcutWindow;
+extern Window *dropShortcutWindow;
+extern Window *setupWindow;
+extern Window *statusWindow;
+extern Window *whoIsOnline;
+extern Window *killStats;
+extern Window *spellShortcutWindow;
+extern Window *botCheckerWindow;
+extern Window *socialWindow;
+
+WindowMenu::WindowMenu():
+ mEmotePopup(0)
+{
+ int x = 0, h = 0;
+
+ addButton(N_("BC"), _("Bot checker"), x, h,
+ KeyboardConfig::KEY_WINDOW_BOT_CHECKER);
+ addButton(N_("ONL"), _("Who is online"), x, h,
+ KeyboardConfig::KEY_NO_VALUE);
+ addButton(N_("KS"), _("Kill stats"), x, h,
+ KeyboardConfig::KEY_WINDOW_KILLS);
+ addButton(":-)", _("Smiles"), x, h,
+ KeyboardConfig::KEY_WINDOW_EMOTE_SHORTCUT);
+ addButton(N_("STA"), _("Status"), x, h, KeyboardConfig::KEY_WINDOW_STATUS);
+ addButton(N_("EQU"), _("Equipment"), x, h,
+ KeyboardConfig::KEY_WINDOW_EQUIPMENT);
+ addButton(N_("INV"), _("Inventory"), x, h,
+ KeyboardConfig::KEY_WINDOW_INVENTORY);
+
+ if (skillDialog->hasSkills())
+ {
+ addButton(N_("SKI"), _("Skills"), x, h,
+ KeyboardConfig::KEY_WINDOW_SKILL);
+ }
+
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ addButton(N_("SPE"), _("Specials"), x, h,
+ KeyboardConfig::KEY_NO_VALUE);
+ }
+
+ addButton(N_("SOC"), _("Social"), x, h, KeyboardConfig::KEY_WINDOW_SOCIAL);
+ addButton(N_("SH"), _("Shortcuts"), x, h,
+ KeyboardConfig::KEY_WINDOW_SHORTCUT);
+ addButton(N_("SP"), _("Spells"), x, h, KeyboardConfig::KEY_WINDOW_SPELLS);
+ addButton(N_("DR"), _("Drop"), x, h, KeyboardConfig::KEY_WINDOW_DROP);
+ addButton(N_("SET"), _("Setup"), x, h, KeyboardConfig::KEY_WINDOW_SETUP);
+
+ mTextPopup = new TextPopup;
+ setDimension(gcn::Rectangle(graphics->getWidth() - x - 3, 3,
+ x - 3, h));
+
+ addMouseListener(this);
+ setVisible(true);
+}
+
+WindowMenu::~WindowMenu()
+{
+ delete mTextPopup;
+ mTextPopup = 0;
+ mButtonNames.clear();
+}
+
+void WindowMenu::action(const gcn::ActionEvent &event)
+{
+ Window *window = 0;
+
+ if (event.getId() == ":-)")
+ {
+ if (!mEmotePopup)
+ {
+ const gcn::Widget *s = event.getSource();
+ if (s)
+ {
+ const gcn::Rectangle &r = s->getDimension();
+ const int parentX = s->getParent()->getX();
+
+ mEmotePopup = new EmotePopup;
+ const int offset = (r.width - mEmotePopup->getWidth()) / 2;
+ mEmotePopup->setPosition(parentX + r.x + offset,
+ r.y + r.height + 5);
+
+ mEmotePopup->addSelectionListener(this);
+ }
+ else
+ {
+ mEmotePopup = 0;
+ }
+ }
+ else
+ {
+ if (windowContainer)
+ windowContainer->scheduleDelete(mEmotePopup);
+ mEmotePopup = 0;
+ }
+ }
+ else if (event.getId() == "STA")
+ {
+ window = statusWindow;
+ }
+ else if (event.getId() == "EQU")
+ {
+ window = equipmentWindow;
+ }
+ else if (event.getId() == "INV")
+ {
+ window = inventoryWindow;
+ }
+ else if (event.getId() == "SKI")
+ {
+ window = skillDialog;
+ }
+ else if (event.getId() == "SPE")
+ {
+ window = specialsWindow;
+ }
+ else if (event.getId() == "SH")
+ {
+ window = itemShortcutWindow;
+ }
+ else if (event.getId() == "SOC")
+ {
+ window = socialWindow;
+ }
+ else if (event.getId() == "DR")
+ {
+ window = dropShortcutWindow;
+ }
+ else if (event.getId() == "SET")
+ {
+ window = setupWindow;
+ }
+ else if (event.getId() == "ONL")
+ {
+ window = whoIsOnline;
+ }
+ else if (event.getId() == "KS")
+ {
+ window = killStats;
+ }
+ else if (event.getId() == "BC")
+ {
+ window = botCheckerWindow;
+ }
+ else if (event.getId() == "SP")
+ {
+ window = spellShortcutWindow;
+ }
+
+ if (window)
+ {
+ window->setVisible(!window->isVisible());
+ if (window->isVisible())
+ window->requestMoveToTop();
+ }
+}
+
+void WindowMenu::valueChanged(const gcn::SelectionEvent &event)
+{
+ if (event.getSource() == mEmotePopup)
+ {
+ int emote = mEmotePopup->getSelectedEmote();
+ if (emote && emoteShortcut)
+ emoteShortcut->useEmote(emote);
+
+ if (windowContainer)
+ windowContainer->scheduleDelete(mEmotePopup);
+ mEmotePopup = 0;
+ }
+}
+
+void WindowMenu::addButton(const char* text, std::string description,
+ int &x, int &h, int key)
+{
+ Button *btn = new Button(gettext(text), text, this);
+ btn->setPosition(x, 0);
+ btn->setDescription(description);
+ btn->setTag(key);
+ add(btn);
+ mButtons.push_back(btn);
+ x += btn->getWidth() + 3;
+ h = btn->getHeight();
+ mButtonNames[text] = btn;
+}
+
+void WindowMenu::mousePressed(gcn::MouseEvent &event)
+{
+ if (!viewport)
+ return;
+
+ if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ Button *btn = dynamic_cast<Button*>(event.getSource());
+ if (!btn)
+ return;
+ if (viewport)
+ viewport->showPopup(event.getX(), event.getY(), btn);
+ }
+}
+
+void WindowMenu::mouseMoved(gcn::MouseEvent &event)
+{
+ if (!mTextPopup)
+ return;
+
+ if (event.getSource() == this)
+ {
+ mTextPopup->hide();
+ return;
+ }
+
+ Button *btn = dynamic_cast<Button*>(event.getSource());
+
+ if (!btn)
+ {
+ mTextPopup->hide();
+ return;
+ }
+
+ const int x = event.getX();
+ const int y = event.getY();
+ int key = btn->getTag();
+ if (key != KeyboardConfig::KEY_NO_VALUE)
+ {
+ mTextPopup->show(x + getX(), y + getY(), btn->getDescription(),
+ "Key: " + keyboard.getKeyValueString(key));
+ }
+ else
+ {
+ mTextPopup->show(x + getX(), y + getY(), btn->getDescription());
+ }
+}
+
+void WindowMenu::mouseExited(gcn::MouseEvent& mouseEvent _UNUSED_)
+{
+ if (!mTextPopup)
+ return;
+
+ mTextPopup->hide();
+} \ No newline at end of file
diff --git a/src/gui/windowmenu.h b/src/gui/windowmenu.h
new file mode 100644
index 000000000..f619a161a
--- /dev/null
+++ b/src/gui/windowmenu.h
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WINDOWMENU_H
+#define WINDOWMENU_H
+
+#include "gui/widgets/container.h"
+#include "gui/widgets/button.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+#include <map>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class EmotePopup;
+class TextPopup;
+
+/**
+ * The window menu. Allows showing and hiding many of the different windows
+ * used in the game.
+ *
+ * \ingroup Interface
+ */
+class WindowMenu : public Container,
+ public gcn::ActionListener,
+ public gcn::SelectionListener,
+ public gcn::MouseListener
+{
+ public:
+ WindowMenu();
+ ~WindowMenu();
+
+ void action(const gcn::ActionEvent &event);
+
+ void valueChanged(const gcn::SelectionEvent &event);
+
+ void mousePressed(gcn::MouseEvent &event);
+
+ void mouseMoved(gcn::MouseEvent &event);
+
+ void mouseExited(gcn::MouseEvent& mouseEvent _UNUSED_);
+
+ std::map <std::string, gcn::Button*> &getButtonNames()
+ { return mButtonNames; }
+
+ private:
+ inline void addButton(const char* text, std::string description,
+ int &x, int &h, int key);
+
+ EmotePopup *mEmotePopup;
+ TextPopup *mTextPopup;
+ std::list <gcn::Button*> mButtons;
+ std::map <std::string, gcn::Button*> mButtonNames;
+};
+
+extern WindowMenu *windowMenu;
+
+#endif
diff --git a/src/gui/worldselectdialog.cpp b/src/gui/worldselectdialog.cpp
new file mode 100644
index 000000000..f00871bd8
--- /dev/null
+++ b/src/gui/worldselectdialog.cpp
@@ -0,0 +1,139 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "gui/worldselectdialog.h"
+
+#include "client.h"
+
+#include "gui/sdlinput.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/listbox.h"
+#include "gui/widgets/scrollarea.h"
+
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+#include "net/worldinfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern WorldInfo **server_info;
+
+/**
+ * The list model for the server list.
+ */
+class WorldListModel : public gcn::ListModel
+{
+ public:
+ WorldListModel(Worlds worlds):
+ mWorlds(worlds)
+ {
+ }
+
+ virtual ~WorldListModel() {}
+
+ int getNumberOfElements()
+ {
+ return static_cast<int>(mWorlds.size());
+ }
+
+ std::string getElementAt(int i)
+ {
+ const WorldInfo *si = mWorlds[i];
+ if (si)
+ return si->name + " (" + toString(si->online_users) + ")";
+ else
+ return "???";
+ }
+ private:
+ Worlds mWorlds;
+};
+
+WorldSelectDialog::WorldSelectDialog(Worlds worlds):
+ Window(_("Select World"))
+{
+ mWorldListModel = new WorldListModel(worlds);
+ mWorldList = new ListBox(mWorldListModel);
+ ScrollArea *worldsScroll = new ScrollArea(mWorldList);
+ mChangeLoginButton = new Button(_("Change Login"), "login", this);
+ mChooseWorld = new Button(_("Choose World"), "world", this);
+
+ worldsScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ place(0, 0, worldsScroll, 3, 5).setPadding(2);
+ place(1, 5, mChangeLoginButton);
+ place(2, 5, mChooseWorld);
+
+ // Make sure the list has enough height
+ getLayout().setRowHeight(0, 60);
+
+ reflowLayout(0, 0);
+
+ if (worlds.size() == 0)
+ // Disable Ok button
+ mChooseWorld->setEnabled(false);
+ else
+ // Select first server
+ mWorldList->setSelected(0);
+
+ addKeyListener(this);
+
+ center();
+ setVisible(true);
+ mChooseWorld->requestFocus();
+}
+
+WorldSelectDialog::~WorldSelectDialog()
+{
+ delete mWorldListModel;
+ mWorldListModel = 0;
+}
+
+void WorldSelectDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "world")
+ {
+ mChangeLoginButton->setEnabled(false);
+ mChooseWorld->setEnabled(false);
+ Net::getLoginHandler()->chooseServer(mWorldList->getSelected());
+
+ // Check in case netcode moves us forward
+ if (Client::getState() == STATE_WORLD_SELECT)
+ Client::setState(STATE_WORLD_SELECT_ATTEMPT);
+ }
+ else if (event.getId() == "login")
+ {
+ Client::setState(STATE_LOGIN);
+ }
+}
+
+void WorldSelectDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ESCAPE)
+ action(gcn::ActionEvent(NULL, mChangeLoginButton->getActionEventId()));
+ else if (key.getValue() == Key::ENTER)
+ action(gcn::ActionEvent(NULL, mChooseWorld->getActionEventId()));
+}
diff --git a/src/gui/worldselectdialog.h b/src/gui/worldselectdialog.h
new file mode 100644
index 000000000..e22438714
--- /dev/null
+++ b/src/gui/worldselectdialog.h
@@ -0,0 +1,73 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WORLD_SELECT_DIALOG_H
+#define WORLD_SELECT_DIALOG_H
+
+#include "gui/widgets/window.h"
+
+#include "net/worldinfo.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/listmodel.hpp>
+
+#include <vector>
+
+class LoginData;
+class WorldListModel;
+
+/**
+ * The server select dialog.
+ *
+ * \ingroup Interface
+ */
+class WorldSelectDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ WorldSelectDialog(Worlds worlds);
+
+ /**
+ * Destructor.
+ */
+ ~WorldSelectDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ private:
+ WorldListModel *mWorldListModel;
+ gcn::ListBox *mWorldList;
+ gcn::Button *mChangeLoginButton;
+ gcn::Button *mChooseWorld;
+};
+
+#endif // WORLD_SELECT_DIALOG_H
diff --git a/src/guichanfwd.h b/src/guichanfwd.h
new file mode 100644
index 000000000..42141028e
--- /dev/null
+++ b/src/guichanfwd.h
@@ -0,0 +1,101 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUICHANFWD_H
+#define GUICHANFWD_H
+
+namespace gcn
+{
+ class ActionEvent;
+ class ActionListener;
+ class AllegroFont;
+ class AllegroGraphics;
+ class AllegroImage;
+ class AllegroImageLoader;
+ class AllegroInput;
+ class BasicContainer;
+ class Button;
+ class CheckBox;
+ class ClipRectangle;
+ class Color;
+ class Container;
+ class DefaultFont;
+ class DropDown;
+ class Event;
+ class Exception;
+ class FocusHandler;
+ class FocusListener;
+ class Font;
+ class GenericInput;
+ class Graphics;
+ class Gui;
+ class HGEGraphics;
+ class HGEImage;
+ class HGEImageFont;
+ class HGEImageLoader;
+ class HGEInput;
+ class Icon;
+ class Image;
+ class ImageButton;
+ class InputEvent;
+ class ImageFont;
+ class ImageLoader;
+ class Input;
+ class Key;
+ class KeyEvent;
+ class KeyInput;
+ class KeyListener;
+ class Label;
+ class ListBox;
+ class ListModel;
+ class MouseEvent;
+ class MouseInput;
+ class MouseListener;
+ class OpenGLAllegroImageLoader;
+ class OpenGLGraphics;
+ class OpenGLImage;
+ class OpenGLSDLImageLoader;
+ class OpenLayerFont;
+ class OpenLayerGraphics;
+ class OpenLayerImage;
+ class OpenLayerImageLoader;
+ class OpenLayerInput;
+ class RadioButton;
+ class Rectangle;
+ class ScrollArea;
+ class SDLGraphics;
+ class SDLImage;
+ class SDLImageLoader;
+ class SDLInput;
+ class SDLPixel;
+ class SelectionEvent;
+ class SelectionListener;
+ class Slider;
+ class Tab;
+ class TabbedArea;
+ class TextBox;
+ class TextField;
+ class Widget;
+ class WidgetListener;
+ class Window;
+}
+
+#endif
diff --git a/src/guild.cpp b/src/guild.cpp
new file mode 100644
index 000000000..c79c574b9
--- /dev/null
+++ b/src/guild.cpp
@@ -0,0 +1,296 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "guild.h"
+
+#include "actorspritemanager.h"
+
+class SortGuildFunctor
+{
+ public:
+ bool operator() (GuildMember* m1, GuildMember* m2)
+ {
+ if (!m1 || !m2)
+ return false;
+ if (m1->getPos() != m2->getPos())
+ return m1->getPos() < m2->getPos();
+
+ return m1->getName() < m2->getName();
+ }
+} guildSorter;
+
+GuildMember::GuildMember(Guild *guild, int accountId, int charId,
+ const std::string &name):
+ Avatar(name), mGuild(guild), mPos(0)
+{
+ mId = accountId;
+ mCharId = charId;
+}
+
+GuildMember::GuildMember(Guild *guild, const std::string &name):
+ Avatar(name), mGuild(guild), mPos(0)
+{
+}
+
+std::string GuildMember::getAdditionString() const
+{
+ if (!mGuild)
+ return "";
+
+ return " - " + mGuild->getPos(mPos);
+}
+
+Guild::GuildMap Guild::guilds;
+
+Guild::Guild(short id):
+ mId(id),
+ mCanInviteUsers(false),
+ mEmblemId(0)
+{
+ guilds[id] = this;
+}
+
+GuildMember *Guild::addMember(int accountId, int charId,
+ const std::string &name)
+{
+ GuildMember *m;
+ if ((m = getMember(accountId, charId)))
+ return m;
+
+ m = new GuildMember(this, accountId, charId, name);
+
+ mMembers.push_back(m);
+
+ return m;
+}
+
+GuildMember *Guild::addMember(const std::string &name)
+{
+ GuildMember *m;
+ if ((m = getMember(name)))
+ return m;
+
+ m = new GuildMember(this, name);
+
+ mMembers.push_back(m);
+
+ return m;
+}
+
+GuildMember *Guild::getMember(int id) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == id)
+ return (*itr);
+ ++itr;
+ }
+
+ return NULL;
+}
+
+GuildMember *Guild::getMember(int accountId, int charId) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == accountId && (*itr)->mCharId == charId)
+ return (*itr);
+ ++itr;
+ }
+
+ return NULL;
+}
+
+GuildMember *Guild::getMember(const std::string &name) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->getName() == name)
+ return (*itr);
+ ++itr;
+ }
+
+ return NULL;
+}
+
+void Guild::removeMember(GuildMember *member)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == member->mId &&
+ (*itr)->mCharId == member->mCharId &&
+ (*itr)->getName() == member->getName())
+ {
+ mMembers.erase(itr);
+ delete *itr;
+ }
+ ++itr;
+ }
+}
+
+void Guild::removeMember(int id)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == id)
+ mMembers.erase(itr);
+ ++itr;
+ }
+}
+
+void Guild::removeMember(const std::string &name)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->getName() == name)
+ mMembers.erase(itr);
+ ++itr;
+ }
+}
+
+void Guild::removeFromMembers()
+{
+ if (!actorSpriteManager)
+ return;
+
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ Being *b = actorSpriteManager->findBeing((*itr)->getID());
+ if (b)
+ b->removeGuild(getId());
+ ++itr;
+ }
+}
+
+Avatar *Guild::getAvatarAt(int index)
+{
+ return mMembers[index];
+}
+
+void Guild::setRights(short rights)
+{
+ // to invite, rights must be greater than 0
+ if (rights > 0)
+ mCanInviteUsers = true;
+}
+
+bool Guild::isMember(GuildMember *member) const
+{
+ if (member->mGuild > 0 && member->mGuild != this)
+ return false;
+
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == member->mId &&
+ (*itr)->getName() == member->getName())
+ {
+ return true;
+ }
+ ++itr;
+ }
+
+ return false;
+}
+
+bool Guild::isMember(int id) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == id)
+ return true;
+ ++itr;
+ }
+
+ return false;
+}
+
+bool Guild::isMember(const std::string &name) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->getName() == name)
+ return true;
+ ++itr;
+ }
+
+ return false;
+}
+
+void Guild::getNames(std::vector<std::string> &names) const
+{
+ names.clear();
+ MemberList::const_iterator it = mMembers.begin(),
+ it_end = mMembers.end();
+
+ while (it != it_end)
+ {
+ names.push_back((*it)->getName());
+ ++it;
+ }
+}
+
+void Guild::addPos(int id, std::string name)
+{
+ mPositions[id] = name;
+}
+
+Guild *Guild::getGuild(short id)
+{
+ GuildMap::iterator it = guilds.find(id);
+ if (it != guilds.end())
+ return it->second;
+
+ return new Guild(id);
+}
+
+std::string Guild::getPos(int id) const
+{
+ PositionsMap::const_iterator it = mPositions.find(id);
+ if (it == mPositions.end())
+ return "";
+ else
+ return it->second;
+}
+
+void Guild::sort()
+{
+ std::sort(mMembers.begin(), mMembers.end(), guildSorter);
+} \ No newline at end of file
diff --git a/src/guild.h b/src/guild.h
new file mode 100644
index 000000000..2d3cb646a
--- /dev/null
+++ b/src/guild.h
@@ -0,0 +1,199 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUILD_H
+#define GUILD_H
+
+#include "avatar.h"
+
+#include "gui/widgets/avatarlistbox.h"
+
+#include "utils/dtor.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class Guild;
+
+typedef std::map<unsigned, std::string> PositionsMap;
+
+class GuildMember : public Avatar
+{
+public:
+ Guild *getGuild() const
+ { return mGuild; }
+
+ int getPos()
+ { return mPos; }
+
+ void setPos(int pos)
+ { mPos = pos; }
+
+ std::string getAdditionString() const;
+
+protected:
+ friend class Guild;
+
+ GuildMember(Guild *guild, int id, int accountId, const std::string &name);
+
+ GuildMember(Guild *guild, const std::string &name);
+
+ Guild *mGuild;
+ int mPos;
+};
+
+class Guild : public AvatarListModel
+{
+public:
+ /**
+ * Set the guild's name.
+ */
+ void setName(const std::string &name)
+ { mName = name; }
+
+ /**
+ * Adds member to the list.
+ */
+ GuildMember *addMember(int accountId, int charId, const std::string &name);
+
+ /**
+ * Adds member to the list.
+ */
+ GuildMember *addMember(const std::string &name);
+
+ /**
+ * Find a member by ID.
+ *
+ * @return the member with the given ID, or NULL if they don't exist.
+ */
+ GuildMember *getMember(int id) const;
+
+ /**
+ * Find a member by account ID and char ID.
+ *
+ * @return the member with the given ID, or NULL if they don't exist.
+ */
+ GuildMember *getMember(int accountId, int charId) const;
+
+ /**
+ * Find a member by name.
+ *
+ * @return the member with the given name, or NULL if they don't exist.
+ */
+ GuildMember *getMember(const std::string &name) const;
+
+ /**
+ * Get the name of the guild.
+ * @return returns name of the guild
+ */
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Get the id of the guild.
+ * @return Returns the id of the guild
+ */
+ short getId() const
+ { return mId; }
+
+ /**
+ * Removes a member from the guild.
+ */
+ void removeMember(GuildMember *member);
+
+ /**
+ * Removes a member from the guild.
+ */
+ void removeMember(int id);
+
+ /**
+ * Removes a member from the guild.
+ */
+ void removeMember(const std::string &name);
+
+ void removeFromMembers();
+
+ void clearMembers()
+ { delete_all(mMembers); mMembers.clear(); }
+
+ /**
+ * Get size of members list.
+ * @return Returns the number of members in the guild.
+ */
+ int getNumberOfElements()
+ { return static_cast<int>(mMembers.size()); }
+
+ Avatar *getAvatarAt(int i);
+
+ /**
+ * Get whether user can invite users to this guild.
+ * @return Returns true if user can invite users
+ */
+ bool getInviteRights() const
+ { return mCanInviteUsers; }
+
+ void setRights(short rights);
+
+ bool isMember(GuildMember *member) const;
+
+ bool isMember(int id) const;
+
+ bool isMember(const std::string &name) const;
+
+ void getNames(std::vector<std::string> &names) const;
+
+ void addPos(int id, std::string name);
+
+ void sort();
+
+ std::string getPos(int id) const;
+
+ static Guild *getGuild(short id);
+
+ const PositionsMap &getPositions() const
+ { return mPositions; }
+
+ void setEmblemId(int id)
+ { mEmblemId = id; }
+
+ int getEmblemId()
+ { return mEmblemId; }
+
+private:
+ typedef std::map<int, Guild*> GuildMap;
+ static GuildMap guilds;
+
+ /**
+ * Constructor with guild id passed to it.
+ */
+ Guild(short id);
+
+ typedef std::vector<GuildMember*> MemberList;
+ MemberList mMembers;
+ std::string mName;
+ short mId;
+ bool mCanInviteUsers;
+ int mEmblemId;
+ PositionsMap mPositions;
+};
+
+#endif // GUILD_H
diff --git a/src/imageparticle.cpp b/src/imageparticle.cpp
new file mode 100644
index 000000000..d2195a533
--- /dev/null
+++ b/src/imageparticle.cpp
@@ -0,0 +1,91 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "imageparticle.h"
+
+#include "graphics.h"
+
+#include "resources/image.h"
+
+std::map<std::string, int> ImageParticle::imageParticleCountByName;
+
+ImageParticle::ImageParticle(Map *map, Image *image):
+ Particle(map),
+ mImage(image)
+{
+ if (mImage)
+ {
+ mImage->incRef();
+
+ std::string name = mImage->getIdPath();
+ if (ImageParticle::imageParticleCountByName.find(name)
+ == ImageParticle::imageParticleCountByName.end())
+ {
+ ImageParticle::imageParticleCountByName[name] = 1;
+ }
+ else
+ {
+ ImageParticle::imageParticleCountByName[name] ++;
+ }
+ }
+}
+
+ImageParticle::~ImageParticle()
+{
+ if (mImage)
+ {
+ std::string name = mImage->getIdPath();
+ if (ImageParticle::imageParticleCountByName[name] > 0)
+ ImageParticle::imageParticleCountByName[name] --;
+
+ mImage->decRef();
+ }
+}
+
+bool ImageParticle::draw(Graphics *graphics, int offsetX, int offsetY) const
+{
+ if (!isAlive() || !mImage)
+ return false;
+
+ int screenX = (int) mPos.x + offsetX - mImage->getWidth() / 2;
+ int screenY = (int) mPos.y - (int)mPos.z
+ + offsetY - mImage->getHeight() / 2;
+
+ // Check if on screen
+ if (screenX + mImage->getWidth() < 0 ||
+ screenX > graphics->getWidth() ||
+ screenY + mImage->getHeight() < 0 ||
+ screenY > graphics->getHeight())
+ {
+ return false;
+ }
+
+ float alphafactor = mAlpha;
+
+ if (mFadeOut && mLifetimeLeft > -1 && mLifetimeLeft < mFadeOut)
+ alphafactor *= (float) mLifetimeLeft / (float) mFadeOut;
+
+ if (mFadeIn && mLifetimePast < mFadeIn)
+ alphafactor *= (float) mLifetimePast / (float) mFadeIn;
+
+ mImage->setAlpha(alphafactor);
+ return graphics->drawImage(mImage, screenX, screenY);
+}
diff --git a/src/imageparticle.h b/src/imageparticle.h
new file mode 100644
index 000000000..792bd4933
--- /dev/null
+++ b/src/imageparticle.h
@@ -0,0 +1,61 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef IMAGEPARTICLE_H
+#define IMAGEPARTICLE_H
+
+#include "particle.h"
+
+#include <map>
+
+class Image;
+class Map;
+
+/**
+ * A particle that uses an image for its visualization.
+ */
+class ImageParticle : public Particle
+{
+ public:
+ /**
+ * Constructor. The image is reference counted by this particle.
+ *
+ * @param map the map this particle appears on
+ * @param image an Image instance, may not be NULL
+ */
+ ImageParticle(Map *map, Image *image);
+
+ /**
+ * Destructor.
+ */
+ ~ImageParticle();
+
+ /**
+ * Draws the particle image
+ */
+ virtual bool draw(Graphics *graphics, int offsetX, int offsetY) const;
+
+ static std::map<std::string, int> imageParticleCountByName;
+ protected:
+ Image *mImage; /**< The image used for this particle. */
+};
+
+#endif
diff --git a/src/imagesprite.cpp b/src/imagesprite.cpp
new file mode 100644
index 000000000..7db3c96d1
--- /dev/null
+++ b/src/imagesprite.cpp
@@ -0,0 +1,54 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "imagesprite.h"
+
+#include "graphics.h"
+
+ImageSprite::ImageSprite(Image *image):
+ mImage(image)
+{
+ if (mImage)
+ {
+ mAlpha = mImage->getAlpha();
+ mImage->incRef();
+ }
+ else
+ {
+ mAlpha = 1;
+ }
+}
+
+ImageSprite::~ImageSprite()
+{
+ if (mImage)
+ mImage->decRef();
+}
+
+bool ImageSprite::draw(Graphics* graphics, int posX, int posY) const
+{
+ if (!mImage)
+ return false;
+
+ if (mImage->getAlpha() != mAlpha)
+ mImage->setAlpha(mAlpha);
+
+ return graphics->drawImage(mImage, posX, posY);
+}
diff --git a/src/imagesprite.h b/src/imagesprite.h
new file mode 100644
index 000000000..b59cd18d0
--- /dev/null
+++ b/src/imagesprite.h
@@ -0,0 +1,79 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef IMAGESPRITE_H
+#define IMAGESPRITE_H
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+#include "sprite.h"
+
+#include "resources/image.h"
+
+class Graphics;
+
+class ImageSprite : public Sprite
+{
+public:
+ ImageSprite(Image *image);
+
+ ~ImageSprite();
+
+ bool reset()
+ { return false; }
+
+ bool play(std::string action _UNUSED_)
+ { return false; }
+
+ bool update(int time _UNUSED_)
+ { return false; }
+
+ bool draw(Graphics* graphics, int posX, int posY) const;
+
+ int getWidth() const
+ { return mImage ? mImage->getWidth() : 0; }
+
+ int getHeight() const
+ { return mImage ? mImage->getHeight() : 0; }
+
+ const Image* getImage() const
+ { return mImage; }
+
+ virtual bool setDirection(SpriteDirection direction _UNUSED_)
+ { return false; }
+
+ int getNumberOfLayers()
+ { return 1; }
+
+ unsigned int getCurrentFrame() const
+ { return 0; }
+
+ unsigned int getFrameCount() const
+ { return 1; }
+
+private:
+ Image *mImage;
+};
+
+#endif // IMAGESPRITE_H
diff --git a/src/inventory.cpp b/src/inventory.cpp
new file mode 100644
index 000000000..23387cadb
--- /dev/null
+++ b/src/inventory.cpp
@@ -0,0 +1,225 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "inventory.h"
+#include "item.h"
+#include "log.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "resources/iteminfo.h"
+
+#include <algorithm>
+#include <string>
+
+struct SlotUsed : public std::unary_function<Item*, bool>
+{
+ bool operator()(const Item *item) const
+ {
+ return item && item->getId() >= 0 && item->getQuantity() > 0;
+ }
+};
+
+Inventory::Inventory(int type, int size):
+ mType(type),
+ mSize(size == -1 ? Net::getInventoryHandler()->getSize(type)
+ : static_cast<unsigned>(size)),
+ mUsed(0)
+{
+ mItems = new Item*[mSize];
+ std::fill_n(mItems, mSize, (Item*) 0);
+}
+
+Inventory::~Inventory()
+{
+ for (unsigned i = 0; i < mSize; i++)
+ delete mItems[i];
+
+ delete [] mItems;
+ mItems = 0;
+}
+
+Item *Inventory::getItem(int index) const
+{
+ if (index < 0 || index >= static_cast<int>(mSize) || !mItems[index]
+ || mItems[index]->getQuantity() <= 0)
+ {
+ return 0;
+ }
+
+ return mItems[index];
+}
+
+Item *Inventory::findItem(int itemId) const
+{
+ for (unsigned i = 0; i < mSize; i++)
+ {
+ if (mItems[i] && mItems[i]->getId() == itemId)
+ return mItems[i];
+ }
+
+ return 0;
+}
+
+void Inventory::addItem(int id, int quantity, int refine, bool equipment)
+{
+ setItem(getFreeSlot(), id, quantity, refine, equipment);
+}
+
+void Inventory::setItem(int index, int id, int quantity,
+ int refine, bool equipment)
+{
+ if (index < 0 || index >= static_cast<int>(mSize))
+ {
+ logger->log("Warning: invalid inventory index: %d", index);
+ return;
+ }
+
+ if (!mItems[index] && id > 0)
+ {
+ Item *item = new Item(id, quantity, refine, equipment);
+ item->setInvIndex(index);
+ mItems[index] = item;
+ mUsed++;
+ distributeSlotsChangedEvent();
+ }
+ else if (id > 0 && mItems[index])
+ {
+ mItems[index]->setId(id);
+ mItems[index]->setQuantity(quantity);
+ mItems[index]->setRefine(refine);
+ mItems[index]->setEquipment(equipment);
+ }
+ else if (mItems[index])
+ {
+ removeItemAt(index);
+ }
+}
+
+void Inventory::clear()
+{
+ for (unsigned i = 0; i < mSize; i++)
+ removeItemAt(i);
+}
+
+void Inventory::removeItem(int id)
+{
+ for (unsigned i = 0; i < mSize; i++)
+ {
+ if (mItems[i] && mItems[i]->getId() == id)
+ removeItemAt(i);
+ }
+}
+
+void Inventory::removeItemAt(int index)
+{
+ delete mItems[index];
+ mItems[index] = 0;
+ mUsed--;
+ if (mUsed < 0) // Already at 0, no need to distribute event
+ mUsed = 0;
+ else
+ distributeSlotsChangedEvent();
+}
+
+bool Inventory::contains(Item *item) const
+{
+ for (unsigned i = 0; i < mSize; i++)
+ {
+ if (mItems[i] && mItems[i]->getId() == item->getId())
+ return true;
+ }
+
+ return false;
+}
+
+int Inventory::getFreeSlot() const
+{
+ Item **i = std::find_if(mItems, mItems + mSize,
+ std::not1(SlotUsed()));
+ return (i == mItems + static_cast<int>(mSize)) ? -1 : (i - mItems);
+}
+
+int Inventory::getLastUsedSlot() const
+{
+ for (int i = mSize - 1; i >= 0; i--)
+ {
+ if (SlotUsed()(mItems[i]))
+ return i;
+ }
+
+ return -1;
+}
+
+void Inventory::addInventoyListener(InventoryListener* listener)
+{
+ mInventoryListeners.push_back(listener);
+}
+
+void Inventory::removeInventoyListener(InventoryListener* listener)
+{
+ mInventoryListeners.remove(listener);
+}
+
+void Inventory::distributeSlotsChangedEvent()
+{
+ InventoryListenerList::const_iterator i = mInventoryListeners.begin();
+ InventoryListenerList::const_iterator i_end = mInventoryListeners.end();
+ for (; i != i_end; i++)
+ (*i)->slotsChanged(this);
+}
+
+Item *Inventory::findItemBySprite(std::string spritePath, Gender gender)
+{
+ spritePath = removeSpriteIndex(spritePath);
+// logger->log1("Inventory::FindItemBySprite sprite: " + spritePath);
+
+ std::string spritePathShort = extractNameFromSprite(spritePath);
+// logger->log1("Inventory::FindItemBySprite spriteShort: " + spritePathShort);
+ int partialIndex = -1;
+
+ for (unsigned i = 0; i < mSize; i++)
+ {
+ if (mItems[i])
+ {
+ std::string path = mItems[i]->getInfo().getSprite(gender);
+ if (!path.empty())
+ {
+ path = removeSpriteIndex(path);
+
+// logger->log("Inventory::FindItemBySprite normal: " + path);
+
+ if (spritePath == path)
+ return mItems[i];
+
+ path = extractNameFromSprite(path);
+// logger->log("Inventory::FindItemBySprite short: " + path);
+ if (spritePathShort == path)
+ partialIndex = i;
+ }
+ }
+ }
+ if (partialIndex != -1)
+ return mItems[partialIndex];
+
+ return 0;
+}
diff --git a/src/inventory.h b/src/inventory.h
new file mode 100644
index 000000000..c09492e22
--- /dev/null
+++ b/src/inventory.h
@@ -0,0 +1,160 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef INVENTORY_H
+#define INVENTORY_H
+
+#include "being.h"
+
+#include <list>
+#include <string>
+
+class Inventory;
+class Item;
+
+class InventoryListener
+{
+public:
+ virtual ~InventoryListener() {}
+
+ virtual void slotsChanged(Inventory* inventory) = 0;
+
+protected:
+ InventoryListener() {}
+};
+
+class Inventory
+{
+ public:
+ static const int NO_SLOT_INDEX = -1; /**< Slot has no index. */
+
+ enum
+ {
+ INVENTORY = 0,
+ STORAGE,
+ TRADE,
+ TYPE_END
+ };
+
+
+ /**
+ * Constructor.
+ *
+ * @param size the number of items that fit in the inventory
+ */
+ Inventory(int type, int size = -1);
+
+ /**
+ * Destructor.
+ */
+ ~Inventory();
+
+ /**
+ * Returns the size that this instance is configured for.
+ */
+ unsigned getSize() const
+ { return mSize; }
+
+ /**
+ * Returns the item at the specified index.
+ */
+ Item *getItem(int index) const;
+
+ /**
+ * Searches for the specified item by it's id.
+ *
+ * @param itemId The id of the item to be searched.
+ * @return Item found on success, NULL on failure.
+ */
+ Item *findItem(int itemId) const;
+
+ /**
+ * Adds a new item in a free slot.
+ */
+ void addItem(int id, int quantity, int refine, bool equipment = false);
+
+ /**
+ * Sets the item at the given position.
+ */
+ void setItem(int index, int id, int quantity, int refine,
+ bool equipment = false);
+
+ /**
+ * Remove a item from the inventory.
+ */
+ void removeItem(int id);
+
+ /**
+ * Remove the item at the specified index from the inventory.
+ */
+ void removeItemAt(int index);
+
+ /**
+ * Checks if the given item is in the inventory.
+ */
+ bool contains(Item *item) const;
+
+ /**
+ * Returns id of next free slot or -1 if all occupied.
+ */
+ int getFreeSlot() const;
+
+ /**
+ * Reset all item slots.
+ */
+ void clear();
+
+ /**
+ * Get the number of slots filled with an item
+ */
+ int getNumberOfSlotsUsed() const
+ { return mUsed; }
+
+ /**
+ * Returns the index of the last occupied slot or 0 if none occupied.
+ */
+ int getLastUsedSlot() const;
+
+ void addInventoyListener(InventoryListener* listener);
+
+ void removeInventoyListener(InventoryListener* listener);
+
+ int getType() const
+ { return mType; }
+
+ bool isMainInventory() const
+ { return mType == INVENTORY; }
+
+ Item *findItemBySprite(std::string spritePath, Gender gender);
+
+ protected:
+ typedef std::list<InventoryListener*> InventoryListenerList;
+ InventoryListenerList mInventoryListeners;
+
+ void distributeSlotsChangedEvent();
+
+ int mType;
+ Item **mItems; /**< The holder of items */
+ unsigned mSize; /**< The max number of inventory items */
+ int mUsed; /**< THe number of slots in use */
+};
+
+#endif
diff --git a/src/item.cpp b/src/item.cpp
new file mode 100644
index 000000000..94eaf383e
--- /dev/null
+++ b/src/item.cpp
@@ -0,0 +1,94 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "item.h"
+
+#include "gui/theme.h"
+
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
+#include "configuration.h"
+
+Item::Item(int id, int quantity, int refine, bool equipment, bool equipped):
+ mImage(0),
+ mDrawImage(0),
+ mQuantity(quantity),
+ mEquipment(equipment),
+ mEquipped(equipped),
+ mInEquipment(false),
+ mRefine(refine),
+ mInvIndex(0)
+{
+ setId(id);
+}
+
+Item::~Item()
+{
+ if (mImage)
+ mImage->decRef();
+}
+
+void Item::setId(int id)
+{
+ mId = id;
+
+ // Types 0 and 1 are not equippable items.
+ mEquipment = id && getInfo().getType() >= 2;
+
+ // Load the associated image
+ if (mImage)
+ mImage->decRef();
+
+ if (mDrawImage)
+ mDrawImage->decRef();
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ SpriteDisplay display = getInfo().getDisplay();
+ std::string imagePath = paths.getStringValue("itemIcons")
+ + display.image;
+ mImage = resman->getImage(imagePath);
+ mDrawImage = resman->getImage(imagePath);
+
+ if (!mImage)
+ {
+ mImage = Theme::getImageFromTheme(paths.getValue("unknownItemFile",
+ "unknown-item.png"));
+ }
+
+ if (!mDrawImage)
+ {
+ mDrawImage = Theme::getImageFromTheme(
+ paths.getValue("unknownItemFile", "unknown-item.png"));
+ }
+}
+
+Image *Item::getImage(int id)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ SpriteDisplay display = ItemDB::get(id).getDisplay();
+ std::string imagePath = "graphics/items/" + display.image;
+ Image *image = resman->getImage(imagePath);
+
+ if (!image)
+ image = Theme::getImageFromTheme("unknown-item.png");
+ return image;
+}
diff --git a/src/item.h b/src/item.h
new file mode 100644
index 000000000..520028f8f
--- /dev/null
+++ b/src/item.h
@@ -0,0 +1,167 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEM_H
+#define ITEM_H
+
+#include "resources/itemdb.h"
+
+class Image;
+
+/**
+ * Represents one or more instances of a certain item type.
+ */
+class Item
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Item(int id = -1, int quantity = 0, int refine = 0,
+ bool equipment = false, bool equipped = false);
+
+ /**
+ * Destructor.
+ */
+ virtual ~Item();
+
+ /**
+ * Sets the item id, identifying the item type.
+ */
+ void setId(int id);
+
+ /**
+ * Returns the item id.
+ */
+ int getId() const
+ { return mId; }
+
+ /**
+ * Returns the item image.
+ */
+ Image *getImage() const
+ { return mImage; }
+
+ /**
+ * Returns the item image.
+ */
+ Image *getDrawImage() const
+ { return mDrawImage; }
+
+ /**
+ * Sets the number of items.
+ */
+ void setQuantity(int quantity)
+ { mQuantity = quantity; }
+
+ /**
+ * Increases the number of items by the given amount.
+ */
+ void increaseQuantity(int amount)
+ { mQuantity += amount; }
+
+ /**
+ * Returns the number of items.
+ */
+ int getQuantity() const
+ { return mQuantity; }
+
+ /**
+ * Sets whether this item is considered equipment.
+ */
+ void setEquipment(bool equipment)
+ { mEquipment = equipment; }
+
+ /**
+ * Returns whether this item is considered equipment.
+ */
+ bool isEquipment() const
+ { return mEquipment; }
+
+ /**
+ * Sets whether this item is equipped.
+ */
+ void setEquipped(bool equipped)
+ { mEquipped = equipped; }
+
+ /**
+ * Returns whether this item is equipped.
+ */
+ bool isEquipped() const
+ { return mEquipped; }
+
+ /**
+ * Sets this item refine level.
+ */
+ void setRefine(int refine)
+ { mRefine = refine; }
+
+ /**
+ * Returns this item refine level.
+ */
+ int getRefine() const
+ { return mRefine; }
+
+ /**
+ * Sets whether this item is in equipment.
+ */
+ void setInEquipment(bool inEquipment)
+ { mInEquipment = inEquipment; }
+
+ /**
+ * Returns whether this item is in equipment.
+ */
+ bool isInEquipment() const
+ { return mInEquipment; }
+
+ /**
+ * Sets the inventory index of this item.
+ */
+ void setInvIndex(int index)
+ { mInvIndex = index; }
+
+ /**
+ * Returns the inventory index of this item.
+ */
+ int getInvIndex() const
+ { return mInvIndex; }
+
+ /**
+ * Returns information about this item type.
+ */
+ const ItemInfo &getInfo() const
+ { return ItemDB::get(mId); }
+
+ static Image *getImage(int id);
+
+ protected:
+ int mId; /**< Item type id. */
+ Image *mImage; /**< Item image. */
+ Image *mDrawImage; /**< Draw image. */
+ int mQuantity; /**< Number of items. */
+ bool mEquipment; /**< Item is equipment. */
+ bool mEquipped; /**< Item is equipped. */
+ bool mInEquipment; /**< Item is in equipment */
+ int mRefine; /**< Item refine level. */
+ int mInvIndex; /**< Inventory index. */
+};
+
+#endif
diff --git a/src/itemshortcut.cpp b/src/itemshortcut.cpp
new file mode 100644
index 000000000..bef6ba5e2
--- /dev/null
+++ b/src/itemshortcut.cpp
@@ -0,0 +1,155 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "configuration.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "spellmanager.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "utils/stringutils.h"
+
+ItemShortcut *itemShortcut[SHORTCUT_TABS];
+
+ItemShortcut::ItemShortcut(int number):
+ mItemSelected(-1),
+ mNumber(number)
+{
+ load();
+}
+
+ItemShortcut::~ItemShortcut()
+{
+ logger->log1("ItemShortcut::~ItemShortcut");
+}
+
+void ItemShortcut::load(bool oldConfig)
+{
+ std::string name;
+ Configuration *cfg;
+ if (oldConfig)
+ cfg = &config;
+ else
+ cfg = &serverConfig;
+
+ if (mNumber)
+ name = "shortcut" + toString(mNumber) + "_";
+ else
+ name = "shortcut";
+ for (int i = 0; i < SHORTCUT_ITEMS; i++)
+ {
+ int itemId = (int) cfg->getValue(name + toString(i), -1);
+
+ mItems[i] = itemId;
+ }
+}
+
+void ItemShortcut::save()
+{
+ std::string name;
+ if (mNumber)
+ name = "shortcut" + toString(mNumber) + "_";
+ else
+ name = "shortcut";
+
+ logger->log("save %s", name.c_str());
+
+ for (int i = 0; i < SHORTCUT_ITEMS; i++)
+ {
+ const int itemId = mItems[i] ? mItems[i] : -1;
+ serverConfig.setValue(name + toString(i), itemId);
+ }
+}
+
+void ItemShortcut::useItem(int index)
+{
+ if (!PlayerInfo::getInventory())
+ return;
+
+ int itemId = mItems[index];
+ if (itemId >= 0)
+ {
+ if (itemId < SPELL_MIN_ID)
+ {
+ Item *item = PlayerInfo::getInventory()->findItem(itemId);
+ if (item && item->getQuantity())
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ else
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ else
+ {
+ Net::getInventoryHandler()->useItem(item);
+ }
+ }
+ }
+ else if (spellManager)
+ {
+ spellManager->useItem(itemId);
+ }
+ }
+}
+
+void ItemShortcut::equipItem(int index)
+{
+ if (!PlayerInfo::getInventory())
+ return;
+
+ if (mItems[index])
+ {
+ Item *item = PlayerInfo::getInventory()->findItem(mItems[index]);
+ if (item && item->getQuantity())
+ {
+ if (item->isEquipment())
+ {
+ if (!item->isEquipped())
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ }
+ }
+}
+void ItemShortcut::unequipItem(int index)
+{
+ if (!PlayerInfo::getInventory())
+ return;
+
+ if (mItems[index])
+ {
+ Item *item = PlayerInfo::getInventory()->findItem(mItems[index]);
+ if (item && item->getQuantity())
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ }
+ }
+ }
+}
diff --git a/src/itemshortcut.h b/src/itemshortcut.h
new file mode 100644
index 000000000..e4797e134
--- /dev/null
+++ b/src/itemshortcut.h
@@ -0,0 +1,146 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEMSHORTCUT_H
+#define ITEMSHORTCUT_H
+
+#define SHORTCUT_ITEMS 20
+
+#define SHORTCUT_TABS 3
+
+class Item;
+
+/**
+ * The class which keeps track of the item shortcuts.
+ */
+class ItemShortcut
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ItemShortcut(int number);
+
+ /**
+ * Destructor.
+ */
+ ~ItemShortcut();
+
+ /**
+ * Load the configuration information.
+ */
+ void load(bool oldConfig = 0);
+
+ /**
+ * Save the configuration information.
+ */
+ void save();
+
+ /**
+ * Returns the shortcut item ID specified by the index.
+ *
+ * @param index Index of the shortcut item.
+ */
+ int getItem(int index) const
+ { return mItems[index]; }
+
+ /**
+ * Returns the amount of shortcut items.
+ */
+ int getItemCount() const
+ { return SHORTCUT_ITEMS; }
+
+ /**
+ * Returns the item ID that is currently selected.
+ */
+ int getItemSelected() const
+ { return mItemSelected; }
+
+ /**
+ * Adds the selected item ID to the items specified by the index.
+ *
+ * @param index Index of the items.
+ */
+ void setItem(int index)
+ { mItems[index] = mItemSelected; save(); }
+
+ /**
+ * Adds an item to the items store specified by the index.
+ *
+ * @param index Index of the item.
+ * @param itemId ID of the item.
+ */
+ void setItems(int index, int itemId)
+ { mItems[index] = itemId; save(); }
+
+ /**
+ * Set the item that is selected.
+ *
+ * @param itemId The ID of the item that is to be assigned.
+ */
+ void setItemSelected(int itemId)
+ { mItemSelected = itemId; }
+
+ /**
+ * Returns selected shortcut item ID.
+ */
+ int getSelectedItem() const
+ { return mItemSelected; }
+
+ /**
+ * A flag to check if the item is selected.
+ */
+ bool isItemSelected() const
+ { return mItemSelected > -1; }
+
+ /**
+ * Remove a item from the shortcut.
+ */
+ void removeItem(int index)
+ { mItems[index] = -1; save(); }
+
+ /**
+ * Try to use the item specified by the index.
+ *
+ * @param index Index of the item shortcut.
+ */
+ void useItem(int index);
+
+ /**
+ * Equip a item from the shortcut.
+ */
+ void equipItem(int index);
+
+ /**
+ * UnEquip a item from the shortcut.
+ */
+ void unequipItem(int index);
+
+ private:
+
+ int mItems[SHORTCUT_ITEMS]; /**< The items stored. */
+ int mItemSelected; /**< The item held by cursor. */
+ int mNumber;
+};
+
+extern ItemShortcut *itemShortcut[SHORTCUT_TABS];
+
+#endif
diff --git a/src/joystick.cpp b/src/joystick.cpp
new file mode 100644
index 000000000..8d59d2783
--- /dev/null
+++ b/src/joystick.cpp
@@ -0,0 +1,150 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "configuration.h"
+#include "joystick.h"
+#include "log.h"
+
+#include <cassert>
+
+int Joystick::joystickCount = 0;
+
+void Joystick::init()
+{
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+
+ // Have SDL call SDL_JoystickUpdate() automatically
+ SDL_JoystickEventState(SDL_ENABLE);
+
+ joystickCount = SDL_NumJoysticks();
+ logger->log("%i joysticks/gamepads found", joystickCount);
+ for (int i = 0; i < joystickCount; i++)
+ logger->log("- %s", SDL_JoystickName(i));
+}
+
+Joystick::Joystick(int no):
+ mDirection(0),
+ mCalibrating(false),
+ mEnabled(false)
+{
+ assert(no < joystickCount);
+
+ mJoystick = SDL_JoystickOpen(no);
+
+ // TODO Bail out!
+ if (!mJoystick)
+ {
+ logger->log("Couldn't open joystick: %s", SDL_GetError());
+ return;
+ }
+
+ logger->log("Axes: %i ", SDL_JoystickNumAxes(mJoystick));
+ logger->log("Balls: %i", SDL_JoystickNumBalls(mJoystick));
+ logger->log("Hats: %i", SDL_JoystickNumHats(mJoystick));
+ logger->log("Buttons: %i", SDL_JoystickNumButtons(mJoystick));
+
+ mEnabled = config.getBoolValue("joystickEnabled");
+ mUpTolerance = config.getIntValue("upTolerance");
+ mDownTolerance = config.getIntValue("downTolerance");
+ mLeftTolerance = config.getIntValue("leftTolerance");
+ mRightTolerance = config.getIntValue("rightTolerance");
+
+ for (int i = 0; i < MAX_BUTTONS; i++)
+ mButtons[i] = false;
+}
+
+Joystick::~Joystick()
+{
+ SDL_JoystickClose(mJoystick);
+}
+
+void Joystick::update()
+{
+ mDirection = 0;
+
+ // When calibrating, don't bother the outside with our state
+ if (mCalibrating)
+ {
+ doCalibration();
+ return;
+ };
+
+ if (!mEnabled)
+ return;
+
+ // X-Axis
+ int position = SDL_JoystickGetAxis(mJoystick, 0);
+ if (position >= mRightTolerance)
+ mDirection |= RIGHT;
+ else if (position <= mLeftTolerance)
+ mDirection |= LEFT;
+
+ // Y-Axis
+ position = SDL_JoystickGetAxis(mJoystick, 1);
+ if (position <= mUpTolerance)
+ mDirection |= UP;
+ else if (position >= mDownTolerance)
+ mDirection |= DOWN;
+
+ // Buttons
+ for (int i = 0; i < MAX_BUTTONS; i++)
+ mButtons[i] = (SDL_JoystickGetButton(mJoystick, i) == 1);
+}
+
+void Joystick::startCalibration()
+{
+ mUpTolerance = 0;
+ mDownTolerance = 0;
+ mLeftTolerance = 0;
+ mRightTolerance = 0;
+ mCalibrating = true;
+}
+
+void Joystick::doCalibration()
+{
+ // X-Axis
+ int position = SDL_JoystickGetAxis(mJoystick, 0);
+ if (position > mRightTolerance)
+ mRightTolerance = position;
+ else if (position < mLeftTolerance)
+ mLeftTolerance = position;
+
+ // Y-Axis
+ position = SDL_JoystickGetAxis(mJoystick, 1);
+ if (position > mDownTolerance)
+ mDownTolerance = position;
+ else if (position < mUpTolerance)
+ mUpTolerance = position;
+}
+
+void Joystick::finishCalibration()
+{
+ config.setValue("leftTolerance", mLeftTolerance);
+ config.setValue("rightTolerance", mRightTolerance);
+ config.setValue("upTolerance", mUpTolerance);
+ config.setValue("downTolerance", mDownTolerance);
+ mCalibrating = false;
+}
+
+bool Joystick::buttonPressed(unsigned char no) const
+{
+ return (mEnabled && no < MAX_BUTTONS) ? mButtons[no] : false;
+}
diff --git a/src/joystick.h b/src/joystick.h
new file mode 100644
index 000000000..da60686c7
--- /dev/null
+++ b/src/joystick.h
@@ -0,0 +1,114 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef JOYSTICK_H
+#define JOYSTICK_H
+
+#include <SDL.h>
+
+class Joystick
+{
+ public:
+ /**
+ * Number of buttons we can handle.
+ */
+ enum
+ {
+ MAX_BUTTONS = 6
+ };
+
+ /**
+ * Directions, to be used as bitmask values.
+ */
+ enum
+ {
+ UP = 1,
+ DOWN = 2,
+ LEFT = 4,
+ RIGHT = 8
+ };
+
+ /**
+ * Initializes the joystick subsystem.
+ */
+ static void init();
+
+ /**
+ * Returns the number of available joysticks.
+ */
+ static int getNumberOfJoysticks()
+ { return joystickCount; }
+
+ /**
+ * Constructor, pass the number of the joystick the new object
+ * should access.
+ */
+ Joystick(int no);
+
+ ~Joystick();
+
+ bool isEnabled() const
+ { return mEnabled; }
+
+ void setEnabled(bool enabled)
+ { mEnabled = enabled; }
+
+ /**
+ * Updates the direction and button information.
+ */
+ void update();
+
+ void startCalibration();
+
+ void finishCalibration();
+
+ bool isCalibrating() const
+ { return mCalibrating; }
+
+ bool buttonPressed(unsigned char no) const;
+
+ bool isUp() const
+ { return mEnabled && (mDirection & UP); };
+
+ bool isDown() const
+ { return mEnabled && (mDirection & DOWN); };
+
+ bool isLeft() const
+ { return mEnabled && (mDirection & LEFT); };
+
+ bool isRight() const
+ { return mEnabled && (mDirection & RIGHT); };
+
+ protected:
+ unsigned char mDirection;
+ bool mButtons[MAX_BUTTONS];
+ SDL_Joystick *mJoystick;
+
+ int mUpTolerance, mDownTolerance, mLeftTolerance, mRightTolerance;
+ bool mCalibrating;
+ bool mEnabled;
+
+ static int joystickCount;
+
+ void doCalibration();
+};
+
+#endif // JOYSTICK_H
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
new file mode 100644
index 000000000..fd3c3aa09
--- /dev/null
+++ b/src/keyboardconfig.cpp
@@ -0,0 +1,449 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "configuration.h"
+#include "keyboardconfig.h"
+#include "log.h"
+
+#include "gui/sdlinput.h"
+#include "gui/setup_keyboard.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+struct KeyData
+{
+ const char *configField;
+ int defaultValue;
+ std::string caption;
+ int grp;
+};
+
+// keyData must be in same order as enum keyAction.
+static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = {
+ {"keyMoveUp", SDLK_UP, _("Move Up"), KeyboardConfig::GRP_DEFAULT},
+ {"keyMoveDown", SDLK_DOWN, _("Move Down"), KeyboardConfig::GRP_DEFAULT},
+ {"keyMoveLeft", SDLK_LEFT, _("Move Left"), KeyboardConfig::GRP_DEFAULT},
+ {"keyMoveRight", SDLK_RIGHT, _("Move Right"), KeyboardConfig::GRP_DEFAULT},
+ {"keyAttack", SDLK_LCTRL, _("Attack"), KeyboardConfig::GRP_DEFAULT},
+ {"keyTargetAttack", SDLK_x, _("Target & Attack"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyMoveToTarget", SDLK_v, _("Move to Target"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChangeMoveToTarget", SDLK_PERIOD, _("Change Move to Target type"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyMoveToHome", SDLK_d, _("Move to Home location"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keySetHome", SDLK_KP5, _("Set home location"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyMoveToPoint", SDLK_RSHIFT, _("Move to navigation point"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keySmilie", SDLK_LALT, _("Smilie"), KeyboardConfig::GRP_DEFAULT},
+ {"keyTalk", SDLK_t, _("Talk"), KeyboardConfig::GRP_DEFAULT},
+ {"keyTarget", SDLK_LSHIFT, _("Stop Attack"), KeyboardConfig::GRP_DEFAULT},
+ {"keyTargetClosest", SDLK_a, _("Target Closest"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyTargetNPC", SDLK_n, _("Target NPC"), KeyboardConfig::GRP_DEFAULT},
+ {"keyTargetPlayer", SDLK_q, _("Target Player"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyPickup", SDLK_z, _("Pickup"), KeyboardConfig::GRP_DEFAULT},
+ {"keyChangePickupType", SDLK_o, _("Change Pickup Type"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyHideWindows", SDLK_h, _("Hide Windows"), KeyboardConfig::GRP_DEFAULT},
+ {"keyBeingSit", SDLK_s, _("Sit"), KeyboardConfig::GRP_DEFAULT},
+ {"keyScreenshot", SDLK_p, _("Screenshot"), KeyboardConfig::GRP_DEFAULT},
+ {"keyTrade", SDLK_r, _("Enable/Disable Trading"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyPathfind", SDLK_f, _("Change Map View Mode"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcutsKey", SDLK_MENU, _("Item Shortcuts Key"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut1", SDLK_1, strprintf(_("Item Shortcut %d"), 1),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut2", SDLK_2, strprintf(_("Item Shortcut %d"), 2),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut3", SDLK_3, strprintf(_("Item Shortcut %d"), 3),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut4", SDLK_4, strprintf(_("Item Shortcut %d"), 4),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut5", SDLK_5, strprintf(_("Item Shortcut %d"), 5),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut6", SDLK_6, strprintf(_("Item Shortcut %d"), 6),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut7", SDLK_7, strprintf(_("Item Shortcut %d"), 7),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut8", SDLK_8, strprintf(_("Item Shortcut %d"), 8),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut9", SDLK_9, strprintf(_("Item Shortcut %d"), 9),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut10", SDLK_0, strprintf(_("Item Shortcut %d"), 10),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut11", SDLK_MINUS, strprintf(_("Item Shortcut %d"), 11),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut12", SDLK_EQUALS, strprintf(_("Item Shortcut %d"), 12),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut13", SDLK_BACKSPACE, strprintf(_("Item Shortcut %d"), 13),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut14", SDLK_INSERT, strprintf(_("Item Shortcut %d"), 14),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut15", SDLK_HOME, strprintf(_("Item Shortcut %d"), 15),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut16", KeyboardConfig::KEY_NO_VALUE,
+ strprintf(_("Item Shortcut %d"), 16), KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut17", KeyboardConfig::KEY_NO_VALUE,
+ strprintf(_("Item Shortcut %d"), 17), KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut18", KeyboardConfig::KEY_NO_VALUE,
+ strprintf(_("Item Shortcut %d"), 18), KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut19", KeyboardConfig::KEY_NO_VALUE,
+ strprintf(_("Item Shortcut %d"), 19), KeyboardConfig::GRP_DEFAULT},
+ {"keyShortcut20", KeyboardConfig::KEY_NO_VALUE,
+ strprintf(_("Item Shortcut %d"), 20), KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowHelp", SDLK_F1, _("Help Window"), KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowStatus", SDLK_F2, _("Status Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowInventory", SDLK_F3, _("Inventory Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowEquipment", SDLK_F4, _("Equipment Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowSkill", SDLK_F5, _("Skill Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowMinimap", SDLK_F6, _("Minimap Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowChat", SDLK_F7, _("Chat Window"), KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowShortcut", SDLK_F8, _("Item Shortcut Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowSetup", SDLK_F9, _("Setup Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowDebug", SDLK_F10, _("Debug Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowSocial", SDLK_F11, _("Social Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowEmoteBar", SDLK_F12, _("Emote Shortcut Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowOutfit", SDLK_BACKQUOTE, _("Outfits Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowShop", -1, _("Shop Window"), KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowDrop", SDLK_w, _("Quick drop Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowKills", SDLK_e, _("Kills Stats Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowSpells", SDLK_j, _("Commands Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowBotChecker", SDLK_LEFTBRACKET, _("Bot Checker Window"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyWindowOnline", KeyboardConfig::KEY_NO_VALUE,
+ _("Who Is Online Window"), KeyboardConfig::GRP_DEFAULT},
+ {"keySocialPrevTab", KeyboardConfig::KEY_NO_VALUE,
+ _("Previous Social Tab"), KeyboardConfig::GRP_DEFAULT},
+ {"keySocialNextTab", KeyboardConfig::KEY_NO_VALUE, _("Next Social Tab"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyEmoteShortcut1", SDLK_1, strprintf(_("Emote Shortcut %d"), 1),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut2", SDLK_2, strprintf(_("Emote Shortcut %d"), 2),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut3", SDLK_3, strprintf(_("Emote Shortcut %d"), 3),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut4", SDLK_4, strprintf(_("Emote Shortcut %d"), 4),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut5", SDLK_5, strprintf(_("Emote Shortcut %d"), 5),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut6", SDLK_6, strprintf(_("Emote Shortcut %d"), 6),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut7", SDLK_7, strprintf(_("Emote Shortcut %d"), 7),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut8", SDLK_8, strprintf(_("Emote Shortcut %d"), 8),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut9", SDLK_9, strprintf(_("Emote Shortcut %d"), 9),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut10", SDLK_0, strprintf(_("Emote Shortcut %d"), 10),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut11", SDLK_MINUS, strprintf(_("Emote Shortcut %d"), 11),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut12", SDLK_EQUALS, strprintf(_("Emote Shortcut %d"), 12),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut13", SDLK_BACKSPACE,
+ strprintf(_("Emote Shortcut %d"), 13),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut14", SDLK_INSERT, strprintf(_("Emote Shortcut %d"), 14),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut15", SDLK_HOME, strprintf(_("Emote Shortcut %d"), 15),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut16", SDLK_q, strprintf(_("Emote Shortcut %d"), 16),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut17", SDLK_w, strprintf(_("Emote Shortcut %d"), 17),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut18", SDLK_e, strprintf(_("Emote Shortcut %d"), 18),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut19", SDLK_r, strprintf(_("Emote Shortcut %d"), 19),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut20", SDLK_t, strprintf(_("Emote Shortcut %d"), 20),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut21", SDLK_y, strprintf(_("Emote Shortcut %d"), 21),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut22", SDLK_u, strprintf(_("Emote Shortcut %d"), 22),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut23", SDLK_i, strprintf(_("Emote Shortcut %d"), 23),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut24", SDLK_o, strprintf(_("Emote Shortcut %d"), 24),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut25", SDLK_p, strprintf(_("Emote Shortcut %d"), 25),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut26", SDLK_LEFTBRACKET,
+ strprintf(_("Emote Shortcut %d"), 26),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut27", SDLK_RIGHTBRACKET,
+ strprintf(_("Emote Shortcut %d"), 27),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut28", SDLK_BACKSLASH,
+ strprintf(_("Emote Shortcut %d"), 28),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut29", SDLK_a, strprintf(_("Emote Shortcut %d"), 29),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut30", SDLK_s, strprintf(_("Emote Shortcut %d"), 30),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut31", SDLK_d, strprintf(_("Emote Shortcut %d"), 31),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut32", SDLK_f, strprintf(_("Emote Shortcut %d"), 32),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut33", SDLK_g, strprintf(_("Emote Shortcut %d"), 33),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut34", SDLK_h, strprintf(_("Emote Shortcut %d"), 34),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut35", SDLK_j, strprintf(_("Emote Shortcut %d"), 35),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut36", SDLK_k, strprintf(_("Emote Shortcut %d"), 36),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut37", SDLK_l, strprintf(_("Emote Shortcut %d"), 37),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut38", SDLK_SEMICOLON,
+ strprintf(_("Emote Shortcut %d"), 38),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut39", SDLK_QUOTE, strprintf(_("Emote Shortcut %d"), 39),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut40", SDLK_z, strprintf(_("Emote Shortcut %d"), 40),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut41", SDLK_x, strprintf(_("Emote Shortcut %d"), 41),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut42", SDLK_c, strprintf(_("Emote Shortcut %d"), 42),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyWearOutfit", SDLK_RCTRL, _("Wear Outfit"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyCopyOutfit", SDLK_RALT, _("Copy Outfit"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyCopyEquipedOutfit", SDLK_RIGHTBRACKET, _("Copy Equiped to Outfit"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChat", SDLK_RETURN, _("Toggle Chat"),
+ KeyboardConfig::GRP_DEFAULT | KeyboardConfig::GRP_CHAT},
+ {"keyChatScrollUp", SDLK_PAGEUP, _("Scroll Chat Up"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChatScrollDown", SDLK_PAGEDOWN, _("Scroll Chat Down"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChatPrevTab", SDLK_KP7, _("Previous Chat Tab"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChatNextTab", SDLK_KP9, _("Next Chat Tab"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChatPrevHistory", SDLK_KP7, _("Previous chat tab line"),
+ KeyboardConfig::GRP_CHAT},
+ {"keyChatNextHistory", SDLK_KP9, _("Next chat tab line"),
+ KeyboardConfig::GRP_CHAT},
+ {"keyAutoCompleteChat", SDLK_TAB, _("Chat Auto Complete"),
+ KeyboardConfig::GRP_CHAT},
+ {"keyDeActivateChat", SDLK_ESCAPE, _("Deactivate Chat Input"),
+ KeyboardConfig::GRP_CHAT},
+ {"keyOK", SDLK_SPACE, _("Select OK"), KeyboardConfig::GRP_DEFAULT},
+ {"keyQuit", SDLK_ESCAPE, _("Quit"), KeyboardConfig::GRP_DEFAULT},
+ {"keyIgnoreInput1", SDLK_LSUPER, _("Ignore input 1"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyIgnoreInput2", SDLK_RSUPER, _("Ignore input 2"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyDirectUp", SDLK_l, _("Direct Up"), KeyboardConfig::GRP_DEFAULT},
+ {"keyDirectDown", SDLK_SEMICOLON, _("Direct Down"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyDirectLeft", SDLK_k, _("Direct Left"), KeyboardConfig::GRP_DEFAULT},
+ {"keyDirectRight", SDLK_QUOTE, _("Direct Right"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyCrazyMoves", SDLK_SLASH, _("Crazy moves"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChangeCrazyMoveType", SDLK_BACKSLASH, _("Change Crazy Move mode"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyQuickDrop", SDLK_y, _("Quick Drop N Items from 0 slot"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyQuickDropN", SDLK_u, _("Quick Drop N Items"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keySwitchQuickDrop", SDLK_i, _("Switch Quick Drop Counter"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyMagicInma1", SDLK_c, _("Quick heal target or self"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyMagicItenplz", SDLK_m, _("Use #itenplz spell"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyMagicAttack", SDLK_b, _("Use magic attack"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keySwitchMagicAttack", SDLK_COMMA, _("Switch magic attack"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyInvertDirection", SDLK_KP0, _("Change move type"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChangeAttackWeaponType", SDLK_g, _("Change Attack Weapon Type"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChangeAttackType", SDLK_END, _("Change Attack Type"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChangeFollowMode", SDLK_KP1, _("Change Follow mode"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyChangeImitationMode", SDLK_KP4, _("Change Imitation mode"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyDisableGameModifiers", SDLK_KP8,
+ _("Disbale / Enable Game modifier keys"), KeyboardConfig::GRP_DEFAULT},
+ {"keyChangeAudio", SDLK_KP3, _("On / Off audio"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyAway", SDLK_KP2, _("Enable / Disable away mode"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyRightClick", SDLK_TAB, _("Emulate right click from keyboard"),
+ KeyboardConfig::GRP_DEFAULT},
+ {"keyCameraMode", SDLK_KP_PLUS, _("Toggle camera mode"),
+ KeyboardConfig::GRP_DEFAULT}
+};
+
+void KeyboardConfig::init()
+{
+ for (int i = 0; i < KEY_TOTAL; i++)
+ {
+ mKey[i].configField = keyData[i].configField;
+ mKey[i].defaultValue = keyData[i].defaultValue;
+ mKey[i].caption = keyData[i].caption;
+ mKey[i].value = KEY_NO_VALUE;
+ mKey[i].grp = keyData[i].grp;
+ }
+ mNewKeyIndex = KEY_NO_VALUE;
+ mEnabled = true;
+
+ retrieve();
+}
+
+void KeyboardConfig::retrieve()
+{
+ for (int i = 0; i < KEY_TOTAL; i++)
+ {
+ mKey[i].value = (int) config.getValue(
+ mKey[i].configField, mKey[i].defaultValue);
+ }
+}
+
+void KeyboardConfig::store()
+{
+ for (int i = 0; i < KEY_TOTAL; i++)
+ config.setValue(mKey[i].configField, mKey[i].value);
+}
+
+void KeyboardConfig::makeDefault()
+{
+ for (int i = 0; i < KEY_TOTAL; i++)
+ mKey[i].value = mKey[i].defaultValue;
+}
+
+bool KeyboardConfig::hasConflicts()
+{
+ int i, j;
+ /**
+ * No need to parse the square matrix: only check one triangle
+ * that's enough to detect conflicts
+ */
+ for (i = 0; i < KEY_TOTAL; i++)
+ {
+ if (mKey[i].value == KEY_NO_VALUE)
+ continue;
+
+ for (j = i, j++; j < KEY_TOTAL; j++)
+ {
+ // Allow for item shortcut and emote keys to overlap
+ // as well as emote and ignore keys, but no other keys
+ if (mKey[j].value != KEY_NO_VALUE &&
+ mKey[i].value == mKey[j].value &&
+ ((mKey[i].grp & mKey[j].grp) != 0)
+ )
+ {
+ mBindError = strprintf(_("Conflict \"%s\" and \"%s\" keys. "
+ "Resolve them, or gameplay may result"
+ " in strange behaviour."),
+ mKey[i].caption.c_str(),
+ mKey[j].caption.c_str());
+ return true;
+ }
+ }
+ }
+ mBindError = "";
+ return false;
+}
+
+void KeyboardConfig::callbackNewKey()
+{
+ mSetupKey->newKeyCallback(mNewKeyIndex);
+}
+
+int KeyboardConfig::getKeyIndex(int keyValue, int grp) const
+{
+ for (int i = 0; i < KEY_TOTAL; i++)
+ {
+ if (keyValue == mKey[i].value &&
+ (grp & mKey[i].grp) != 0)
+ {
+ return i;
+ }
+ }
+ return KEY_NO_VALUE;
+}
+
+
+int KeyboardConfig::getKeyEmoteOffset(int keyValue) const
+{
+ for (int i = KEY_EMOTE_1; i <= KEY_EMOTE_42; i++)
+ {
+ if (keyValue == mKey[i].value)
+ return 1 + i - KEY_EMOTE_1;
+ }
+ return 0;
+}
+
+bool KeyboardConfig::isKeyActive(int index) const
+{
+ if (!mActiveKeys)
+ return false;
+ return mActiveKeys[mKey[index].value];
+}
+
+void KeyboardConfig::refreshActiveKeys()
+{
+ mActiveKeys = SDL_GetKeyState(NULL);
+}
+
+std::string KeyboardConfig::getKeyValueString(int index) const
+{
+ std::string key = SDL_GetKeyName(
+ (SDLKey) getKeyValue(index));
+
+ return getKeyShortString(key);
+}
+
+std::string KeyboardConfig::getKeyShortString(const std::string &key) const
+{
+ if (key == "backspace")
+ return "bksp";
+ else if (key == "unknown key")
+ return "u key";
+ return key;
+} \ No newline at end of file
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
new file mode 100644
index 000000000..dbc90d2c4
--- /dev/null
+++ b/src/keyboardconfig.h
@@ -0,0 +1,333 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef KEYBOARDCONFIG_H
+#define KEYBOARDCONFIG_H
+
+#include <SDL_types.h>
+
+#include <string>
+
+/**
+ * Each key represents a key function. Such as 'Move up', 'Attack' etc.
+ */
+struct KeyFunction
+{
+ const char* configField; /** Field index that is in the config file. */
+ int defaultValue; /** The default key value used. */
+ std::string caption; /** The caption value for the key function. */
+ int value; /** The actual value that is used. */
+ int grp; /** The key group */
+};
+
+class Setup_Keyboard;
+
+class KeyboardConfig
+{
+ public:
+ /**
+ * Initializes the keyboard config explicitly.
+ */
+ void init();
+
+ /**
+ * Retrieve the key values from config file.
+ */
+ void retrieve();
+
+ /**
+ * Store the key values to config file.
+ */
+ void store();
+
+ /**
+ * Make the keys their default values.
+ */
+ void makeDefault();
+
+ /**
+ * Determines if any key assignments are the same as each other.
+ */
+ bool hasConflicts();
+
+ /**
+ * Calls a function back so the key re-assignment(s) can be seen.
+ */
+ void callbackNewKey();
+
+ /**
+ * Obtain the value stored in memory.
+ */
+ int getKeyValue(int index) const
+ { return mKey[index].value; }
+
+ /**
+ * Get the index of the new key to be assigned.
+ */
+ int getNewKeyIndex() const
+ { return mNewKeyIndex; }
+
+ /**
+ * Get the enable flag, which will stop the user from doing actions.
+ */
+ bool isEnabled() const
+ { return mEnabled; }
+
+ /**
+ * Get the key caption, providing more meaning to the user.
+ */
+ const std::string &getKeyCaption(int index) const
+ { return mKey[index].caption; }
+
+ /**
+ * Get the key function index by providing the keys value.
+ */
+ int getKeyIndex(int keyValue, int grp = 1) const;
+
+ /**
+ * Get the key function index for an emote by providing the offset value.
+ */
+ int getKeyEmoteOffset(int keyValue) const;
+
+ /**
+ * Set the enable flag, which will stop the user from doing actions.
+ */
+ void setEnabled(bool flag)
+ { mEnabled = flag; }
+
+ /**
+ * Set the index of the new key to be assigned.
+ */
+ void setNewKeyIndex(int value)
+ { mNewKeyIndex = value; }
+
+ /**
+ * Set the value of the new key.
+ */
+ void setNewKey(int value)
+ { mKey[mNewKeyIndex].value = value; }
+
+ /**
+ * Set a reference to the key setup window.
+ */
+ void setSetupKeyboard(Setup_Keyboard *setupKey)
+ { mSetupKey = setupKey; }
+
+ /**
+ * Checks if the key is active, by providing the key function index.
+ */
+ bool isKeyActive(int index) const;
+
+ /**
+ * Takes a snapshot of all the active keys.
+ */
+ void refreshActiveKeys();
+
+ std::string getKeyValueString(int index) const;
+
+ std::string getKeyShortString(const std::string &key) const;
+
+ const std::string &getBindError() const
+ { return mBindError; }
+
+ /**
+ * All the key functions.
+ * KEY_NO_VALUE is used in initialization, and should be unchanged.
+ * KEY_TOTAL should always be last (used as a conditional in loops).
+ * The key assignment view gets arranged according to the order of
+ * these values.
+ */
+ enum KeyAction
+ {
+ KEY_NO_VALUE = -1,
+ KEY_MOVE_UP,
+ KEY_MOVE_DOWN,
+ KEY_MOVE_LEFT,
+ KEY_MOVE_RIGHT,
+ KEY_ATTACK,
+ KEY_TARGET_ATTACK,
+ KEY_MOVE_TO_TARGET,
+ KEY_CHANGE_MOVE_TO_TARGET,
+ KEY_MOVE_TO_HOME,
+ KEY_SET_HOME,
+ KEY_MOVE_TO_POINT,
+ KEY_EMOTE,
+ KEY_TALK,
+ KEY_TARGET,
+ KEY_TARGET_CLOSEST,
+ KEY_TARGET_NPC,
+ KEY_TARGET_PLAYER,
+ KEY_PICKUP,
+ KEY_CHANGE_PICKUP_TYPE,
+ KEY_HIDE_WINDOWS,
+ KEY_SIT,
+ KEY_SCREENSHOT,
+ KEY_TRADE,
+ KEY_PATHFIND,
+ KEY_SHORTCUTS_KEY,
+ KEY_SHORTCUT_1,
+ KEY_SHORTCUT_2,
+ KEY_SHORTCUT_3,
+ KEY_SHORTCUT_4,
+ KEY_SHORTCUT_5,
+ KEY_SHORTCUT_6,
+ KEY_SHORTCUT_7,
+ KEY_SHORTCUT_8,
+ KEY_SHORTCUT_9,
+ KEY_SHORTCUT_10,
+ KEY_SHORTCUT_11,
+ KEY_SHORTCUT_12,
+ KEY_SHORTCUT_13,
+ KEY_SHORTCUT_14,
+ KEY_SHORTCUT_15,
+ KEY_SHORTCUT_16,
+ KEY_SHORTCUT_17,
+ KEY_SHORTCUT_18,
+ KEY_SHORTCUT_19,
+ KEY_SHORTCUT_20,
+ KEY_WINDOW_HELP,
+ KEY_WINDOW_STATUS,
+ KEY_WINDOW_INVENTORY,
+ KEY_WINDOW_EQUIPMENT,
+ KEY_WINDOW_SKILL,
+ KEY_WINDOW_MINIMAP,
+ KEY_WINDOW_CHAT,
+ KEY_WINDOW_SHORTCUT,
+ KEY_WINDOW_SETUP,
+ KEY_WINDOW_DEBUG,
+ KEY_WINDOW_SOCIAL,
+ KEY_WINDOW_EMOTE_SHORTCUT,
+ KEY_WINDOW_OUTFIT,
+ KEY_WINDOW_SHOP,
+ KEY_WINDOW_DROP,
+ KEY_WINDOW_KILLS,
+ KEY_WINDOW_SPELLS,
+ KEY_WINDOW_BOT_CHECKER,
+ KEY_WINDOW_ONLINE,
+ KEY_PREV_SOCIAL_TAB,
+ KEY_NEXT_SOCIAL_TAB,
+ KEY_EMOTE_1,
+ KEY_EMOTE_2,
+ KEY_EMOTE_3,
+ KEY_EMOTE_4,
+ KEY_EMOTE_5,
+ KEY_EMOTE_6,
+ KEY_EMOTE_7,
+ KEY_EMOTE_8,
+ KEY_EMOTE_9,
+ KEY_EMOTE_10,
+ KEY_EMOTE_11,
+ KEY_EMOTE_12,
+ KEY_EMOTE_13,
+ KEY_EMOTE_14,
+ KEY_EMOTE_15,
+ KEY_EMOTE_16,
+ KEY_EMOTE_17,
+ KEY_EMOTE_18,
+ KEY_EMOTE_19,
+ KEY_EMOTE_20,
+ KEY_EMOTE_21,
+ KEY_EMOTE_22,
+ KEY_EMOTE_23,
+ KEY_EMOTE_24,
+ KEY_EMOTE_25,
+ KEY_EMOTE_26,
+ KEY_EMOTE_27,
+ KEY_EMOTE_28,
+ KEY_EMOTE_29,
+ KEY_EMOTE_30,
+ KEY_EMOTE_31,
+ KEY_EMOTE_32,
+ KEY_EMOTE_33,
+ KEY_EMOTE_34,
+ KEY_EMOTE_35,
+ KEY_EMOTE_36,
+ KEY_EMOTE_37,
+ KEY_EMOTE_38,
+ KEY_EMOTE_39,
+ KEY_EMOTE_40,
+ KEY_EMOTE_41,
+ KEY_EMOTE_42,
+ KEY_WEAR_OUTFIT,
+ KEY_COPY_OUTFIT,
+ KEY_COPY_EQUIPED_OUTFIT,
+ KEY_TOGGLE_CHAT,
+ KEY_SCROLL_CHAT_UP,
+ KEY_SCROLL_CHAT_DOWN,
+ KEY_PREV_CHAT_TAB,
+ KEY_NEXT_CHAT_TAB,
+ KEY_CHAT_PREV_HISTORY,
+ KEY_CHAT_NEXT_HISTORY,
+ KEY_AUTOCOMPLETE_CHAT,
+ KEY_DEACTIVATE_CHAT,
+ KEY_OK,
+ KEY_QUIT,
+ KEY_IGNORE_INPUT_1,
+ KEY_IGNORE_INPUT_2,
+ KEY_DIRECT_UP,
+ KEY_DIRECT_DOWN,
+ KEY_DIRECT_LEFT,
+ KEY_DIRECT_RIGHT,
+ KEY_CRAZY_MOVES,
+ KEY_CHANGE_CRAZY_MOVES_TYPE,
+ KEY_QUICK_DROP,
+ KEY_QUICK_DROPN,
+ KEY_SWITCH_QUICK_DROP,
+ KEY_MAGIC_INMA1,
+ KEY_MAGIC_ITENPLZ,
+ KEY_MAGIC_ATTACK,
+ KEY_SWITCH_MAGIC_ATTACK,
+ KEY_INVERT_DIRECTION,
+ KEY_CHANGE_ATTACK_WEAPON_TYPE,
+ KEY_CHANGE_ATTACK_TYPE,
+ KEY_CHANGE_FOLLOW_MODE,
+ KEY_CHANGE_IMITATION_MODE,
+ KEY_DISABLE_GAME_MODIFIERS,
+ KEY_CHANGE_AUDIO,
+ KEY_AWAY,
+ KEY_RIGHT_CLICK,
+ KEY_CAMERA,
+ KEY_TOTAL
+ };
+
+ enum KeyGroup
+ {
+ GRP_DEFAULT = 1, // default game key
+ GRP_CHAT = 2, // chat key
+ GRP_EMOTION = 4, // emotions key
+ GRP_OUTFIT = 8 // outfit key
+ };
+
+ private:
+ int mNewKeyIndex; /**< Index of new key to be assigned */
+ bool mEnabled; /**< Flag to respond to key input */
+
+ Setup_Keyboard *mSetupKey; /**< Reference to setup window */
+
+ KeyFunction mKey[KEY_TOTAL]; /**< Pointer to all the key data */
+
+ Uint8 *mActiveKeys; /**< Stores a list of all the keys */
+
+ std::string mBindError;
+};
+
+extern KeyboardConfig keyboard;
+
+#endif
diff --git a/src/listener.cpp b/src/listener.cpp
new file mode 100644
index 000000000..f9acac95c
--- /dev/null
+++ b/src/listener.cpp
@@ -0,0 +1,43 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "listener.h"
+
+#include "event.h"
+
+namespace Mana
+{
+
+Listener::~Listener()
+{
+ Event::remove(this);
+}
+
+void Listener::listen(Channels channel)
+{
+ Event::bind(this, channel);
+}
+
+void Listener::ignore(Channels channel)
+{
+ Event::unbind(this, channel);
+}
+
+} // namespace Mana
diff --git a/src/listener.h b/src/listener.h
new file mode 100644
index 000000000..ff5a78f86
--- /dev/null
+++ b/src/listener.h
@@ -0,0 +1,45 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LISTENER_H
+#define LISTENER_H
+
+#include "event.h"
+
+#include <string>
+
+namespace Mana
+{
+
+class Listener
+{
+ public:
+ ~Listener();
+
+ void listen(Channels channel);
+
+ void ignore(Channels channel);
+
+ virtual void event(Channels channel, const Event &event) = 0;
+};
+
+} // namespace Mana
+
+#endif
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
new file mode 100644
index 000000000..edff2ce67
--- /dev/null
+++ b/src/localplayer.cpp
@@ -0,0 +1,3633 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "localplayer.h"
+
+#include "actorspritemanager.h"
+#include "client.h"
+#include "configuration.h"
+#include "effectmanager.h"
+#include "flooritem.h"
+#include "graphics.h"
+#include "guild.h"
+#include "item.h"
+#include "keyboardconfig.h"
+#include "log.h"
+#include "map.h"
+#include "party.h"
+#include "particle.h"
+#include "playerinfo.h"
+#include "simpleanimation.h"
+#include "sound.h"
+#include "statuseffect.h"
+#include "text.h"
+#include "dropshortcut.h"
+
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/inventorywindow.h"
+#include "gui/killstats.h"
+#include "gui/ministatus.h"
+#include "gui/okdialog.h"
+#include "gui/outfitwindow.h"
+#include "gui/palette.h"
+#include "gui/skilldialog.h"
+#include "gui/socialwindow.h"
+#include "gui/statuswindow.h"
+#include "gui/theme.h"
+#include "gui/userpalette.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "net/beinghandler.h"
+#include "net/chathandler.h"
+#include "net/guildhandler.h"
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+#include "net/partyhandler.h"
+#include "net/playerhandler.h"
+#include "net/specialhandler.h"
+#include "net/tradehandler.h"
+
+#include "resources/animation.h"
+#include "resources/imageset.h"
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <cassert>
+
+#include "mumblemanager.h"
+
+// This is the minimal delay between to permitted
+// setDestination() calls using the keyboard.
+// TODO: This can fine tuned later on when running is added...
+const short walkingKeyboardDelay = 1000;
+const short awayLimitTimer = 60;
+
+LocalPlayer *player_node = NULL;
+
+extern std::list<BeingCacheEntry*> beingInfoCache;
+
+LocalPlayer::LocalPlayer(int id, int subtype):
+ Being(id, PLAYER, subtype, 0),
+ mAttackRange(0),
+ mTargetTime(-1),
+ mLastTarget(-1),
+ mTarget(NULL),
+ mPlayerFollowed(""),
+ mPlayerImitated(""),
+ mPickUpTarget(NULL),
+ mGoingToTarget(false), mKeepAttacking(false),
+ mLastAction(-1),
+ mWalkingDir(0),
+ mPathSetByMouse(false),
+ mLocalWalkTime(-1),
+ mMessageTime(0),
+ mAwayDialog(0),
+ mAfkTime(0),
+ mAwayMode(false),
+ mShowNavigePath(false),
+ mDrawPath(false),
+ mActivityTime(0),
+ mNavigateX(0), mNavigateY(0),
+ mNavigateId(0),
+ mCrossX(0), mCrossY(0),
+ mOldX(0), mOldY(0),
+ mOldTileX(0), mOldTileY(0),
+ mLastHitFrom(""),
+ mWaitFor("")
+{
+ logger->log1("LocalPlayer::LocalPlayer");
+
+ listen(CHANNEL_ATTRIBUTES);
+ mLevel = 1;
+
+ mAwayListener = new AwayListener();
+
+ mUpdateName = true;
+
+ mTextColor = &Theme::getThemeColor(Theme::PLAYER);
+ mNameColor = &userPalette->getColor(UserPalette::SELF);
+
+ mLastTargetX = 0;
+ mLastTargetY = 0;
+
+ mInvertDirection = config.getIntValue("invertMoveDirection");
+ mCrazyMoveType = config.getIntValue("crazyMoveType");
+ mCrazyMoveState = 0;
+ mAttackWeaponType = config.getIntValue("attackWeaponType");
+ mQuickDropCounter = config.getIntValue("quickDropCounter");
+ mMoveState = 0;
+ mDisableCrazyMove = false;
+ mPickUpType = config.getIntValue("pickUpType");
+ mMagicAttackType = config.getIntValue("magicAttackType");
+ mMoveToTargetType = config.getIntValue("moveToTargetType");
+ mDisableGameModifiers = config.getBoolValue("disableGameModifiers");
+ mTargetDeadPlayers = config.getBoolValue("targetDeadPlayers");
+ mAttackType = config.getIntValue("attackType");
+ mFollowMode = config.getIntValue("followMode");
+ mImitationMode = config.getIntValue("imitationMode");
+ mIsServerBuggy = serverConfig.getValueBool("enableBuggyServers", true);
+ mSyncPlayerMove = config.getBoolValue("syncPlayerMove");
+ mDrawPath = config.getBoolValue("drawPath");
+ mServerAttack = config.getBoolValue("serverAttack");
+ mAttackMoving = config.getBoolValue("attackMoving");
+
+ mPingSendTick = 0;
+ mWaitPing = false;
+ mPingTime = 0;
+
+ PlayerInfo::setStatBase(WALK_SPEED, getWalkSpeed().x);
+ PlayerInfo::setStatMod(WALK_SPEED, 0);
+
+ loadHomes();
+// initTargetCursor();
+
+ config.addListener("showownname", this);
+ config.addListener("targetDeadPlayers", this);
+ serverConfig.addListener("enableBuggyServers", this);
+ config.addListener("syncPlayerMove", this);
+ config.addListener("drawPath", this);
+ config.addListener("serverAttack", this);
+ config.addListener("attackMoving", this);
+ setShowName(config.getBoolValue("showownname"));
+ beingInfoCache.clear();
+}
+
+LocalPlayer::~LocalPlayer()
+{
+ logger->log1("LocalPlayer::~LocalPlayer");
+
+ config.removeListener("showownname", this);
+ config.removeListener("targetDeadPlayers", this);
+ serverConfig.removeListener("enableBuggyServers", this);
+ config.removeListener("syncPlayerMove", this);
+ config.removeListener("drawPath", this);
+ config.removeListener("serverAttack", this);
+ config.removeListener("attackMoving", this);
+
+ delete mAwayDialog;
+ mAwayDialog = 0;
+ delete mAwayListener;
+ mAwayListener = 0;
+ beingInfoCache.clear();
+}
+
+void LocalPlayer::logic()
+{
+ if (mumbleManager)
+ mumbleManager->setPos(getTileX(), getTileY(), getDirection());
+
+ // Actions are allowed once per second
+ if (get_elapsed_time(mLastAction) >= 1000)
+ mLastAction = -1;
+
+ if (mActivityTime == 0 || mLastAction != -1)
+ mActivityTime = cur_time;
+
+ if (mAction != MOVE && !mNavigatePath.empty())
+ {
+ int dist = 5;
+ if (!mSyncPlayerMove)
+ dist = 20;
+
+ if ((mNavigateX || mNavigateY) &&
+ ((mCrossX + dist >= getTileX() && mCrossX <= getTileX() + dist
+ && mCrossY + dist >= getTileY() && mCrossY <= getTileY() + dist)
+ || (!mCrossX && !mCrossY)))
+ {
+ for (Path::const_iterator i = mNavigatePath.begin(),
+ i_end = mNavigatePath.end(); i != i_end; ++i)
+ {
+ if ((*i).x == getTileX() && (*i).y == getTileY())
+ {
+ mNavigatePath.pop_front();
+ break;
+ }
+ moveTo((*i).x, (*i).y);
+ break;
+ }
+ }
+ }
+
+ // Show XP messages
+ if (!mMessages.empty())
+ {
+ if (mMessageTime == 0)
+ {
+ //const Vector &pos = getPosition();
+
+ MessagePair info = mMessages.front();
+
+ if (particleEngine)
+ {
+ particleEngine->addTextRiseFadeOutEffect(
+ info.first,
+ /*(int) pos.x,
+ (int) pos.y - 48,*/
+ getPixelX(),
+ getPixelY() - 48,
+ &userPalette->getColor(info.second),
+ gui->getInfoParticleFont(), true);
+ }
+
+ mMessages.pop_front();
+ mMessageTime = 30;
+ }
+ mMessageTime--;
+ }
+
+ PlayerInfo::logic();
+
+ // Targeting allowed 4 times a second
+ if (get_elapsed_time(mLastTarget) >= 250)
+ mLastTarget = -1;
+
+// // Remove target if its been on a being for more than a minute
+ if (get_elapsed_time(mTargetTime) >= 60000)
+ {
+ mTargetTime = tick_time;
+// setTarget(NULL);
+ mLastTarget = -1;
+ }
+
+ if (mTarget)
+ {
+ if (mTarget->getType() == ActorSprite::NPC)
+ {
+ // NPCs are always in range
+ mTarget->setTargetType(TCT_IN_RANGE);
+ }
+ else
+ {
+ // Find whether target is in range
+ // TODO: Make this nicer, probably using getPosition() only
+ const int rangeX =
+ (Net::getNetworkType() == ServerInfo::MANASERV) ?
+ static_cast<int>(abs(mTarget->getPosition().x
+ - getPosition().x)) :
+ static_cast<int>(abs(mTarget->getTileX() - getTileX()));
+ const int rangeY =
+ (Net::getNetworkType() == ServerInfo::MANASERV) ?
+ static_cast<int>(abs(mTarget->getPosition().y
+ - getPosition().y)) :
+ static_cast<int>(abs(mTarget->getTileY() - getTileY()));
+
+ const int attackRange = getAttackRange();
+ const TargetCursorType targetType = rangeX > attackRange ||
+ rangeY > attackRange ?
+ TCT_NORMAL : TCT_IN_RANGE;
+ mTarget->setTargetType(targetType);
+
+ if (!mTarget->isAlive() && (!mTargetDeadPlayers
+ || mTarget->getType() != Being::PLAYER))
+ {
+ stopAttack();
+ }
+
+ if (mKeepAttacking && mTarget)
+ attack(mTarget, true);
+ }
+ }
+
+ Being::logic();
+}
+
+void LocalPlayer::setAction(Action action, int attackType)
+{
+ if (action == DEAD)
+ {
+ mLastTarget = -1;
+ if (!mLastHitFrom.empty())
+ {
+ debugMsg(_("You were killed by ") + mLastHitFrom);
+ mLastHitFrom = "";
+ }
+ setTarget(NULL);
+ }
+
+ Being::setAction(action, attackType);
+ if (mumbleManager)
+ mumbleManager->setAction(static_cast<int>(action));
+}
+
+void LocalPlayer::setGMLevel(int level)
+{
+ mGMLevel = level;
+
+ if (level > 0)
+ setGM(true);
+}
+
+
+Position LocalPlayer::getNextWalkPosition(unsigned char dir)
+{
+ // check for mMap?
+
+ // Compute where the next tile will be set.
+ int dx = 0, dy = 0;
+ if (dir & Being::UP)
+ dy--;
+ if (dir & Being::DOWN)
+ dy++;
+ if (dir & Being::LEFT)
+ dx--;
+ if (dir & Being::RIGHT)
+ dx++;
+
+ Vector pos = getPosition();
+
+ // If no map or no direction is given, give back the current player position
+ if (!mMap || (!dx && !dy))
+ return Position(static_cast<int>(pos.x), static_cast<int>(pos.y));
+
+ // Get the current tile pos and its offset
+ int tileX = static_cast<int>(pos.x) / mMap->getTileWidth();
+ int tileY = static_cast<int>(pos.y) / mMap->getTileHeight();
+ int offsetX = static_cast<int>(pos.x) % mMap->getTileWidth();
+ int offsetY = static_cast<int>(pos.y) % mMap->getTileHeight();
+
+ // Get the walkability of every surrounding tiles.
+ bool wTopLeft = mMap->getWalk(tileX - 1, tileY - 1, getWalkMask());
+ bool wTop = mMap->getWalk(tileX, tileY - 1, getWalkMask());
+ bool wTopRight = mMap->getWalk(tileX + 1, tileY - 1, getWalkMask());
+ bool wLeft = mMap->getWalk(tileX - 1, tileY, getWalkMask());
+ bool wRight = mMap->getWalk(tileX + 1, tileY, getWalkMask());
+ bool wBottomLeft = mMap->getWalk(tileX - 1, tileY + 1, getWalkMask());
+ bool wBottom = mMap->getWalk(tileX, tileY + 1, getWalkMask());
+ bool wBottomRight = mMap->getWalk(tileX + 1, tileY + 1, getWalkMask());
+
+ // Make diagonals unwalkable when both straight directions are blocking
+ if (!wTop)
+ {
+ if (!wRight)
+ wTopRight = false;
+ if (!wLeft)
+ wTopLeft = false;
+ }
+ if (!wBottom)
+ {
+ if (!wRight)
+ wBottomRight = false;
+ if (!wLeft)
+ wBottomLeft = false;
+ }
+
+ // We'll make tests for each desired direction
+
+ // Handle diagonal cases by setting the way back to a straight direction
+ // when necessary.
+ if (dx && dy)
+ {
+ // Going top-right
+ if (dx > 0 && dy < 0)
+ {
+ if (!wTopRight)
+ {
+ // Choose a straight direction when diagonal target is blocked
+ if (!wTop && wRight)
+ {
+ dy = 0;
+ }
+ else if (wTop && !wRight)
+ {
+ dx = 0;
+ }
+ else if (!wTop && !wRight)
+ {
+ return Position(tileX * 32 + 32 - getCollisionRadius(),
+ tileY * 32 + getCollisionRadius());
+ }
+ else // Both straight direction are walkable
+ {
+ // Go right when below the corner
+ if (offsetY >= (offsetX / mMap->getTileHeight()
+ - (offsetX / mMap->getTileWidth()
+ * mMap->getTileHeight()) ))
+ {
+ dy = 0;
+ }
+ else // Go up otherwise
+ {
+ dx = 0;
+ }
+ }
+ }
+ else // The diagonal is walkable
+ {
+ return mMap->checkNodeOffsets(getCollisionRadius(),
+ getWalkMask(), Position(static_cast<int>(pos.x) + 32,
+ static_cast<int>(pos.y) - 32));
+ }
+ }
+
+ // Going top-left
+ if (dx < 0 && dy < 0)
+ {
+ if (!wTopLeft)
+ {
+ // Choose a straight direction when diagonal target is blocked
+ if (!wTop && wLeft)
+ {
+ dy = 0;
+ }
+ else if (wTop && !wLeft)
+ {
+ dx = 0;
+ }
+ else if (!wTop && !wLeft)
+ {
+ return Position(tileX * 32 + getCollisionRadius(),
+ tileY * 32 + getCollisionRadius());
+ }
+ else // Both straight direction are walkable
+ {
+ // Go left when below the corner
+ if (offsetY >= (offsetX / mMap->getTileWidth()
+ * mMap->getTileHeight()))
+ {
+ dy = 0;
+ }
+ else // Go up otherwise
+ {
+ dx = 0;
+ }
+ }
+ }
+ else // The diagonal is walkable
+ {
+ return mMap->checkNodeOffsets(getCollisionRadius(),
+ getWalkMask(), Position(static_cast<int>(pos.x) - 32,
+ static_cast<int>(pos.y) - 32));
+ }
+ }
+
+ // Going bottom-left
+ if (dx < 0 && dy > 0)
+ {
+ if (!wBottomLeft)
+ {
+ // Choose a straight direction when diagonal target is blocked
+ if (!wBottom && wLeft)
+ {
+ dy = 0;
+ }
+ else if (wBottom && !wLeft)
+ {
+ dx = 0;
+ }
+ else if (!wBottom && !wLeft)
+ {
+ return Position(tileX * 32 + getCollisionRadius(),
+ tileY * 32 + 32 - getCollisionRadius());
+ }
+ else // Both straight direction are walkable
+ {
+ // Go down when below the corner
+ if (offsetY >= (offsetX / mMap->getTileHeight()
+ - (offsetX / mMap->getTileWidth()
+ * mMap->getTileHeight())))
+ {
+ dx = 0;
+ }
+ else // Go left otherwise
+ {
+ dy = 0;
+ }
+ }
+ }
+ else // The diagonal is walkable
+ {
+ return mMap->checkNodeOffsets(getCollisionRadius(),
+ getWalkMask(), Position(static_cast<int>(pos.x) - 32,
+ static_cast<int>(pos.y) + 32));
+ }
+ }
+
+ // Going bottom-right
+ if (dx > 0 && dy > 0)
+ {
+ if (!wBottomRight)
+ {
+ // Choose a straight direction when diagonal target is blocked
+ if (!wBottom && wRight)
+ {
+ dy = 0;
+ }
+ else if (wBottom && !wRight)
+ {
+ dx = 0;
+ }
+ else if (!wBottom && !wRight)
+ {
+ return Position(tileX * 32 + 32 - getCollisionRadius(),
+ tileY * 32 + 32 - getCollisionRadius());
+ }
+ else // Both straight direction are walkable
+ {
+ // Go down when below the corner
+ if (offsetY >= (offsetX / mMap->getTileWidth()
+ * mMap->getTileHeight()))
+ {
+ dx = 0;
+ }
+ else // Go right otherwise
+ {
+ dy = 0;
+ }
+ }
+ }
+ else // The diagonal is walkable
+ {
+ return mMap->checkNodeOffsets(getCollisionRadius(),
+ getWalkMask(), Position(static_cast<int>(pos.x) + 32,
+ static_cast<int>(pos.y) + 32));
+ }
+ }
+
+ } // End of diagonal cases
+
+ // Straight directions
+ // Right direction
+ if (dx > 0 && !dy)
+ {
+ // If the straight destination is blocked,
+ // Make the player go the closest possible.
+ if (!wRight)
+ {
+ return Position(tileX * 32 + 32 - getCollisionRadius(),
+ static_cast<int>(pos.y));
+ }
+ else
+ {
+ if (!wTopRight)
+ {
+ // If we're going to collide with the top-right corner
+ if (offsetY - getCollisionRadius() < 0)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + 32 - getCollisionRadius(),
+ tileY * 32 + getCollisionRadius());
+
+ }
+ }
+
+ if (!wBottomRight)
+ {
+ // If we're going to collide with the bottom-right corner
+ if (offsetY + getCollisionRadius() > 32)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + 32 - getCollisionRadius(),
+ tileY * 32 + 32 - getCollisionRadius());
+
+ }
+ }
+ // If the way is clear, step up one checked tile ahead.
+ return mMap->checkNodeOffsets(getCollisionRadius(), getWalkMask(),
+ Position(static_cast<int>(pos.x) + 32,
+ static_cast<int>(pos.y)));
+ }
+ }
+
+ // Left direction
+ if (dx < 0 && !dy)
+ {
+ // If the straight destination is blocked,
+ // Make the player go the closest possible.
+ if (!wLeft)
+ {
+ return Position(tileX * 32 + getCollisionRadius(),
+ static_cast<int>(pos.y));
+ }
+ else
+ {
+ if (!wTopLeft)
+ {
+ // If we're going to collide with the top-left corner
+ if (offsetY - getCollisionRadius() < 0)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + getCollisionRadius(),
+ tileY * 32 + getCollisionRadius());
+
+ }
+ }
+
+ if (!wBottomLeft)
+ {
+ // If we're going to collide with the bottom-left corner
+ if (offsetY + getCollisionRadius() > 32)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + getCollisionRadius(),
+ tileY * 32 + 32 - getCollisionRadius());
+
+ }
+ }
+ // If the way is clear, step up one checked tile ahead.
+ return mMap->checkNodeOffsets(getCollisionRadius(), getWalkMask(),
+ Position(static_cast<int>(pos.x) - 32,
+ static_cast<int>(pos.y)));
+ }
+ }
+
+ // Up direction
+ if (!dx && dy < 0)
+ {
+ // If the straight destination is blocked,
+ // Make the player go the closest possible.
+ if (!wTop)
+ {
+ return Position(static_cast<int>(pos.x),
+ tileY * 32 + getCollisionRadius());
+ }
+ else
+ {
+ if (!wTopLeft)
+ {
+ // If we're going to collide with the top-left corner
+ if (offsetX - getCollisionRadius() < 0)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + getCollisionRadius(),
+ tileY * 32 + getCollisionRadius());
+
+ }
+ }
+
+ if (!wTopRight)
+ {
+ // If we're going to collide with the top-right corner
+ if (offsetX + getCollisionRadius() > 32)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + 32 - getCollisionRadius(),
+ tileY * 32 + getCollisionRadius());
+
+ }
+ }
+ // If the way is clear, step up one checked tile ahead.
+ return mMap->checkNodeOffsets(getCollisionRadius(), getWalkMask(),
+ Position(static_cast<int>(pos.x),
+ static_cast<int>(pos.y) - 32));
+ }
+ }
+
+ // Down direction
+ if (!dx && dy > 0)
+ {
+ // If the straight destination is blocked,
+ // Make the player go the closest possible.
+ if (!wBottom)
+ {
+ return Position(static_cast<int>(pos.x),
+ tileY * 32 + 32 - getCollisionRadius());
+ }
+ else
+ {
+ if (!wBottomLeft)
+ {
+ // If we're going to collide with the bottom-left corner
+ if (offsetX - getCollisionRadius() < 0)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + getCollisionRadius(),
+ tileY * 32 + 32 - getCollisionRadius());
+
+ }
+ }
+
+ if (!wBottomRight)
+ {
+ // If we're going to collide with the bottom-right corner
+ if (offsetX + getCollisionRadius() > 32)
+ {
+ // We make the player corrects its offset
+ // before going further
+ return Position(tileX * 32 + 32 - getCollisionRadius(),
+ tileY * 32 + 32 - getCollisionRadius());
+
+ }
+ }
+ // If the way is clear, step up one checked tile ahead.
+ return mMap->checkNodeOffsets(getCollisionRadius(), getWalkMask(),
+ Position(static_cast<int>(pos.x),
+ static_cast<int>(pos.y) + 32));
+ }
+ }
+
+ // Return the current position if everything else has failed.
+ return Position(static_cast<int>(pos.x), static_cast<int>(pos.y));
+}
+
+void LocalPlayer::nextTile(unsigned char dir = 0)
+{
+ if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+// updatePos();
+
+ if (Party::getParty(1))
+ {
+ PartyMember *pm = Party::getParty(1)->getMember(getName());
+ if (pm)
+ {
+ pm->setX(getTileX());
+ pm->setY(getTileY());
+ }
+ }
+
+ // TODO: Fix picking up when reaching target (this method is obsolete)
+ // TODO: Fix holding walking button to keep walking smoothly
+ if (mPath.empty())
+ {
+ if (mPickUpTarget)
+ pickUp(mPickUpTarget);
+
+ if (mWalkingDir)
+ startWalking(mWalkingDir);
+ }
+
+ // TODO: Fix automatically walking within range of target, when wanted
+ if (mGoingToTarget && mTarget && withinAttackRange(mTarget))
+ {
+ mAction = Being::STAND;
+ attack(mTarget, true);
+ mGoingToTarget = false;
+ mPath.clear();
+ return;
+ }
+ else if (mGoingToTarget && !mTarget)
+ {
+ mGoingToTarget = false;
+ mPath.clear();
+ }
+
+
+ Being::nextTile();
+ }
+ else
+ {
+ if (!mMap || !dir)
+ return;
+
+ const Vector &pos = getPosition();
+ Position destination = getNextWalkPosition(dir);
+
+ if (static_cast<int>(pos.x) != destination.x
+ || static_cast<int>(pos.y) != destination.y)
+ {
+ setDestination(destination.x, destination.y);
+ }
+ else if (dir != mDirection)
+ {
+ // If the being can't move, just change direction
+
+ if (!Client::limitPackets(PACKET_DIRECTION))
+ return;
+
+ Net::getPlayerHandler()->setDirection(dir);
+ setDirection(dir);
+ }
+ }
+}
+
+bool LocalPlayer::checkInviteRights(const std::string &guildName)
+{
+ Guild *guild = getGuild(guildName);
+ if (guild)
+ return guild->getInviteRights();
+
+ return false;
+}
+
+void LocalPlayer::inviteToGuild(Being *being)
+{
+ if (!being || being->getType() != PLAYER)
+ return;
+
+ // TODO: Allow user to choose which guild to invite being to
+ // For now, just invite to the first guild you have permissions to invite with
+ std::map<int, Guild*>::iterator itr = mGuilds.begin();
+ std::map<int, Guild*>::iterator itr_end = mGuilds.end();
+ for (; itr != itr_end; ++itr)
+ {
+ if (checkInviteRights(itr->second->getName()))
+ {
+ Net::getGuildHandler()->invite(itr->second->getId(), being);
+ return;
+ }
+ }
+}
+
+bool LocalPlayer::pickUp(FloorItem *item)
+{
+ if (!item)
+ return false;
+
+ if (!Client::limitPackets(PACKET_PICKUP))
+ return false;
+
+ int dx = item->getTileX() - getTileX();
+ int dy = item->getTileY() - getTileY();
+ int dist = 6;
+
+ if (mPickUpType >= 4 && mPickUpType <= 6)
+ dist = 4;
+
+ if (dx * dx + dy * dy < dist)
+ {
+ Net::getPlayerHandler()->pickUp(item);
+ mPickUpTarget = NULL;
+ }
+ else if (mPickUpType >= 4 && mPickUpType <= 6)
+ {
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ setDestination(item->getPixelX() + 16, item->getPixelY() + 16);
+ mPickUpTarget = item;
+ mPickUpTarget->addActorSpriteListener(this);
+ }
+ else
+ {
+ const Vector &playerPos = getPosition();
+ Path debugPath = mMap->findPath(
+ static_cast<int>(playerPos.x - 16) / 32,
+ static_cast<int>(playerPos.y - 32) / 32,
+ item->getTileX(), item->getTileY(), 0x00, 0);
+ if (!debugPath.empty())
+ navigateTo(item->getTileX(), item->getTileY());
+ else
+ setDestination(item->getTileX(), item->getTileY());
+
+ mPickUpTarget = item;
+ mPickUpTarget->addActorSpriteListener(this);
+// stopAttack();
+ }
+ }
+ return true;
+}
+
+void LocalPlayer::actorSpriteDestroyed(const ActorSprite &actorSprite)
+{
+ if (mPickUpTarget == &actorSprite)
+ mPickUpTarget = 0;
+}
+
+Being *LocalPlayer::getTarget() const
+{
+ return mTarget;
+}
+
+void LocalPlayer::setTarget(Being *target)
+{
+ if ((mLastTarget != -1 || target == this) && target)
+ return;
+
+ if (target)
+ mLastTarget = tick_time;
+
+ if (target == mTarget)
+ return;
+
+ if (target || mAction == ATTACK)
+ {
+ mTargetTime = tick_time;
+ }
+ else
+ {
+ mKeepAttacking = false;
+ mTargetTime = -1;
+ }
+
+ Being *oldTarget = 0;
+ if (mTarget)
+ {
+ mTarget->untarget();
+ oldTarget = mTarget;
+ }
+
+ if (mTarget && mTarget->getType() == ActorSprite::MONSTER)
+ mTarget->setShowName(false);
+
+ mTarget = target;
+
+ if (oldTarget)
+ oldTarget->updateName();
+
+ if (mTarget)
+ {
+ mLastTargetX = mTarget->getTileX();
+ mLastTargetY = mTarget->getTileY();
+ mTarget->updateName();
+ }
+
+ if (target && target->getType() == ActorSprite::MONSTER)
+ target->setShowName(true);
+}
+
+void LocalPlayer::setDestination(int x, int y)
+{
+ mActivityTime = cur_time;
+
+ mPickUpTarget = NULL;
+ if (getAttackType() == 0 || !mAttackMoving)
+ mKeepAttacking = false;
+
+ // Only send a new message to the server when destination changes
+ if (x != mDest.x || y != mDest.y)
+ {
+ if (mInvertDirection != 1)
+ {
+ Net::getPlayerHandler()->setDestination(x, y, mDirection);
+ Being::setDestination(x, y);
+ }
+ else if (mInvertDirection == 1)
+ {
+ Uint8 newDir = 0;
+ if (mDirection&UP)
+ newDir |= DOWN;
+ if (mDirection&LEFT)
+ newDir |= RIGHT;
+ if (mDirection&DOWN)
+ newDir |= UP;
+ if (mDirection&RIGHT)
+ newDir |= LEFT;
+
+ Net::getPlayerHandler()->setDestination(x, y, newDir);
+
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ setDirection(newDir);
+ Net::getPlayerHandler()->setDirection(newDir);
+ }
+
+ Being::setDestination(x, y);
+ }
+
+ // Manaserv:
+ // If the destination given to being class is accepted,
+ // we inform the Server.
+ if ((x == mDest.x && y == mDest.y)
+ || Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+ Net::getPlayerHandler()->setDestination(x, y, mDirection);
+ }
+
+ return;
+ }
+}
+
+void LocalPlayer::setWalkingDir(unsigned char dir)
+{
+ // This function is called by Game::handleInput()
+
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ // First if player is pressing key for the direction he is already
+ // going, do nothing more...
+
+ // Else if he is pressing a key, and its different from what he has
+ // been pressing, stop (do not send this stop to the server) and
+ // start in the new direction
+ if (dir && (dir != getWalkingDir()))
+ stopWalking(false);
+
+ // Else, he is not pressing a key,
+ // and the current path hasn't been sent by mouse,
+ // then, stop (sending to server).
+ else if (!dir)
+ {
+ if (!mPathSetByMouse)
+ stopWalking(true);
+ return;
+ }
+
+ // If the delay to send another walk message to the server hasn't expired,
+ // don't do anything or we could get disconnected for spamming the server
+ if (get_elapsed_time(mLocalWalkTime) < walkingKeyboardDelay)
+ return;
+ }
+
+ mWalkingDir = dir;
+
+ // If we're not already walking, start walking.
+ if (mAction != MOVE && dir)
+ {
+ startWalking(dir);
+ }
+ else if (mAction == MOVE
+ && (Net::getNetworkType() == ServerInfo::MANASERV))
+ {
+ nextTile(dir);
+ }
+}
+
+void LocalPlayer::startWalking(unsigned char dir)
+{
+ // This function is called by setWalkingDir(),
+ // but also by nextTile() for TMW-Athena...
+ if (!mMap || !dir)
+ return;
+
+ if (mAction == MOVE && !mPath.empty())
+ {
+ // Just finish the current action, otherwise we get out of sync
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ const Vector &pos = getPosition();
+ Being::setDestination(static_cast<int>(pos.x),
+ static_cast<int>(pos.y));
+ }
+ else
+ {
+ Being::setDestination(getTileX(), getTileY());
+ }
+ return;
+ }
+
+ int dx = 0, dy = 0;
+ if (dir & UP)
+ dy--;
+ if (dir & DOWN)
+ dy++;
+ if (dir & LEFT)
+ dx--;
+ if (dir & RIGHT)
+ dx++;
+
+ if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ {
+ // Prevent skipping corners over colliding tiles
+ if (dx && !mMap->getWalk(getTileX() + dx, getTileY(), getWalkMask()))
+ dx = 0;
+ if (dy && !mMap->getWalk(getTileX(), getTileY() + dy, getWalkMask()))
+ dy = 0;
+
+ // Choose a straight direction when diagonal target is blocked
+ if (dx && dy && !mMap->getWalk(getTileX() + dx, getTileY() + dy,
+ getWalkMask()))
+ {
+ dx = 0;
+ }
+
+ // Walk to where the player can actually go
+ if ((dx || dy) && mMap->getWalk(getTileX() + dx, getTileY() + dy,
+ getWalkMask()))
+ {
+ setDestination(getTileX() + dx, getTileY() + dy);
+ }
+ else if (dir != mDirection)
+ {
+ // If the being can't move, just change direction
+
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ Net::getPlayerHandler()->setDirection(dir);
+ setDirection(dir);
+ }
+ }
+ }
+ else
+ {
+ nextTile(dir);
+ }
+}
+
+void LocalPlayer::stopWalking(bool sendToServer)
+{
+ if (mAction == MOVE && mWalkingDir)
+ {
+ mWalkingDir = 0;
+ mLocalWalkTime = 0;
+
+ setDestination(static_cast<int>(getPosition().x),
+ static_cast<int>(getPosition().y));
+ if (sendToServer)
+ {
+ Net::getPlayerHandler()->setDestination(
+ static_cast<int>(getPosition().x),
+ static_cast<int>(getPosition().y));
+ }
+ setAction(STAND);
+ }
+
+ // No path set anymore, so we reset the path by mouse flag
+ mPathSetByMouse = false;
+
+ clearPath();
+}
+
+bool LocalPlayer::toggleSit()
+{
+ if (!Client::limitPackets(PACKET_SIT))
+ return false;
+
+ Being::Action newAction;
+ switch (mAction)
+ {
+ case STAND: newAction = SIT; break;
+ case SIT: newAction = STAND; break;
+ default: return true;
+ }
+
+ Net::getPlayerHandler()->changeAction(newAction);
+ return true;
+}
+
+bool LocalPlayer::updateSit()
+{
+ if (!Client::limitPackets(PACKET_SIT))
+ return false;
+
+ Net::getPlayerHandler()->changeAction(mAction);
+ return true;
+}
+
+bool LocalPlayer::emote(Uint8 emotion)
+{
+ if (!Client::limitPackets(PACKET_EMOTE))
+ return false;
+
+ Net::getPlayerHandler()->emote(emotion);
+ return true;
+}
+
+void LocalPlayer::attack(Being *target, bool keep, bool dontChangeEquipment)
+{
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ if (mLastAction != -1)
+ return;
+
+ // Can only attack when standing still
+ if (mAction != STAND && mAction != ATTACK)
+ return;
+ }
+
+ mKeepAttacking = keep;
+
+ if (!target || target->getType() == ActorSprite::NPC)
+ return;
+
+ if (mTarget != target || !mTarget)
+ {
+ mLastTarget = -1;
+ setTarget(target);
+ }
+
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ Vector plaPos = this->getPosition();
+ Vector tarPos = mTarget->getPosition();
+ int dist_x = static_cast<int>(plaPos.x - tarPos.x);
+ int dist_y = static_cast<int>(plaPos.y - tarPos.y);
+
+ if (abs(dist_y) >= abs(dist_x))
+ {
+ if (dist_y < 0)
+ setDirection(DOWN);
+ else
+ setDirection(UP);
+ }
+ else
+ {
+ if (dist_x < 0)
+ setDirection(RIGHT);
+ else
+ setDirection(LEFT);
+ }
+
+ mLastAction = tick_time;
+ }
+ else
+ {
+ int dist_x = target->getTileX() - getTileX();
+ int dist_y = target->getTileY() - getTileY();
+
+ // Must be standing or sitting to attack
+ if (mAction != STAND && mAction != SIT)
+ return;
+
+ if (abs(dist_y) >= abs(dist_x))
+ {
+ if (dist_y > 0)
+ setDirection(DOWN);
+ else
+ setDirection(UP);
+ }
+ else
+ {
+ if (dist_x > 0)
+ setDirection(RIGHT);
+ else
+ setDirection(LEFT);
+ }
+
+ mActionTime = tick_time;
+ mTargetTime = tick_time;
+ }
+
+ setAction(ATTACK);
+
+ if (mEquippedWeapon)
+ {
+ std::string soundFile = mEquippedWeapon->getSound(EQUIP_EVENT_STRIKE);
+ if (!soundFile.empty())
+ sound.playSfx(soundFile);
+ }
+ else
+ {
+ sound.playSfx(paths.getValue("attackSfxFile", "fist-swish.ogg"));
+ }
+
+ if (!Client::limitPackets(PACKET_ATTACK))
+ return;
+
+ if (!dontChangeEquipment && target)
+ changeEquipmentBeforeAttack(target);
+
+ Net::getPlayerHandler()->attack(target->getId(), mServerAttack);
+ if ((Net::getNetworkType() == ServerInfo::TMWATHENA) && !keep)
+ stopAttack();
+}
+
+void LocalPlayer::stopAttack()
+{
+ if (mServerAttack && mAction == ATTACK)
+ Net::getPlayerHandler()->stopAttack();
+
+ if (mAction == ATTACK)
+ setAction(STAND);
+
+ if (mTarget)
+ setTarget(NULL);
+
+ mKeepAttacking = false;
+ mLastTarget = -1;
+}
+
+void LocalPlayer::pickedUp(const ItemInfo &itemInfo, int amount)
+{
+ if (!amount)
+ {
+ if (config.getBoolValue("showpickupchat"))
+ {
+ localChatTab->chatLog(_("Unable to pick up item."),
+ BY_SERVER);
+ }
+ }
+ else
+ {
+ if (config.getBoolValue("showpickupchat") && localChatTab)
+ {
+ // TRANSLATORS: This sentence may be translated differently
+ // for different grammatical numbers (singular, plural, ...)
+ localChatTab->chatLog(strprintf(ngettext("You picked up %d "
+ "[@@%d|%s@@].", "You picked up %d [@@%d|%s@@].", amount),
+ amount, itemInfo.getId(), itemInfo.getName().c_str()),
+ BY_SERVER);
+ }
+
+ if (mMap && config.getBoolValue("showpickupparticle"))
+ {
+ // Show pickup notification
+ addMessageToQueue(itemInfo.getName(), UserPalette::PICKUP_INFO);
+ }
+ }
+}
+
+int LocalPlayer::getAttackRange()
+{
+ if (mAttackRange > -1)
+ {
+ return mAttackRange;
+ }
+ else
+ {
+ // TODO: Fix this to be more generic
+ Item *weapon = PlayerInfo::getEquipment(EQUIP_FIGHT1_SLOT);
+ if (weapon)
+ {
+ const ItemInfo info = weapon->getInfo();
+ return info.getAttackRange();
+ }
+ return 48; // unarmed range
+ }
+}
+
+bool LocalPlayer::withinAttackRange(Being *target, bool fixDistance,
+ int addRange)
+{
+ if (!target)
+ return false;
+
+ int range = getAttackRange() + addRange;
+ int dx;
+ int dy;
+
+ if (fixDistance && range == 1)
+ range = 2;
+
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ const Vector &targetPos = target->getPosition();
+ const Vector &pos = getPosition();
+ dx = static_cast<int>(abs(targetPos.x - pos.x));
+ dy = static_cast<int>(abs(targetPos.y - pos.y));
+
+ }
+ else
+ {
+ dx = static_cast<int>(abs(target->getTileX() - getTileX()));
+ dy = static_cast<int>(abs(target->getTileY() - getTileY()));
+ }
+ return !(dx > range || dy > range);
+}
+
+void LocalPlayer::setGotoTarget(Being *target)
+{
+ mLastTarget = -1;
+
+ if (!target)
+ return;
+
+ if (Net::getNetworkType() == ServerInfo::MANASERV)
+ {
+ mTarget = target;
+ mGoingToTarget = true;
+ const Vector &targetPos = target->getPosition();
+ setDestination(targetPos.x, targetPos.y);
+ }
+ else
+ {
+ setTarget(target);
+ mGoingToTarget = true;
+ setDestination(target->getTileX(), target->getTileY());
+ }
+}
+
+extern MiniStatusWindow *miniStatusWindow;
+extern SkillDialog *skillDialog;
+
+void LocalPlayer::handleStatusEffect(StatusEffect *effect, int effectId)
+{
+ Being::handleStatusEffect(effect, effectId);
+
+ if (effect)
+ {
+ effect->deliverMessage();
+ effect->playSFX();
+
+ AnimatedSprite *sprite = effect->getIcon();
+
+ if (!sprite)
+ {
+ // delete sprite, if necessary
+ for (unsigned int i = 0; i < mStatusEffectIcons.size(); )
+ {
+ if (mStatusEffectIcons[i] == effectId)
+ {
+ mStatusEffectIcons.erase(mStatusEffectIcons.begin() + i);
+ if (miniStatusWindow)
+ miniStatusWindow->eraseIcon(i);
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+ else
+ {
+ // replace sprite or append
+ bool found = false;
+
+ for (unsigned int i = 0; i < mStatusEffectIcons.size(); i++)
+ {
+ if (mStatusEffectIcons[i] == effectId)
+ {
+ if (miniStatusWindow)
+ miniStatusWindow->setIcon(i, sprite);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ { // add new
+ int offset = static_cast<int>(mStatusEffectIcons.size());
+ if (miniStatusWindow)
+ miniStatusWindow->setIcon(offset, sprite);
+ mStatusEffectIcons.push_back(effectId);
+ }
+ }
+ }
+}
+
+void LocalPlayer::addMessageToQueue(const std::string &message, int color)
+{
+ if (mMessages.size() < 20)
+ mMessages.push_back(MessagePair(message, color));
+}
+
+void LocalPlayer::optionChanged(const std::string &value)
+{
+ if (value == "showownname")
+ setShowName(config.getBoolValue("showownname"));
+ else if (value == "targetDeadPlayers")
+ mTargetDeadPlayers = config.getBoolValue("targetDeadPlayers");
+ else if (value == "enableBuggyServers")
+ mIsServerBuggy = serverConfig.getBoolValue("enableBuggyServers");
+ else if (value == "syncPlayerMove")
+ mSyncPlayerMove = config.getBoolValue("syncPlayerMove");
+ else if (value == "drawPath")
+ mDrawPath = config.getBoolValue("drawPath");
+ else if (value == "serverAttack")
+ mServerAttack = config.getBoolValue("serverAttack");
+ else if (value == "attackMoving")
+ mAttackMoving = config.getBoolValue("attackMoving");
+}
+
+void LocalPlayer::event(Channels channel, const Mana::Event &event)
+{
+ if (channel == CHANNEL_ATTRIBUTES)
+ {
+ if (event.getName() == EVENT_UPDATEATTRIBUTE)
+ {
+ switch (event.getInt("id"))
+ {
+ case EXP:
+ {
+ if (event.getInt("oldValue") > event.getInt("newValue"))
+ break;
+
+ int change = event.getInt("newValue")
+ - event.getInt("oldValue");
+
+ if (change != 0)
+ addMessageToQueue(toString(change) + " xp");
+ break;
+ }
+ case LEVEL:
+ mLevel = event.getInt("newValue");
+ break;
+ default:
+ break;
+ };
+ }
+ }
+}
+
+void LocalPlayer::moveTo(int x, int y)
+{
+ setDestination(x, y);
+}
+
+void LocalPlayer::move(int dX, int dY)
+{
+ moveTo(getTileX() + dX, getTileY() + dY);
+}
+
+void LocalPlayer::moveToTarget(unsigned int dist)
+{
+ bool gotPos(false);
+ Path debugPath;
+
+ Vector targetPos(-1, -1);
+ const Vector &playerPos = getPosition();
+ unsigned int limit(0);
+
+ if (static_cast<int>(dist) == -1)
+ {
+ dist = mMoveToTargetType;
+ if (mMoveToTargetType == 0)
+ {
+ dist = 0;
+ }
+ else
+ {
+ switch (mMoveToTargetType)
+ {
+ case 1:
+ dist = 1;
+ break;
+ case 2:
+ dist = 2;
+ break;
+ case 3:
+ dist = 3;
+ break;
+ case 4:
+ dist = 5;
+ break;
+ case 5:
+ dist = 7;
+ break;
+ case 6:
+ dist = mAttackRange;
+ if (dist == 1)
+ dist = 2;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (mTarget)
+ {
+ debugPath = mMap->findPath(static_cast<int>(playerPos.x - 16) / 32,
+ static_cast<int>(playerPos.y - 32) / 32,
+ mTarget->getTileX(), mTarget->getTileY(), 0x00, 0);
+
+ if (debugPath.size() < dist)
+ return;
+ limit = static_cast<int>(debugPath.size()) - dist;
+ gotPos = true;
+ }
+ else if (mNavigateX || mNavigateY)
+ {
+ debugPath = mNavigatePath;
+ limit = dist;
+ gotPos = true;
+ }
+
+ if (gotPos)
+ {
+ if (dist == 0)
+ {
+ if (mTarget)
+ navigateTo(mTarget);
+ }
+ else
+ {
+ Position pos(0, 0);
+ unsigned int f = 0;
+
+ for (Path::const_iterator i = debugPath.begin(),
+ i_end = debugPath.end();
+ i != i_end && f < limit; ++i, f++)
+ {
+ pos = (*i);
+ }
+ navigateTo(pos.x, pos.y);
+ }
+ }
+ else if (mLastTargetX || mLastTargetY)
+ {
+ navigateTo(mLastTargetX, mLastTargetY);
+ }
+}
+
+void LocalPlayer::moveToHome()
+{
+ if ((getTileX() != mCrossX || getTileY() != mCrossY) && mCrossX && mCrossY)
+ {
+ moveTo(mCrossX, mCrossY);
+ }
+ else
+ {
+ std::map<std::string, Vector>::iterator iter =
+ mHomes.find(mMap->getProperty("_filename"));
+
+ if (iter != mHomes.end())
+ {
+ Vector pos = mHomes[(*iter).first];
+ if (getTileX() == pos.x && getTileY() == pos.y)
+ {
+ Net::getPlayerHandler()->setDestination(
+ static_cast<int>(pos.x),
+ static_cast<int>(pos.y),
+ static_cast<int>(mDirection));
+ }
+ else
+ {
+ navigateTo(pos.x, pos.y);
+ }
+ }
+ }
+}
+
+void LocalPlayer::changeAttackWeaponType()
+{
+ mAttackWeaponType++;
+ if (mAttackWeaponType > 3)
+ mAttackWeaponType = 1;
+
+ config.setValue("attackWeaponType", mAttackWeaponType);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::changeAttackType()
+{
+ mAttackType++;
+ if (mAttackType > 3)
+ mAttackType = 0;
+
+ config.setValue("attackType", mAttackType);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::invertDirection()
+{
+ mMoveState = 0;
+ mInvertDirection ++;
+ if (mInvertDirection > 4)
+ mInvertDirection = 0;
+ config.setValue("invertMoveDirection", mInvertDirection);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::changeCrazyMoveType()
+{
+ mCrazyMoveState = 0;
+ mCrazyMoveType++;
+ if (mCrazyMoveType > 10)
+ mCrazyMoveType = 1;
+
+ config.setValue("crazyMoveType", mCrazyMoveType);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::changePickUpType()
+{
+ mPickUpType++;
+ if (mPickUpType > 6)
+ mPickUpType = 0;
+
+ config.setValue("pickUpType", mPickUpType);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::changeFollowMode()
+{
+ mFollowMode++;
+ if (mFollowMode > 3)
+ mFollowMode = 0;
+
+ config.setValue("followMode", mFollowMode);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::changeImitationMode()
+{
+ mImitationMode++;
+ if (mImitationMode > 1)
+ mImitationMode = 0;
+
+ config.setValue("imitationMode", mImitationMode);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::changeEquipmentBeforeAttack(Being* target)
+{
+ if (mAttackWeaponType == 1 || !target || !PlayerInfo::getInventory())
+ return;
+
+ bool allowSword = false;
+ int dx = target->getTileX() - getTileX();
+ int dy = target->getTileY() - getTileY();
+ Item *item = NULL;
+
+ if (dx * dx + dy * dy > 80)
+ return;
+
+ if (dx * dx + dy * dy < 8)
+ allowSword = true;
+
+ //if attack distance for sword
+ if (allowSword)
+ {
+ //finding sword
+ item = PlayerInfo::getInventory()->findItem(571);
+
+ if (!item)
+ item = PlayerInfo::getInventory()->findItem(570);
+
+ if (!item)
+ item = PlayerInfo::getInventory()->findItem(536);
+
+ //no swords
+ if (!item)
+ return;
+
+ //if sword not equiped
+ if (!item->isEquipped())
+ {
+ Net::getInventoryHandler()->equipItem(item);
+ }
+
+ //if need equip shield too
+ if (mAttackWeaponType == 3)
+ {
+ //finding shield
+ item = PlayerInfo::getInventory()->findItem(601);
+ if (!item)
+ item = PlayerInfo::getInventory()->findItem(602);
+ if (item && !item->isEquipped())
+ {
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ }
+
+ }
+ //big distance. allowed only bow
+ else
+ {
+ //finding bow
+ item = PlayerInfo::getInventory()->findItem(545);
+
+ if (!item)
+ item = PlayerInfo::getInventory()->findItem(530);
+
+ //no bow
+ if (!item)
+ return;
+
+ if (!item->isEquipped())
+ {
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ }
+
+}
+
+
+void LocalPlayer::crazyMove()
+{
+// if (!allowAction())
+// return;
+
+ bool oldDisableCrazyMove = mDisableCrazyMove;
+ mDisableCrazyMove = true;
+ switch(mCrazyMoveType)
+ {
+ case 1:
+ crazyMove1();
+ break;
+ case 2:
+ crazyMove2();
+ break;
+ case 3:
+ crazyMove3();
+ break;
+ case 4:
+ crazyMove4();
+ break;
+ case 5:
+ crazyMove5();
+ break;
+ case 6:
+ crazyMove6();
+ break;
+ case 7:
+ crazyMove7();
+ break;
+ case 8:
+ crazyMove8();
+ break;
+ case 9:
+ crazyMove9();
+ break;
+ case 10:
+ crazyMoveA();
+ break;
+ default:
+ break;
+ }
+ mDisableCrazyMove = oldDisableCrazyMove;
+}
+
+void LocalPlayer::crazyMove1()
+{
+ if (mAction == MOVE)
+ return;
+
+ if (!Client::limitPackets(PACKET_DIRECTION))
+ return;
+
+ if (getDirection() == Being::UP)
+ {
+ setWalkingDir(Being::UP);
+ setDirection(Being::LEFT);
+ Net::getPlayerHandler()->setDirection(Being::LEFT);
+ }
+ else if (getDirection() == Being::LEFT)
+ {
+ setWalkingDir(Being::LEFT);
+ setDirection(Being::DOWN);
+ Net::getPlayerHandler()->setDirection(Being::DOWN);
+ }
+ else if (getDirection() == Being::DOWN)
+ {
+ setWalkingDir(Being::DOWN);
+ setDirection(Being::RIGHT);
+ Net::getPlayerHandler()->setDirection(Being::RIGHT);
+ }
+ else if (getDirection() == Being::RIGHT)
+ {
+ setWalkingDir(Being::RIGHT);
+ setDirection(Being::UP);
+ Net::getPlayerHandler()->setDirection(Being::UP);
+ }
+}
+
+void LocalPlayer::crazyMove2()
+{
+ if (mAction == MOVE)
+ return;
+
+ if (!Client::limitPackets(PACKET_DIRECTION))
+ return;
+
+ if (getDirection() == Being::UP)
+ {
+ setWalkingDir(Being::UP | Being::LEFT);
+ setDirection(Being::RIGHT);
+ Net::getPlayerHandler()->setDirection(Being::DOWN | Being::RIGHT);
+ }
+ else if (getDirection() == Being::RIGHT)
+ {
+ setWalkingDir(Being::UP | Being::RIGHT);
+ setDirection(Being::DOWN);
+ Net::getPlayerHandler()->setDirection(Being::DOWN | Being::LEFT);
+ }
+ else if (getDirection() == Being::DOWN)
+ {
+ setWalkingDir(Being::DOWN | Being::RIGHT);
+ setDirection(Being::LEFT);
+ Net::getPlayerHandler()->setDirection(Being::UP | Being::LEFT);
+ }
+ else if (getDirection() == Being::LEFT)
+ {
+ setWalkingDir(Being::DOWN | Being::LEFT);
+ setDirection(Being::UP);
+ Net::getPlayerHandler()->setDirection(Being::UP | Being::RIGHT);
+ }
+}
+
+void LocalPlayer::crazyMove3()
+{
+ if (mAction == MOVE)
+ return;
+
+ switch(mCrazyMoveState)
+ {
+ case 0:
+ move(1, 1);
+ mCrazyMoveState = 1;
+ break;
+ case 1:
+ move(1, -1);
+ mCrazyMoveState = 2;
+ break;
+ case 2:
+ move(-1, -1);
+ mCrazyMoveState = 3;
+ break;
+ case 3:
+ move(-1, 1);
+ mCrazyMoveState = 0;
+ break;
+ default:
+ break;
+ }
+
+ if (!Client::limitPackets(PACKET_DIRECTION))
+ return;
+
+ setDirection(Being::DOWN);
+ Net::getPlayerHandler()->setDirection(Being::DOWN);
+}
+
+void LocalPlayer::crazyMove4()
+{
+ if (mAction == MOVE)
+ return;
+
+ switch(mCrazyMoveState)
+ {
+ case 0:
+ move(7, 0);
+ mCrazyMoveState = 1;
+ break;
+ case 1:
+ move(-7, 0);
+ mCrazyMoveState = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void LocalPlayer::crazyMove5()
+{
+ if (mAction == MOVE)
+ return;
+
+ switch(mCrazyMoveState)
+ {
+ case 0:
+ move(0, 7);
+ mCrazyMoveState = 1;
+ break;
+ case 1:
+ move(0, -7);
+ mCrazyMoveState = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void LocalPlayer::crazyMove6()
+{
+ if (mAction == MOVE)
+ return;
+
+ switch(mCrazyMoveState)
+ {
+ case 0:
+ move(3, 0);
+ mCrazyMoveState = 1;
+ break;
+ case 1:
+ move(2, -2);
+ mCrazyMoveState = 2;
+ break;
+ case 2:
+ move(0, -3);
+ mCrazyMoveState = 3;
+ break;
+ case 3:
+ move(-2, -2);
+ mCrazyMoveState = 4;
+ break;
+ case 4:
+ move(-3, 0);
+ mCrazyMoveState = 5;
+ break;
+ case 5:
+ move(-2, 2);
+ mCrazyMoveState = 6;
+ break;
+ case 6:
+ move(0, 3);
+ mCrazyMoveState = 7;
+ break;
+ case 7:
+ move(2, 2);
+ mCrazyMoveState = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void LocalPlayer::crazyMove7()
+{
+ if (mAction == MOVE)
+ return;
+
+ switch(mCrazyMoveState)
+ {
+ case 0:
+ move(1, 1);
+ mCrazyMoveState = 1;
+ break;
+ case 1:
+ move(-1, 1);
+ mCrazyMoveState = 2;
+ break;
+ case 2:
+ move(-1, -1);
+ mCrazyMoveState = 3;
+ break;
+ case 3:
+ move(1, -1);
+ mCrazyMoveState = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void LocalPlayer::crazyMove8()
+{
+ if (mAction == MOVE)
+ return;
+ int idx = 0;
+ int dist = 1;
+
+// look
+// up, ri,do,le
+ static const int movesX[][4] =
+ {
+ {-1, 0, 1, 0}, //move left
+ { 0, 1, 0, -1}, //move up
+ { 1, 0, -1, 0}, //move right
+ { 0, -1, 0, 1} //move down
+ };
+
+// look
+// up, ri,do,le
+ static const int movesY[][4] =
+ {
+ { 0, -1, 0, 1}, //move left
+ {-1, 0, 1, 0}, //move up
+ { 0, 1, 0, -1}, //move right
+ { 1, 0, -1, 0} //move down
+ };
+
+ if (getDirection() == Being::UP)
+ idx = 0;
+ else if (getDirection() == Being::RIGHT)
+ idx = 1;
+ else if (getDirection() == Being::DOWN)
+ idx = 2;
+ else if (getDirection() == Being::LEFT)
+ idx = 3;
+
+
+ int mult = 1;
+ if (mMap->getWalk(getTileX() + movesX[idx][0],
+ getTileY() + movesY[idx][0], getWalkMask()))
+ {
+ while (mMap->getWalk(getTileX() + movesX[idx][0] * mult,
+ getTileY() + movesY[idx][0] * mult,
+ getWalkMask()) && mult <= dist)
+ {
+ mult ++;
+ }
+ move(movesX[idx][0] * (mult - 1), movesY[idx][0] * (mult - 1));
+ }
+ else if (mMap->getWalk(getTileX() + movesX[idx][1],
+ getTileY() + movesY[idx][1], getWalkMask()))
+ {
+ while (mMap->getWalk(getTileX() + movesX[idx][1] * mult,
+ getTileY() + movesY[idx][1] * mult,
+ getWalkMask()) && mult <= dist)
+ {
+ mult ++;
+ }
+ move(movesX[idx][1] * (mult - 1), movesY[idx][1] * (mult - 1));
+ }
+ else if (mMap->getWalk(getTileX() + movesX[idx][2],
+ getTileY() + movesY[idx][2], getWalkMask()))
+ {
+ while (mMap->getWalk(getTileX() + movesX[idx][2] * mult,
+ getTileY() + movesY[idx][2] * mult,
+ getWalkMask()) && mult <= dist)
+ {
+ mult ++;
+ }
+ move(movesX[idx][2] * (mult - 1), movesY[idx][2] * (mult - 1));
+ }
+ else if (mMap->getWalk(getTileX() + movesX[idx][3],
+ getTileY() + movesY[idx][3], getWalkMask()))
+ {
+ while (mMap->getWalk(getTileX() + movesX[idx][3] * mult,
+ getTileY() + movesY[idx][3] * mult,
+ getWalkMask()) && mult <= dist)
+ {
+ mult ++;
+ }
+ move(movesX[idx][3] * (mult - 1), movesY[idx][3] * (mult - 1));
+ }
+}
+
+void LocalPlayer::crazyMove9()
+{
+ int dx = 0;
+ int dy = 0;
+
+ if (mAction == MOVE)
+ return;
+
+ switch (mCrazyMoveState)
+ {
+ case 0:
+ switch (getDirection())
+ {
+ case UP : dy = -1; break;
+ case DOWN : dy = 1; break;
+ case LEFT : dx = -1; break;
+ case RIGHT: dx = 1; break;
+ default: break;
+ }
+ move(dx, dy);
+ mCrazyMoveState = 1;
+ break;
+ case 1:
+ mCrazyMoveState = 2;
+ if (!allowAction())
+ return;
+ Net::getPlayerHandler()->changeAction(SIT);
+ break;
+ case 2:
+ mCrazyMoveState = 3;
+ break;
+ case 3:
+ mCrazyMoveState = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void LocalPlayer::crazyMoveA()
+{
+ std::string mMoveProgram(config.getStringValue("crazyMoveProgram"));
+
+ if (mAction == MOVE)
+ return;
+
+ if (mMoveProgram.length() == 0)
+ return;
+
+ if (mCrazyMoveState >= mMoveProgram.length())
+ mCrazyMoveState = 0;
+
+ Uint8 dir = 0;
+
+ // move command
+ if (mMoveProgram[mCrazyMoveState] == 'm')
+ {
+ int dx = 0;
+ int dy = 0;
+
+ mCrazyMoveState ++;
+ if (mCrazyMoveState < mMoveProgram.length())
+ {
+ char param = mMoveProgram[mCrazyMoveState++];
+ if (param == '?')
+ {
+ char cmd[] = {'l', 'r', 'u', 'd'};
+ srand(tick_time);
+ param = cmd[rand() % 4];
+ }
+ switch (param)
+ {
+ case 'd':
+ move(0, 1);
+ break;
+ case 'u':
+ move(0, -1);
+ break;
+ case 'l':
+ move(-1, 0);
+ break;
+ case 'r':
+ move(1, 0);
+ break;
+ case 'f':
+ switch (getDirection())
+ {
+ case UP : dy = -1; break;
+ case DOWN : dy = 1; break;
+ case LEFT : dx = -1; break;
+ case RIGHT: dx = 1; break;
+ default: break;
+ }
+ move(dx, dy);
+ break;
+ case 'b':
+ switch (getDirection())
+ {
+ case UP : dy = 1; break;
+ case DOWN : dy = -1; break;
+ case LEFT : dx = 1; break;
+ case RIGHT: dx = -1; break;
+ default: break;
+ }
+ move(dx, dy);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ // direction command
+ else if (mMoveProgram[mCrazyMoveState] == 'd')
+ {
+ mCrazyMoveState ++;
+
+ if (mCrazyMoveState < mMoveProgram.length())
+ {
+ char param = mMoveProgram[mCrazyMoveState++];
+ if (param == '?')
+ {
+ char cmd[] = {'l', 'r', 'u', 'd'};
+ srand(tick_time);
+ param = cmd[rand() % 4];
+ }
+ switch (param)
+ {
+ case 'd':
+
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ setDirection(Being::DOWN);
+ Net::getPlayerHandler()->setDirection(Being::DOWN);
+ }
+ break;
+ case 'u':
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ setDirection(Being::UP);
+ Net::getPlayerHandler()->setDirection(Being::UP);
+ }
+ break;
+ case 'l':
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ setDirection(Being::LEFT);
+ Net::getPlayerHandler()->setDirection(Being::LEFT);
+ }
+ break;
+ case 'r':
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ setDirection(Being::RIGHT);
+ Net::getPlayerHandler()->setDirection(Being::RIGHT);
+ }
+ break;
+ case 'L':
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ switch (getDirection())
+ {
+ case UP : dir = Being::LEFT; break;
+ case DOWN : dir = Being::RIGHT; break;
+ case LEFT : dir = Being::DOWN; break;
+ case RIGHT : dir = Being::UP; break;
+ default: break;
+ }
+ setDirection(dir);
+ Net::getPlayerHandler()->setDirection(dir);
+ }
+ break;
+ case 'R':
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ switch (getDirection())
+ {
+ case UP : dir = Being::RIGHT; break;
+ case DOWN : dir = Being::LEFT; break;
+ case LEFT : dir = Being::UP; break;
+ case RIGHT : dir = Being::DOWN; break;
+ default: break;
+ }
+ setDirection(dir);
+ Net::getPlayerHandler()->setDirection(dir);
+ }
+ break;
+ case 'b':
+ if (Client::limitPackets(PACKET_DIRECTION))
+ {
+ switch (getDirection())
+ {
+ case UP : dir = Being::DOWN; break;
+ case DOWN : dir = Being::UP; break;
+ case LEFT : dir = Being::RIGHT; break;
+ case RIGHT : dir = Being::LEFT; break;
+ default: break;
+ }
+ setDirection(dir);
+ Net::getPlayerHandler()->setDirection(dir);
+ }
+ break;
+ case '0':
+ dropShortcut->dropFirst();
+ break;
+ case 'a':
+ dropShortcut->dropItems();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ // sit command
+ else if (mMoveProgram[mCrazyMoveState] == 's')
+ {
+ mCrazyMoveState ++;
+ if (toggleSit())
+ mCrazyMoveState ++;
+ }
+ // wear outfits
+ else if (mMoveProgram[mCrazyMoveState] == 'o')
+ {
+ mCrazyMoveState ++;
+ if (mCrazyMoveState < mMoveProgram.length())
+ {
+ // wear next outfit
+ if (mMoveProgram[mCrazyMoveState] == 'n')
+ {
+ mCrazyMoveState ++;
+ outfitWindow->wearNextOutfit();
+ }
+ // wear previous outfit
+ else if (mMoveProgram[mCrazyMoveState] == 'p')
+ {
+ mCrazyMoveState ++;
+ outfitWindow->wearPreviousOutfit();
+ }
+ }
+ }
+ // pause
+ else if (mMoveProgram[mCrazyMoveState] == 'w')
+ {
+ mCrazyMoveState ++;
+ }
+ // pick up
+ else if (mMoveProgram[mCrazyMoveState] == 'p')
+ {
+ mCrazyMoveState ++;
+ pickUpItems();
+ }
+ // emote
+ else if (mMoveProgram[mCrazyMoveState] == 'e')
+ {
+ mCrazyMoveState ++;
+ char emo = mMoveProgram[mCrazyMoveState];
+ if (emo == '?')
+ {
+ srand(tick_time);
+ emote(static_cast<unsigned char>(1 + (rand() % 13)));
+ }
+ else
+ {
+ if (emo >= '0' && emo <= '9')
+ emote(static_cast<unsigned char>(emo - '0' + 1));
+ else if (emo >= 'a' && emo <= 'd')
+ emote(static_cast<unsigned char>(emo - 'a' + 11));
+ }
+
+ mCrazyMoveState ++;
+ }
+ else
+ {
+ mCrazyMoveState ++;
+ }
+
+// mCrazyMoveState ++;
+ if (mCrazyMoveState >= mMoveProgram.length())
+ mCrazyMoveState = 0;
+
+// debugMsg("mCrazyMoveState: " + toString(mCrazyMoveState));
+}
+
+bool LocalPlayer::isReachable(int x, int y, int maxCost)
+{
+ if (!mMap)
+ return false;
+
+ if (x - 1 <= getTileX() && x + 1 >= getTileX()
+ && y - 1 <= getTileY() && y + 1 >= getTileY() )
+ {
+ return true;
+ }
+
+ const Vector &playerPos = getPosition();
+
+ Path debugPath = mMap->findPath(
+ (int) (playerPos.x - 16) / 32,
+ (int) (playerPos.y - 32) / 32,
+ x, y, 0x00, maxCost);
+
+ return !debugPath.empty();
+}
+
+bool LocalPlayer::isReachable(Being *being, int maxCost)
+{
+ if (!being || !mMap)
+ return false;
+
+ if (being->isReachable() == Being::REACH_NO)
+ return false;
+
+ if (being->getTileX() - 1 <= getTileX()
+ && being->getTileX() + 1 >= getTileX()
+ && being->getTileY() - 1 <= getTileY()
+ && being->getTileY() + 1 >= getTileY())
+ {
+ being->setDistance(0);
+ being->setIsReachable(Being::REACH_YES);
+ return true;
+ }
+
+ const Vector &playerPos = getPosition();
+
+ Path debugPath = mMap->findPath(
+ (int) (playerPos.x - 16) / 32,
+ (int) (playerPos.y - 32) / 32,
+ being->getTileX(), being->getTileY(), 0x00, maxCost);
+
+ being->setDistance(static_cast<int>(debugPath.size()));
+ if (!debugPath.empty())
+ {
+ being->setIsReachable(Being::REACH_YES);
+ return true;
+ }
+ else
+ {
+ being->setIsReachable(Being::REACH_NO);
+ return false;
+ }
+}
+
+bool LocalPlayer::pickUpItems(int pickUpType)
+{
+ if (!actorSpriteManager)
+ return false;
+
+ bool status = false;
+ int x = getTileX();
+ int y = getTileY();
+
+ // first pick up item on player position
+ FloorItem *item =
+ actorSpriteManager->findItem(x, y);
+ if (item)
+ {
+ status = pickUp(item);
+ //status = true;
+ }
+
+ if (pickUpType == 0)
+ pickUpType = mPickUpType;
+
+ if (pickUpType == 0)
+ return status;
+
+ int x1, y1, x2, y2;
+ switch(pickUpType)
+ {
+ case 1:
+ switch (getDirection())
+ {
+ case UP : --y; break;
+ case DOWN : ++y; break;
+ case LEFT : --x; break;
+ case RIGHT: ++x; break;
+ default: break;
+ }
+ item = actorSpriteManager->findItem(x, y);
+ if (item)
+ {
+ status = pickUp(item);
+// status = true;
+ }
+ break;
+ case 2:
+ switch (getDirection())
+ {
+ case UP : x1 = x - 1; y1 = y - 1; x2 = x + 1; y2 = y; break;
+ case DOWN : x1 = x - 1; y1 = y; x2 = x + 1; y2 = y + 1; break;
+ case LEFT : x1 = x - 1; y1 = y - 1; x2 = x; y2 = y + 1; break;
+ case RIGHT: x1 = x; y1 = y - 1; x2 = x + 1; y2 = y + 1; break;
+ default: x1 = x; x2 = x; y1 = y; y2 = y; break;
+ }
+ if (actorSpriteManager->pickUpAll(x1, y1, x2, y2))
+ status = true;
+ break;
+ case 3:
+ if (actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
+ status = true;
+ break;
+
+ case 4:
+ if (!actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
+ {
+ if (actorSpriteManager->pickUpNearest(x, y, 4))
+ status = true;
+ }
+ else
+ {
+ status = true;
+ }
+ break;
+
+ case 5:
+ if (!actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
+ {
+ if (actorSpriteManager->pickUpNearest(x, y, 8))
+ status = true;
+ }
+ else
+ {
+ status = true;
+ }
+ break;
+
+ case 6:
+ if (!actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
+ {
+ if (actorSpriteManager->pickUpNearest(x, y, 90))
+ status = true;
+ }
+ else
+ {
+ status = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+void LocalPlayer::changeQuickDropCounter()
+{
+ mQuickDropCounter++;
+ if (mQuickDropCounter > 9)
+ mQuickDropCounter = 1;
+
+ config.setValue("quickDropCounter", mQuickDropCounter);
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::moveByDirection(unsigned char dir)
+{
+ int dx = 0, dy = 0;
+#ifdef MANASERV_SUPPORT
+ if (dir & UP)
+ dy -= 32;
+ if (dir & DOWN)
+ dy += 32;
+ if (dir & LEFT)
+ dx -= 32;
+ if (dir & RIGHT)
+ dx += 32;
+#else
+ if (dir & UP)
+ dy--;
+ if (dir & DOWN)
+ dy++;
+ if (dir & LEFT)
+ dx--;
+ if (dir & RIGHT)
+ dx++;
+#endif
+
+ move(dx, dy);
+}
+
+void LocalPlayer::specialMove(unsigned char direction)
+{
+ if (direction && (mNavigateX || mNavigateY))
+ naviageClean();
+
+ if (direction && (getInvertDirection() >= 2
+ && getInvertDirection() <= 4)
+ && !mIsServerBuggy)
+ {
+ int max;
+ if (getInvertDirection() == 2)
+ max = 10;
+ else
+ max = 30;
+
+ if (mAction == MOVE)
+ return;
+
+ if (getInvertDirection() == 2)
+ max = 5;
+ else if (getInvertDirection() == 4)
+ max = 1;
+ else
+ max = 3;
+
+ if (getMoveState() < max)
+ {
+ moveByDirection(direction);
+ mMoveState ++;
+ }
+ else
+ {
+ mMoveState = 0;
+ crazyMove();
+ }
+ }
+ else
+ {
+// if (direction != 0 && getInvertDirection() == 4)
+// crazyMove();
+ setWalkingDir(direction);
+ }
+
+}
+
+void LocalPlayer::debugMsg(std::string str)
+{
+ if (debugChatTab)
+ debugChatTab->chatLog(str);
+}
+
+void LocalPlayer::switchMagicAttack()
+{
+ mMagicAttackType++;
+ if (mMagicAttackType > 4)
+ mMagicAttackType = 0;
+
+ config.setValue("magicAttackType", mMagicAttackType);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::magicAttack()
+{
+ if (!chatWindow || !isAlive()
+ || !Net::getPlayerHandler()->canUseMagic())
+ {
+ return;
+ }
+
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+
+ switch(mMagicAttackType)
+ {
+ //flar W00
+ case 0:
+ tryMagic("#flar", 1, 0, 10);
+ break;
+ //chiza W01
+ case 1:
+ tryMagic("#chiza", 1, 0, 9);
+ break;
+ //ingrav W10
+ case 2:
+ tryMagic("#ingrav", 2, 2, 20);
+ break;
+ //frillyar W11
+ case 3:
+ tryMagic("#frillyar", 2, 2, 25);
+ break;
+ //upmarmu W12
+ case 4:
+ tryMagic("#upmarmu", 2, 2, 20);
+ break;
+ default:
+ break;
+ }
+}
+
+void LocalPlayer::tryMagic(std::string spell, int baseMagic,
+ int schoolMagic, int mana)
+{
+ if (!chatWindow)
+ return;
+
+ if (PlayerInfo::getStatEffective(340) >= baseMagic
+ && PlayerInfo::getStatEffective(342) >= schoolMagic)
+ {
+ if (PlayerInfo::getAttribute(MP) >= mana)
+ {
+ if (!Client::limitPackets(PACKET_CHAT))
+ return;
+
+ chatWindow->localChatInput(spell);
+ }
+ }
+}
+
+void LocalPlayer::changeMoveToTargetType()
+{
+ mMoveToTargetType++;
+ if (mMoveToTargetType > 6)
+ mMoveToTargetType = 0;
+
+ config.setValue("moveToTargetType", mMoveToTargetType);
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::loadHomes()
+{
+ std::string homeStr = serverConfig.getValue("playerHomes",
+ "maps/018-1.tmx 71 76 maps/013-3.tmx 71 24");
+ std::string buf;
+ std::stringstream ss(homeStr);
+
+ while (ss >> buf)
+ {
+ Vector pos;
+ ss >> pos.x;
+ ss >> pos.y;
+ mHomes[buf] = pos;
+ }
+
+}
+
+void LocalPlayer::setMap(Map *map)
+{
+ if (map)
+ {
+ std::map<std::string, Vector>::iterator iter =
+ mHomes.find(map->getProperty("_filename"));
+
+ if (iter != mHomes.end())
+ {
+ Vector pos = mHomes[(*iter).first];
+ SpecialLayer *specialLayer = map->getSpecialLayer();
+ if (specialLayer)
+ {
+// specialLayer->clean();
+ specialLayer->setTile(static_cast<int>(pos.x),
+ static_cast<int>(pos.y),
+ MapItem::HOME);
+ }
+ }
+ if (socialWindow)
+ socialWindow->updateActiveList();
+ }
+ naviageClean();
+ mCrossX = 0;
+ mCrossY = 0;
+
+ Being::setMap(map);
+ updateNavigateList();
+// updateCoords();
+}
+
+void LocalPlayer::setHome()
+{
+ if (!mMap || !socialWindow)
+ return;
+
+ SpecialLayer *specialLayer = mMap->getSpecialLayer();
+
+ if (!specialLayer)
+ return;
+
+ std::string key = mMap->getProperty("_filename");
+ Vector pos = mHomes[key];
+
+ if (mAction == SIT)
+ {
+ std::map<std::string, Vector>::iterator iter = mHomes.find(key);
+
+ if (iter != mHomes.end())
+ socialWindow->removePortal(pos.x, pos.y);
+
+ if (iter != mHomes.end() && getTileX() == pos.x && getTileY() == pos.y)
+ {
+ mMap->updatePortalTile("", MapItem::EMPTY, pos.x, pos.y);
+// if (specialLayer)
+// specialLayer->setTile(pos.x, pos.y, MapItem::EMPTY);
+ mHomes.erase(key);
+ socialWindow->removePortal(pos.x, pos.y);
+ }
+ else
+ {
+ if (specialLayer && iter != mHomes.end())
+ specialLayer->setTile(pos.x, pos.y, MapItem::EMPTY);
+
+ pos.x = getTileX();
+ pos.y = getTileY();
+ mHomes[key] = pos;
+ mMap->updatePortalTile("home", MapItem::HOME,
+ getTileX(), getTileY());
+// if (specialLayer)
+// specialLayer->setTile(getTileX(), getTileY(), MapItem::HOME);
+ socialWindow->addPortal(getTileX(), getTileY());
+ }
+ MapItem *mapItem = specialLayer->getTile(getTileX(), getTileY());
+ if (mapItem)
+ {
+ int idx = socialWindow->getPortalIndex(getTileX(), getTileY());
+ mapItem->setName(keyboard.getKeyShortString(
+ outfitWindow->keyName(idx)));
+ }
+ saveHomes();
+ }
+ else
+ {
+ MapItem *mapItem = specialLayer->getTile(getTileX(), getTileY());
+ int type = 0;
+// if (!mapItem)
+// return;
+
+ std::map<std::string, Vector>::iterator iter = mHomes.find(key);
+ if (iter != mHomes.end() && getTileX() == pos.x && getTileY() == pos.y)
+ {
+ mHomes.erase(key);
+ saveHomes();
+ }
+
+ if (!mapItem || mapItem->getType() == MapItem::EMPTY)
+ {
+// if (mAction == SIT)
+// type = MapItem::HOME;
+ if (mDirection & UP)
+ type = MapItem::ARROW_UP;
+ else if (mDirection & LEFT)
+ type = MapItem::ARROW_LEFT;
+ else if (mDirection & DOWN)
+ type = MapItem::ARROW_DOWN;
+ else if (mDirection & RIGHT)
+ type = MapItem::ARROW_RIGHT;
+ }
+ else
+ {
+ type = MapItem::EMPTY;
+ }
+ mMap->updatePortalTile("", type, getTileX(), getTileY());
+// mapItem = specialLayer->getTile(getTileX(), getTileY());
+
+ if (type != MapItem::EMPTY)
+ {
+ socialWindow->addPortal(getTileX(), getTileY());
+ mapItem = specialLayer->getTile(getTileX(), getTileY());
+ if (mapItem)
+ {
+ int idx = socialWindow->getPortalIndex(getTileX(), getTileY());
+ mapItem->setName(keyboard.getKeyShortString(
+ outfitWindow->keyName(idx)));
+ }
+ }
+ else
+ {
+ specialLayer->setTile(getTileX(), getTileY(), MapItem::EMPTY);
+ socialWindow->removePortal(getTileX(), getTileY());
+ }
+
+// specialLayer->setTile(getTileX(), getTileY(), type);
+ }
+}
+
+void LocalPlayer::saveHomes()
+{
+ std::string homeStr;
+ std::string buf;
+ std::stringstream ss(homeStr);
+
+ for (std::map<std::string, Vector>::iterator iter = mHomes.begin();
+ iter != mHomes.end(); ++iter )
+ {
+ Vector pos = (*iter).second;
+
+ if (iter != mHomes.begin())
+ ss << " ";
+ ss << (*iter).first << " " << pos.x << " " << pos.y;
+ }
+
+ serverConfig.setValue("playerHomes", ss.str());
+}
+
+
+void LocalPlayer::switchGameModifiers()
+{
+ mDisableGameModifiers = !mDisableGameModifiers;
+ config.setValue("disableGameModifiers", mDisableGameModifiers);
+ miniStatusWindow->updateStatus();
+}
+
+void LocalPlayer::pingRequest()
+{
+ if (mWaitPing == true && mPingSendTick != 0)
+ {
+ if (tick_time >= mPingSendTick
+ && (tick_time - mPingSendTick) > 1000)
+ {
+ return;
+ }
+ }
+
+ mPingSendTick = tick_time;
+ mWaitPing = true;
+ Net::getBeingHandler()->requestNameById(getId());
+}
+
+void LocalPlayer::pingResponse()
+{
+ if (mWaitPing == true && mPingSendTick > 0)
+ {
+ mWaitPing = false;
+ if (tick_time < mPingSendTick)
+ {
+ mPingSendTick = 0;
+ mPingTime = 0;
+ }
+ else
+ {
+ mPingTime = (tick_time - mPingSendTick) * 10;
+ }
+ }
+}
+
+void LocalPlayer::tryPingRequest()
+{
+ if (mPingSendTick == 0 || tick_time < mPingSendTick
+ || (tick_time - mPingSendTick) > 200)
+ {
+ pingRequest();
+ }
+}
+
+void LocalPlayer::changeAwayMode()
+{
+ mAwayMode = !mAwayMode;
+ mAfkTime = 0;
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+ if (mAwayMode)
+ {
+ cancelFollow();
+ naviageClean();
+ if (outfitWindow)
+ outfitWindow->wearAwayOutfit();
+ mAwayDialog = new OkDialog(_("Away"),
+ config.getStringValue("afkMessage"), true, false);
+ mAwayDialog->addActionListener(mAwayListener);
+ sound.volumeOff();
+ }
+ else
+ {
+ mAwayDialog = 0;
+ sound.volumeRestore();
+ }
+}
+
+void LocalPlayer::setAway(const std::string &message)
+{
+ if (!message.empty())
+ config.setValue("afkMessage", message);
+ changeAwayMode();
+}
+
+void LocalPlayer::afkRespond(ChatTab *tab, const std::string &nick)
+{
+ if (mAwayMode)
+ {
+ if (mAfkTime == 0
+ || cur_time < mAfkTime
+ || cur_time - mAfkTime > awayLimitTimer)
+ {
+ std::string msg = "*AFK*: "
+ + config.getStringValue("afkMessage");
+
+ Net::getChatHandler()->privateMessage(nick, msg);
+ if (!tab)
+ {
+ if (localChatTab)
+ {
+ localChatTab->chatLog(getName() + " : " + msg,
+ ACT_WHISPER, false);
+ }
+ }
+ else
+ {
+ tab->chatLog(getName(), msg);
+ }
+ mAfkTime = cur_time;
+ }
+ }
+}
+
+void LocalPlayer::navigateTo(int x, int y)
+{
+ if (!mMap)
+ return;
+
+ SpecialLayer *tmpLayer = mMap->getTempLayer();
+ if (!tmpLayer)
+ return;
+
+ const Vector &playerPos = getPosition();
+ mShowNavigePath = true;
+ mOldX = playerPos.x;
+ mOldY = playerPos.y;
+ mOldTileX = getTileX();
+ mOldTileY = getTileY();
+ mNavigateX = x;
+ mNavigateY = y;
+ mNavigateId = 0;
+
+ mNavigatePath = mMap->findPath((int) (playerPos.x - 16) / 32,
+ (int) (playerPos.y - 32) / 32,
+ x, y, 0x00, 0);
+
+ if (mDrawPath)
+ tmpLayer->addRoad(mNavigatePath);
+}
+
+void LocalPlayer::navigateTo(Being *being)
+{
+ if (!mMap || !being)
+ return;
+
+ SpecialLayer *tmpLayer = mMap->getTempLayer();
+ if (!tmpLayer)
+ return;
+
+ const Vector &playerPos = getPosition();
+ mShowNavigePath = true;
+ mOldX = playerPos.x;
+ mOldY = playerPos.y;
+ mOldTileX = getTileX();
+ mOldTileY = getTileY();
+ mNavigateX = being->getTileX();
+ mNavigateY = being->getTileY();
+
+ mNavigatePath = mMap->findPath((int) (playerPos.x - 16) / 32,
+ (int) (playerPos.y - 32) / 32,
+ being->getTileX(), being->getTileY(),
+ 0x00, 0);
+
+ if (mDrawPath)
+ tmpLayer->addRoad(mNavigatePath);
+}
+
+void LocalPlayer::naviageClean()
+{
+ if (!mMap)
+ return;
+
+ mShowNavigePath = false;
+ mOldX = 0;
+ mOldY = 0;
+ mOldTileX = 0;
+ mOldTileY = 0;
+ mNavigateX = 0;
+ mNavigateY = 0;
+ mNavigateId = 0;
+
+ mNavigatePath.clear();
+
+ SpecialLayer *tmpLayer = mMap->getTempLayer();
+ if (!tmpLayer)
+ return;
+
+ tmpLayer->clean();
+}
+
+void LocalPlayer::updateCoords()
+{
+ Being::updateCoords();
+
+ const Vector &playerPos = getPosition();
+
+ if (getTileX() != mOldTileX || getTileY() != mOldTileY)
+ {
+ if (socialWindow)
+ socialWindow->updatePortals();
+ if (viewport)
+ viewport->hideBeingPopup();
+ }
+
+ if (mShowNavigePath)
+ {
+ if (getTileX() != mOldTileX || getTileY() != mOldTileY)
+// if (playerPos.x != mOldX || playerPos.y != mOldY)
+ {
+ SpecialLayer *tmpLayer = mMap->getTempLayer();
+ if (!tmpLayer)
+ return;
+
+ int x = (int) (playerPos.x - 16) / 32;
+ int y = (int) (playerPos.y - 32) / 32;
+ if (mNavigateId)
+ {
+ if (!actorSpriteManager)
+ {
+ naviageClean();
+ return;
+ }
+
+ Being* being = actorSpriteManager->findBeing(mNavigateId);
+ if (!being)
+ {
+ naviageClean();
+ return;
+ }
+ mNavigateX = being->getTileX();
+ mNavigateY = being->getTileY();
+ }
+
+ if (mNavigateX == x && mNavigateY == y)
+ {
+ naviageClean();
+ return;
+ }
+ else
+ {
+ for (Path::const_iterator i = mNavigatePath.begin(),
+ i_end = mNavigatePath.end(); i != i_end; ++i)
+ {
+ if ((*i).x == getTileX() && (*i).y == getTileY())
+ {
+ mNavigatePath.pop_front();
+ break;
+ }
+ }
+
+ if (mDrawPath)
+ {
+ tmpLayer->clean();
+ tmpLayer->addRoad(mNavigatePath);
+ }
+// navigateTo(mNavigateX, mNavigateY);
+ }
+ }
+ }
+ mOldX = playerPos.x;
+ mOldY = playerPos.y;
+ mOldTileX = getTileX();
+ mOldTileY = getTileY();
+}
+
+void LocalPlayer::targetMoved()
+{
+/*
+ if (mKeepAttacking)
+ {
+ if (mTarget && mServerAttack)
+ {
+ logger->log("LocalPlayer::targetMoved0");
+ if (!Client::limitPackets(PACKET_ATTACK))
+ return;
+ logger->log("LocalPlayer::targetMoved");
+ Net::getPlayerHandler()->attack(mTarget->getId(), mServerAttack);
+ }
+ }
+*/
+}
+
+int LocalPlayer::getPathLength(Being* being)
+{
+ if (!mMap || !being)
+ return 0;
+
+ const Vector &playerPos = getPosition();
+
+ Path debugPath = mMap->findPath((int) (playerPos.x - 16) / 32,
+ (int) (playerPos.y - 32) / 32,
+ being->getTileX(), being->getTileY(),
+ 0x00, 0);
+ return static_cast<int>(debugPath.size());
+}
+
+void LocalPlayer::attack2(Being *target, bool keep, bool dontChangeEquipment)
+{
+ if (!dontChangeEquipment && target)
+ changeEquipmentBeforeAttack(target);
+
+ if ((!target || getAttackType() == 0 || getAttackType() == 3)
+ || (withinAttackRange(target, true, 1)
+ && getPathLength(target) <= getAttackRange() + 1))
+ {
+ attack(target, keep);
+ if (getAttackType() == 2)
+ {
+ if (!target)
+ {
+ if (pickUpItems())
+ return;
+ }
+ else
+ {
+ pickUpItems(3);
+ }
+ }
+
+ }
+ else if (!mPickUpTarget)
+ {
+ if (getAttackType() == 2)
+ {
+ if (pickUpItems())
+ return;
+ }
+ setTarget(target);
+ if (target && target->getType() != Being::NPC)
+ {
+ mKeepAttacking = true;
+ if (mAttackWeaponType == 1)
+ moveToTarget();
+ else
+ moveToTarget(mAttackRange);
+ }
+ }
+}
+
+void LocalPlayer::setFollow(std::string player)
+{
+ mPlayerFollowed = player;
+ if (!mPlayerFollowed.empty())
+ debugMsg("Follow: " + player);
+ else
+ debugMsg("Follow canceled");
+}
+
+void LocalPlayer::setImitate(std::string player)
+{
+ mPlayerImitated = player;
+ if (!mPlayerImitated.empty())
+ debugMsg("Imitation: " + player);
+ else
+ debugMsg("Imitation canceled");
+}
+
+void LocalPlayer::cancelFollow()
+{
+ if (!mPlayerFollowed.empty())
+ debugMsg("Follow canceled");
+ if (!mPlayerImitated.empty())
+ debugMsg("Imitation canceled");
+ mPlayerFollowed = "";
+ mPlayerImitated = "";
+}
+
+void LocalPlayer::imitateEmote(Being* being, unsigned char action)
+{
+ if (!being)
+ return;
+
+ std::string player_imitated = getImitate();
+ if (!player_imitated.empty() && being->getName() == player_imitated)
+ emote(action);
+}
+
+void LocalPlayer::imitateAction(Being *being, Being::Action action)
+{
+ if (!being)
+ return;
+
+ std::string player_imitated = getImitate();
+ if (!player_imitated.empty() && being->getName() == player_imitated)
+ {
+ setAction(action);
+ Net::getPlayerHandler()->changeAction(action);
+ }
+}
+
+void LocalPlayer::imitateDirection(Being *being, unsigned char dir)
+{
+ if (!being)
+ return;
+
+ std::string player_imitated = getImitate();
+ if (!player_imitated.empty() && being->getName() == player_imitated)
+ {
+ if (!Client::limitPackets(PACKET_DIRECTION))
+ return;
+
+ if (mFollowMode == 2)
+ {
+ Uint8 dir2 = 0;
+ if (dir & Being::LEFT)
+ dir2 |= Being::RIGHT;
+ else if (dir & Being::RIGHT)
+ dir2 |= Being::LEFT;
+ if (dir & Being::UP)
+ dir2 |= Being::DOWN;
+ else if (dir & Being::DOWN)
+ dir2 |= Being::UP;
+
+ setDirection(dir2);
+ Net::getPlayerHandler()->setDirection(dir2);
+ }
+ else
+ {
+ setDirection(dir);
+ Net::getPlayerHandler()->setDirection(dir);
+ }
+ }
+}
+
+void LocalPlayer::imitateOutfit(Being *player, int sprite)
+{
+ if (!player)
+ return;
+
+ std::string player_imitated = getImitate();
+ if (mImitationMode == 1 && !player_imitated.empty()
+ && player->getName() == player_imitated)
+ {
+// std::string filename = ItemDB::get(
+// player->getId()).getSprite(mGender);
+// logger->log("LocalPlayer::imitateOutfit sprite: " + toString(sprite));
+// logger->log("LocalPlayer::imitateOutfit sprite: " + toString(player->getNumberOfLayers()));
+// logger->log("LocalPlayer::imitateOutfit spritecount: " + toString(player->getSpritesCount()));
+ if (sprite < 0 || sprite >= player->getNumberOfLayers())
+// if (sprite < 0 || sprite >= 20)
+ return;
+
+// logger->log("after check");
+ AnimatedSprite *equipmentSprite = dynamic_cast<AnimatedSprite *>(player
+ ->getSprite(sprite));
+
+ if (equipmentSprite)
+ {
+// logger->log("have equipmentSprite");
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ std::string path = equipmentSprite->getIdPath();
+ if (path.empty())
+ return;
+
+// logger->log("idPath: " + path);
+
+ Item *item = inv->findItemBySprite(path, player->getGender());
+// if (item)
+// {
+// logger->log("got item");
+// if (item->isEquipped())
+// logger->log("isEquipped");
+// }
+
+ if (item && !item->isEquipped())
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ else
+ {
+// logger->log("have unequip");
+
+ int equipmentSlot = Net::getInventoryHandler()
+ ->convertFromServerSlot(sprite);
+// logger->log("equipmentSlot: " + toString(equipmentSlot));
+ if (equipmentSlot == EQUIP_PROJECTILE_SLOT)
+ return;
+
+ Item *item = PlayerInfo::getEquipment(equipmentSlot);
+ if (item)
+ {
+// logger->log("unequiping");
+ Net::getInventoryHandler()->unequipItem(item);
+ }
+ }
+ }
+}
+
+void LocalPlayer::followMoveTo(Being *being, int x, int y)
+{
+ if (!mPlayerFollowed.empty() && being->getName() == mPlayerFollowed)
+ setDestination(x, y);
+}
+
+void LocalPlayer::followMoveTo(Being *being, int x1, int y1, int x2, int y2)
+{
+ if (!being)
+ return;
+
+ if (!mPlayerFollowed.empty() && being->getName() == mPlayerFollowed)
+ {
+ switch (mFollowMode)
+ {
+ case 0:
+ setDestination(x1, y1);
+ setNextDest(x2, y2);
+ break;
+ case 1:
+ if (x1 != x2 || y1 != y2)
+ {
+ setDestination(getTileX() + x2 - x1, getTileY() + y2 - y1);
+ setNextDest(getTileX() + x2 - x1, getTileY() + y2 - y1);
+ }
+ break;
+ case 2:
+ if (x1 != x2 || y1 != y2)
+ {
+ setDestination(getTileX() + x1 - x2, getTileY() + y1 - y2);
+ setNextDest(getTileX() + x1 - x2, getTileY() + y1 - y2);
+ }
+ break;
+ case 3:
+ if (!mTarget || mTarget->getName() != mPlayerFollowed)
+ {
+ if (actorSpriteManager)
+ {
+ Being *being = actorSpriteManager->findBeingByName(
+ mPlayerFollowed, Being::PLAYER);
+ setTarget(being);
+ }
+ }
+ moveToTarget();
+ setNextDest(x2, y2);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void LocalPlayer::setNextDest(int x, int y)
+{
+ mNextDestX = x;
+ mNextDestY = y;
+}
+
+bool LocalPlayer::allowAction()
+{
+ if (mIsServerBuggy)
+ {
+ if (mLastAction != -1)
+ return false;
+ mLastAction = tick_time;
+ }
+ return true;
+}
+
+bool LocalPlayer::allowMove()
+{
+ if (mIsServerBuggy)
+ {
+ if (mAction == MOVE)
+ return false;
+ }
+ return true;
+}
+
+void LocalPlayer::fixPos(int maxDist)
+{
+ if (!mCrossX && !mCrossY)
+ return;
+
+ int dx = abs(getTileX() - mCrossX);
+ int dy = abs(getTileY() - mCrossY);
+ int dest = (dx * dx) + (dy * dy);
+
+ if (dest > maxDist && mActivityTime
+ && (cur_time < mActivityTime || cur_time - mActivityTime > 2))
+ {
+ mActivityTime = cur_time;
+ moveTo(mCrossX, mCrossY);
+ }
+}
+
+void LocalPlayer::setRealPos(int x, int y)
+{
+ if (!mMap)
+ return;
+
+ SpecialLayer *layer = mMap->getTempLayer();
+ if (layer)
+ {
+ fixPos(1);
+
+ if ((mCrossX || mCrossY) && layer->getTile(mCrossX, mCrossY)
+ && layer->getTile(mCrossX, mCrossY)->getType() == MapItem::CROSS)
+ {
+ layer->setTile(mCrossX, mCrossY, MapItem::EMPTY);
+ }
+
+ if (!layer->getTile(x, y)
+ || layer->getTile(x, y)->getType() == MapItem::EMPTY)
+ {
+ if (getTileX() != x && getTileY() != y)
+ layer->setTile(x, y, MapItem::CROSS);
+ }
+
+ mCrossX = x;
+ mCrossY = y;
+ }
+}
+void LocalPlayer::fixAttackTarget()
+{
+ if (!mMap || !mTarget)
+ return;
+
+ if (!getAttackType() || !config.getBoolValue("autofixPos"))
+ return;
+
+ const Vector &playerPos = getPosition();
+ Path debugPath = mMap->findPath((int) (playerPos.x - 16) / 32,
+ (int) (playerPos.y - 32) / 32,
+ mTarget->getTileX(), mTarget->getTileY(),
+ 0x00, 0);
+ if (!debugPath.empty())
+ {
+ Path::const_iterator i = debugPath.begin();
+ moveTo((*i).x, (*i).y);
+ }
+}
+
+void LocalPlayer::respawn()
+{
+ naviageClean();
+}
+
+int LocalPlayer::getTargetTime()
+{
+ if (mTargetTime != -1)
+ return get_elapsed_time(mTargetTime);
+ else
+ return -1;
+}
+
+int LocalPlayer::getLevel() const
+{
+ return PlayerInfo::getAttribute(LEVEL);
+}
+
+void LocalPlayer::updateNavigateList()
+{
+ if (mMap)
+ {
+ std::map<std::string, Vector>::iterator iter =
+ mHomes.find(mMap->getProperty("_filename"));
+
+ if (iter != mHomes.end())
+ {
+ Vector pos = mHomes[(*iter).first];
+ mMap->addPortalTile("home", MapItem::HOME, pos.x, pos.y);
+ }
+ }
+}
+
+void LocalPlayer::waitFor(std::string nick)
+{
+ mWaitFor = nick;
+}
+
+void LocalPlayer::checkNewName(Being *being)
+{
+ if (!being)
+ return;
+
+ const std::string nick = being->getName();
+ if (being->getType() == ActorSprite::PLAYER)
+ {
+ const Guild *guild = getGuild();
+ if (guild)
+ {
+ const GuildMember *gm = guild->getMember(nick);
+ if (gm)
+ {
+ const int level = gm->getLevel();
+ if (level > 1 && being->getLevel() != level)
+ {
+ being->setLevel(level);
+ being->updateName();
+ }
+ }
+ }
+ if (chatWindow)
+ {
+ ChatTab *tab = chatWindow->getWhisperTab(nick);
+ if (tab)
+ tab->setTabColor(&Theme::getThemeColor(Theme::WHISPER));
+ }
+ }
+
+ if (!mWaitFor.empty() && mWaitFor == nick)
+ {
+ debugMsg(_("You see ") + mWaitFor);
+ sound.playGuiSfx("system/newmessage.ogg");
+ mWaitFor = "";
+ }
+}
+
+void AwayListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok" && player_node && player_node->getAwayMode())
+ {
+ player_node->changeAwayMode();
+ if (outfitWindow)
+ outfitWindow->unwearAwayOutfit();
+ if (miniStatusWindow)
+ miniStatusWindow->updateStatus();
+ }
+} \ No newline at end of file
diff --git a/src/localplayer.h b/src/localplayer.h
new file mode 100644
index 000000000..189483e97
--- /dev/null
+++ b/src/localplayer.h
@@ -0,0 +1,577 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LOCALPLAYER_H
+#define LOCALPLAYER_H
+
+#include "actorspritelistener.h"
+#include "being.h"
+#include "client.h"
+#include "game.h"
+#include "listener.h"
+
+#include "gui/userpalette.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <memory>
+#include <vector>
+
+class ChatTab;
+class FloorItem;
+class ImageSet;
+class Item;
+class Map;
+class OkDialog;
+struct SkillInfo;
+
+class AwayListener : public gcn::ActionListener
+{
+ public:
+ void action(const gcn::ActionEvent &event);
+};
+
+/**
+ * The local player character.
+ */
+class LocalPlayer : public Being, public ActorSpriteListener,
+ public Mana::Listener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ LocalPlayer(int id = 65535, int subtype = 0);
+
+ /**
+ * Destructor.
+ */
+ ~LocalPlayer();
+
+ virtual void logic();
+
+ virtual void setAction(Action action, int attackType = 0);
+
+ /**
+ * Compute the next pathnode location when walking using keyboard.
+ * used by nextTile().
+ */
+ Position getNextWalkPosition(unsigned char dir);
+
+ /**
+ * Adds a new tile to the path when walking.
+ * @note Eathena
+ * Also, when specified, it picks up an item at the end of a path
+ * or attack target.
+ */
+ virtual void nextTile()
+ { nextTile(0); }
+
+ virtual void nextTile(unsigned char dir);
+
+ /**
+ * Check the player has permission to invite users to specific guild
+ */
+ bool checkInviteRights(const std::string &guildName);
+
+ /**
+ * Invite a player to join guild
+ */
+ void inviteToGuild(Being *being);
+
+// void clearInventory();
+// void setInvItem(int index, int id, int amount);
+
+ bool pickUp(FloorItem *item);
+
+ /**
+ * Called when an ActorSprite has been destroyed.
+ * @param actorSprite the ActorSprite being destroyed.
+ */
+ void actorSpriteDestroyed(const ActorSprite &actorSprite);
+
+ /**
+ * Sets the attack range.
+ */
+ void setAttackRange(int range) { mAttackRange = range; }
+
+ /**
+ * Gets the attack range.
+ */
+ int getAttackRange();
+
+ void attack(Being *target = NULL, bool keep = false,
+ bool dontChangeEquipment = false);
+
+ void attack2(Being *target = NULL, bool keep = false,
+ bool dontChangeEquipment = false);
+
+ void setGMLevel(int level);
+
+ int getGMLevel()
+ { return mGMLevel; }
+
+ void stopAttack();
+
+ /**
+ * Overridden to do nothing. The attacks of the local player are
+ * displayed as soon as the player attacks, not when the server says
+ * the player does.
+ *
+ * @param victim the victim being
+ * @param damage the amount of damage dealt (0 means miss)
+ * @param type the attack type
+ */
+ //virtual void handleAttack(Being *victim, int damage, AttackType type) {}
+ virtual void handleAttack()
+ { }
+
+ /**
+ * Returns the current target of the player. Returns 0 if no being is
+ * currently targeted.
+ */
+ Being *getTarget() const;
+
+ /**
+ * Sets the target being of the player.
+ */
+ void setTarget(Being *target);
+
+ /**
+ * Sets a new destination for this being to walk to.
+ */
+ virtual void setDestination(int x, int y);
+
+ /**
+ * Sets a new direction to keep walking in.
+ */
+ void setWalkingDir(unsigned char dir);
+
+ /**
+ * Gets the walking direction
+ */
+ unsigned char getWalkingDir() const
+ { return mWalkingDir; }
+
+ /**
+ * Sets going to being to attack
+ */
+ void setGotoTarget(Being *target);
+
+ /**
+ * Returns whether the target is in range to attack
+ */
+ bool withinAttackRange(Being *target, bool fixDistance = false,
+ int addRange = 0);
+
+ /**
+ * Stops the player dead in his tracks
+ */
+ void stopWalking(bool sendToServer = true);
+
+ bool toggleSit();
+ bool updateSit();
+ bool emote(Uint8 emotion);
+
+ /**
+ * Shows item pickup notifications.
+ */
+ void pickedUp(const ItemInfo &itemInfo, int amount);
+
+ int getLevel() const;
+
+ int getTargetTime();
+
+// int getSkillPoints() const
+// { return mSkillPoints; }
+
+// void setSkillPoints(int points);
+
+ /** Tells that the path has been set by mouse. */
+ void pathSetByMouse()
+ { mPathSetByMouse = true; }
+
+ /** Tells if the path has been set by mouse. */
+ bool isPathSetByMouse() const
+ { return mPathSetByMouse; }
+
+ int getInvertDirection()
+ { return mInvertDirection; }
+
+ void setInvertDirection(int n)
+ { mInvertDirection = n; }
+
+ void invertDirection();
+
+ int getAttackWeaponType()
+ { return mAttackWeaponType; }
+
+ int getAttackType()
+ { return mAttackType; }
+
+ int getFollowMode()
+ { return mFollowMode; }
+
+ int getImitationMode()
+ { return mImitationMode; }
+
+ void changeAttackWeaponType();
+
+ void changeAttackType();
+
+ void changeFollowMode();
+
+ void changeImitationMode();
+
+ void changePickUpType();
+
+ int getCrazyMoveType()
+ { return mCrazyMoveType ; }
+
+ int getPickUpType()
+ { return mPickUpType ; }
+
+ int getQuickDropCounter()
+ { return mQuickDropCounter ; }
+
+ void changeQuickDropCounter();
+
+ int getMoveState()
+ { return mMoveState ; }
+
+ void setMoveState(int n)
+ { mMoveState = n ; }
+
+ void switchMagicAttack();
+
+ int getMagicAttackType()
+ { return mMagicAttackType ; }
+
+ int getMoveToTargetType()
+ { return mMoveToTargetType ; }
+
+ int getDisableGameModifiers()
+ { return mDisableGameModifiers ; }
+
+ int getPingTime()
+ { return mPingTime ; }
+
+ void tryPingRequest();
+
+ void changeMoveToTargetType();
+
+ void switchGameModifiers();
+
+ void magicAttack();
+
+ void specialMove(unsigned char direction);
+
+ void moveByDirection(unsigned char dir);
+
+ bool pickUpItems(int pickUpType = 0);
+
+ void changeCrazyMoveType();
+
+ void crazyMove();
+
+ void moveTo(int x, int y);
+
+ void move(int dX, int dY);
+
+ void moveToTarget(unsigned int dist = -1);
+
+ void moveToHome();
+
+ void debugMsg(std::string str);
+
+// int getSkillLv(int id);
+
+ bool isReachable(int x, int y, int maxCost = 0);
+
+ bool isReachable(Being *being, int maxCost = 0);
+
+ void setHome();
+
+ void pingRequest();
+
+ void pingResponse();
+
+ void changeAwayMode();
+
+ bool getAwayMode()
+ { return mAwayMode; }
+
+ void setAway(const std::string &message);
+
+ void afkRespond(ChatTab *tab, const std::string &nick);
+
+ void navigateTo(int x, int y);
+
+ void navigateTo(Being *being);
+
+ void naviageClean();
+
+ void updateCoords();
+
+ void imitateEmote(Being* being, unsigned char emote);
+
+ void imitateAction(Being *being, Being::Action action);
+
+ void imitateDirection(Being *being, unsigned char dir);
+
+ void imitateOutfit(Being *player, int sprite = -1);
+
+ void followMoveTo(Being *being, int x, int y);
+
+ void followMoveTo(Being *being, int x1, int y1, int x2, int y2);
+
+ bool allowAction();
+
+ bool allowMove();
+
+ void setRealPos(int x, int y);
+
+ bool isServerBuggy()
+ { return mIsServerBuggy; }
+
+ void fixPos(int maxDist = 1);
+
+ /**
+ * Sets the map the being is on
+ */
+ void setMap(Map *map);
+
+ void addMessageToQueue(const std::string &message,
+ int color = UserPalette::EXP_INFO);
+
+ /**
+ * Called when a option (set with config.addListener()) is changed
+ */
+ void optionChanged(const std::string &value);
+
+ void event(Channels channel, const Mana::Event &event);
+
+ /**
+ * set a following player.
+ */
+ void setFollow(std::string player);
+
+ /**
+ * set an imitation player.
+ */
+ void setImitate(std::string player);
+
+ /**
+ * setting the next destination of the following, in case of warp
+ */
+ void setNextDest(int x, int y);
+
+
+ int getNextDestX() const
+ { return mNextDestX; }
+
+ int getNextDestY() const
+ { return mNextDestY; }
+
+ void respawn();
+
+ FloorItem *getPickUpTarget()
+ { return mPickUpTarget; }
+
+ void unSetPickUpTarget()
+ { mPickUpTarget = 0; }
+
+ /**
+ * Stop following a player.
+ */
+ void cancelFollow();
+
+ /**
+ * Get the playername followed by the current player.
+ */
+ std::string getFollow() const
+ { return mPlayerFollowed; }
+
+ /**
+ * Get the playername imitated by the current player.
+ */
+ std::string getImitate() const
+ { return mPlayerImitated; }
+
+ /**
+ * Tells the engine whether to check
+ * if the Player Name is to be displayed.
+ */
+ void setCheckNameSetting(bool checked)
+ { mUpdateName = checked; }
+
+ /**
+ * Gets if the engine has to check
+ * if the Player Name is to be displayed.
+ */
+ bool getCheckNameSetting() const
+ { return mUpdateName; }
+
+ void fixAttackTarget();
+
+ void updateNavigateList();
+
+ int getPathLength(Being* being);
+
+ void targetMoved();
+
+ void setLastHitFrom(std::string n)
+ { mLastHitFrom = n; }
+
+ void waitFor(std::string nick);
+
+ void checkNewName(Being *being);
+
+ protected:
+ /** Whether or not the name settings have changed */
+ bool mUpdateName;
+
+ virtual void handleStatusEffect(StatusEffect *effect, int effectId);
+
+ void startWalking(unsigned char dir);
+
+ void changeEquipmentBeforeAttack(Being* target);
+
+ void tryMagic(std::string spell, int baseMagic,
+ int schoolMagic, int mana);
+
+ void crazyMove1();
+ void crazyMove2();
+ void crazyMove3();
+ void crazyMove4();
+ void crazyMove5();
+ void crazyMove6();
+ void crazyMove7();
+ void crazyMove8();
+ void crazyMove9();
+ void crazyMoveA();
+
+ void loadHomes();
+
+ void saveHomes();
+
+ bool mInStorage; /**< Whether storage is currently accessible */
+
+ int mAttackRange;
+
+ int mTargetTime; /** How long the being has been targeted **/
+ int mLastTarget; /** Time stamp of last targeting action,
+ -1 if none. */
+
+ int mGMLevel;
+
+ //move type
+ unsigned int mInvertDirection;
+ //crazy move type
+ unsigned int mCrazyMoveType;
+ //crazy move state
+ unsigned int mCrazyMoveState;
+ //attack weapon type
+ unsigned int mAttackWeaponType;
+ //quick drop counter
+ unsigned int mQuickDropCounter;
+ //move state. used if mInvertDirection == 2
+ unsigned int mMoveState;
+ //temporary disable crazy moves in moves
+ bool mDisableCrazyMove;
+ //pick up type 1x1, normal aka 2x1, forward aka 2x3, 3x3, 3x3 + 1
+ unsigned int mPickUpType;
+ //magic attack type
+ unsigned int mMagicAttackType;
+ //type how move to target
+ unsigned int mMoveToTargetType;
+ unsigned int mAttackType;
+ unsigned int mFollowMode;
+ unsigned int mImitationMode;
+
+ bool mDisableGameModifiers;
+
+ int mLastTargetX;
+ int mLastTargetY;
+
+ std::map<std::string, Vector> mHomes;
+
+ Being *mTarget;
+
+ /** Follow system **/
+ std::string mPlayerFollowed;
+ std::string mPlayerImitated;
+ int mNextDestX;
+ int mNextDestY;
+
+ FloorItem *mPickUpTarget;
+
+ bool mGoingToTarget;
+ bool mKeepAttacking; /** Whether or not to continue to attack */
+ int mLastAction; /**< Time stamp of the last action, -1 if none.*/
+ unsigned char mWalkingDir; /**< The direction the player is
+ walking in. */
+ bool mPathSetByMouse; /**< Tells if the path was set using mouse */
+
+ std::vector<int> mStatusEffectIcons;
+
+ int mLocalWalkTime; /**< Timestamp used to control keyboard walk
+ messages flooding */
+
+ typedef std::pair<std::string, int> MessagePair;
+ /** Queued messages*/
+ std::list<MessagePair> mMessages;
+ int mMessageTime;
+ AwayListener *mAwayListener;
+ OkDialog *mAwayDialog;
+
+ int mPingSendTick;
+ bool mWaitPing;
+ int mPingTime;
+ int mAfkTime;
+ bool mAwayMode;
+
+ bool mShowNavigePath;
+ bool mIsServerBuggy;
+ bool mSyncPlayerMove;
+ bool mDrawPath;
+ bool mAttackMoving;
+ int mActivityTime;
+ int mNavigateX;
+ int mNavigateY;
+ int mNavigateId;
+ int mCrossX;
+ int mCrossY;
+ int mOldX;
+ int mOldY;
+ int mOldTileX;
+ int mOldTileY;
+ Path mNavigatePath;
+
+ bool mTargetDeadPlayers;
+ bool mServerAttack;
+ std::string mLastHitFrom;
+ std::string mWaitFor;
+};
+
+extern LocalPlayer *player_node;
+
+#endif
diff --git a/src/log.cpp b/src/log.cpp
new file mode 100644
index 000000000..bf8519443
--- /dev/null
+++ b/src/log.cpp
@@ -0,0 +1,213 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <iostream>
+#include <sstream>
+
+#include "log.h"
+
+#include "configuration.h"
+
+#include "gui/widgets/chattab.h"
+
+#ifdef WIN32
+#include <windows.h>
+#elif defined __APPLE__
+#include <Carbon/Carbon.h>
+#elif __linux__ || __linux
+#include <stdlib.h>
+#endif
+
+#include <sys/time.h>
+
+Logger::Logger():
+ mLogToStandardOut(true),
+ mChatWindow(NULL),
+ mDebugLog(false)
+{
+}
+
+Logger::~Logger()
+{
+ if (mLogFile.is_open())
+ {
+ mLogFile.close();
+ }
+}
+
+void Logger::setLogFile(const std::string &logFilename)
+{
+ if (mLogFile.is_open())
+ mLogFile.close();
+
+ mLogFile.open(logFilename.c_str(), std::ios_base::trunc);
+
+ if (!mLogFile.is_open())
+ {
+ std::cout << "Warning: error while opening " << logFilename <<
+ " for writing.\n";
+ }
+}
+
+void Logger::log(std::string str)
+{
+ log("%s", str.c_str());
+}
+
+void Logger::dlog(std::string str)
+{
+ if (!mDebugLog)
+ return;
+
+ // Get the current system time
+ timeval tv;
+ gettimeofday(&tv, NULL);
+
+ // Print the log entry
+ std::stringstream timeStr;
+ timeStr << "["
+ << ((((tv.tv_sec / 60) / 60) % 24 < 10) ? "0" : "")
+ << (int)(((tv.tv_sec / 60) / 60) % 24)
+ << ":"
+ << (((tv.tv_sec / 60) % 60 < 10) ? "0" : "")
+ << (int)((tv.tv_sec / 60) % 60)
+ << ":"
+ << ((tv.tv_sec % 60 < 10) ? "0" : "")
+ << (int)(tv.tv_sec % 60)
+ << "."
+ << (((tv.tv_usec / 10000) % 100) < 10 ? "0" : "")
+ << (int)((tv.tv_usec / 10000) % 100)
+ << "] ";
+
+ if (mLogFile.is_open())
+ mLogFile << timeStr.str() << str << std::endl;
+
+ if (mLogToStandardOut)
+ std::cout << timeStr.str() << str << std::endl;
+
+ if (mChatWindow && debugChatTab)
+ debugChatTab->chatLog(str, BY_LOGGER);
+}
+
+void Logger::log1(const char *buf)
+{
+ // Get the current system time
+ timeval tv;
+ gettimeofday(&tv, NULL);
+
+ // Print the log entry
+ std::stringstream timeStr;
+ timeStr << "["
+ << ((((tv.tv_sec / 60) / 60) % 24 < 10) ? "0" : "")
+ << (int)(((tv.tv_sec / 60) / 60) % 24)
+ << ":"
+ << (((tv.tv_sec / 60) % 60 < 10) ? "0" : "")
+ << (int)((tv.tv_sec / 60) % 60)
+ << ":"
+ << ((tv.tv_sec % 60 < 10) ? "0" : "")
+ << (int)(tv.tv_sec % 60)
+ << "."
+ << (((tv.tv_usec / 10000) % 100) < 10 ? "0" : "")
+ << (int)((tv.tv_usec / 10000) % 100)
+ << "] ";
+
+ if (mLogFile.is_open())
+ mLogFile << timeStr.str() << buf << std::endl;
+
+ if (mLogToStandardOut)
+ std::cout << timeStr.str() << buf << std::endl;
+
+ if (mChatWindow && debugChatTab)
+ debugChatTab->chatLog(buf, BY_LOGGER);
+}
+
+void Logger::log(const char *log_text, ...)
+{
+ unsigned int size = 1024;
+ char* buf = 0;
+ if (strlen(log_text) * 3 > size)
+ size = (unsigned)strlen(log_text) * 3;
+
+ buf = new char[size];
+ va_list ap;
+
+ // Use a temporary buffer to fill in the variables
+ va_start(ap, log_text);
+ vsprintf(buf, log_text, ap);
+ va_end(ap);
+
+ // Get the current system time
+ timeval tv;
+ gettimeofday(&tv, NULL);
+
+ // Print the log entry
+ std::stringstream timeStr;
+ timeStr << "["
+ << ((((tv.tv_sec / 60) / 60) % 24 < 10) ? "0" : "")
+ << (int)(((tv.tv_sec / 60) / 60) % 24)
+ << ":"
+ << (((tv.tv_sec / 60) % 60 < 10) ? "0" : "")
+ << (int)((tv.tv_sec / 60) % 60)
+ << ":"
+ << ((tv.tv_sec % 60 < 10) ? "0" : "")
+ << (int)(tv.tv_sec % 60)
+ << "."
+ << (((tv.tv_usec / 10000) % 100) < 10 ? "0" : "")
+ << (int)((tv.tv_usec / 10000) % 100)
+ << "] ";
+
+ if (mLogFile.is_open())
+ mLogFile << timeStr.str() << buf << std::endl;
+
+ if (mLogToStandardOut)
+ std::cout << timeStr.str() << buf << std::endl;
+
+ if (mChatWindow && debugChatTab)
+ debugChatTab->chatLog(buf, BY_LOGGER);
+
+ // Delete temporary buffer
+ delete[] buf;
+}
+
+void Logger::error(const std::string &error_text)
+{
+ log("Error: %s", error_text.c_str());
+#ifdef WIN32
+ MessageBox(NULL, error_text.c_str(), "Error", MB_ICONERROR | MB_OK);
+#elif defined __APPLE__
+ Str255 msg;
+ CFStringRef error;
+ error = CFStringCreateWithCString(NULL,
+ error_text.c_str(),
+ kCFStringEncodingMacRoman);
+ CFStringGetPascalString(error, msg, 255, kCFStringEncodingMacRoman);
+ StandardAlert(kAlertStopAlert,
+ "\pError",
+ (ConstStr255Param) msg, NULL, NULL);
+#elif defined __linux__ || __linux
+ std::cerr << "Error: " << error_text << std::endl;
+ std::string msg = "xmessage \"" + error_text + "\"";
+ system(msg.c_str());
+#else
+ std::cerr << "Error: " << error_text << std::endl;
+#endif
+ exit(1);
+}
diff --git a/src/log.h b/src/log.h
new file mode 100644
index 000000000..5f0a6b60d
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,109 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef _LOG_H
+#define _LOG_H
+
+#include "main.h"
+#include <fstream>
+
+class ChatWindow;
+
+#ifdef ENABLEDEBUGLOG
+#define DEBUGLOG(msg) logger->dlog(msg)
+#else
+#define DEBUGLOG(msg) {}
+#endif
+
+/**
+ * The Log Class : Useful to write debug or info messages
+ */
+class Logger
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Logger();
+
+ /**
+ * Destructor, closes log file.
+ */
+ ~Logger();
+
+ /**
+ * Sets the file to log to and opens it
+ */
+ void setLogFile(const std::string &logFilename);
+
+ /**
+ * Sets whether the log should be written to standard output.
+ */
+ void setLogToStandardOut(bool value) { mLogToStandardOut = value; }
+
+ /**
+ * Enables logging to chat window
+ */
+ void setChatWindow(ChatWindow *window) { mChatWindow = window; }
+
+ /**
+ * Enters a message in the log. The message will be timestamped.
+ */
+ void log(const char *log_text, ...)
+#ifdef __GNUC__
+ __attribute__((__format__(__printf__, 2, 3)))
+#endif
+ ;
+
+ /**
+ * Enters a message in the log. The message will be timestamped.
+ */
+ void log1(const char *log_text);
+
+ /**
+ * Enters a message in the log. The message will be timestamped.
+ */
+ void log(std::string str);
+
+ /**
+ * Enters debug message in the log. The message will be timestamped.
+ */
+ void dlog(std::string str);
+
+ void setDebugLog(bool n)
+ { mDebugLog = n; }
+
+ /**
+ * Log an error and quit. The error will pop-up on Windows and Mac, and
+ * will be printed to standard error everywhere else.
+ */
+ void error(const std::string &error_text) __attribute__ ((noreturn));
+
+ private:
+ std::ofstream mLogFile;
+ bool mLogToStandardOut;
+ ChatWindow *mChatWindow;
+ bool mDebugLog;
+};
+
+extern Logger *logger;
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 000000000..7cddd633b
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,261 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "main.h"
+
+#include "utils/gettext.h"
+
+#include "client.h"
+#include "log.h"
+
+#include <libxml/parser.h>
+
+#include <getopt.h>
+#include <iostream>
+#include <physfs.h>
+
+#ifdef __MINGW32__
+#include <windows.h>
+#endif
+
+static void printHelp()
+{
+ using std::endl;
+
+ std::cout
+ << _("manaplus [options] [mana-file]") << endl << endl
+ << _("[mana-file] : The mana file is an XML file (.mana)") << endl
+ << _(" used to set custom parameters") << endl
+ << _(" to the mana client.")
+ << endl << endl
+ << _("Options:") << endl
+ << _(" -l --log-file : Log file to use") << endl
+ << _(" -L --chat-log-dir : Chat log dir to use") << endl
+ << _(" -v --version : Display the version") << endl
+ << _(" -h --help : Display this help") << endl
+ << _(" -C --config-dir : Configuration directory to use") << endl
+ << _(" -U --username : Login with this username") << endl
+ << _(" -P --password : Login with this password") << endl
+ << _(" -c --character : Login with this character") << endl
+ << _(" -s --server : Login server name or IP") << endl
+ << _(" -p --port : Login server port") << endl
+ << _(" --update-host : Use this update host") << endl
+ << _(" -D --default : Choose default character server and "
+ "character") << endl
+ << _(" -u --skip-update : Skip the update downloads") << endl
+ << _(" -d --data : Directory to load game "
+ "data from") << endl
+ << _(" -L --localdata-dir : Directory to use as local data"
+ " directory") << endl
+ << _(" --screenshot-dir : Directory to store screenshots") << endl
+ << _(" --safemode : Start game in safe mode") << endl
+#ifdef USE_OPENGL
+ << _(" --no-opengl : Disable OpenGL for this session") << endl
+#endif
+ ;
+}
+
+static void printVersion()
+{
+ std::cout << strprintf("ManaPlus client %s", FULL_VERSION) << std::endl;
+}
+
+static void parseOptions(int argc, char *argv[], Client::Options &options)
+{
+ const char *optstring = "hvud:U:P:Dc:p:l:L:C:";
+
+ const struct option long_options[] =
+ {
+ { "config-dir", required_argument, 0, 'C' },
+ { "data", required_argument, 0, 'd' },
+ { "default", no_argument, 0, 'D' },
+ { "password", required_argument, 0, 'P' },
+ { "character", required_argument, 0, 'c' },
+ { "help", no_argument, 0, 'h' },
+ { "localdata-dir", required_argument, 0, 'L' },
+ { "update-host", required_argument, 0, 'H' },
+ { "port", required_argument, 0, 'p' },
+ { "server", required_argument, 0, 's' },
+ { "skip-update", no_argument, 0, 'u' },
+ { "username", required_argument, 0, 'U' },
+ { "no-opengl", no_argument, 0, 'O' },
+ { "chat-log-dir", required_argument, 0, 'l' },
+ { "version", no_argument, 0, 'v' },
+ { "log-file", required_argument, 0, 'l' },
+ { "chat-log-dir", required_argument, 0, 'L' },
+ { "screenshot-dir", required_argument, 0, 'i' },
+ { "safemode", no_argument, 0, 'm' },
+ { 0, 0, 0, 0 }
+ };
+
+ while (optind < argc)
+ {
+ int result = getopt_long(argc, argv, optstring, long_options, NULL);
+
+ if (result == -1)
+ break;
+
+ switch (result)
+ {
+ case 'C':
+ options.configDir = optarg;
+ break;
+ case 'd':
+ options.dataPath = optarg;
+ break;
+ case 'D':
+ options.chooseDefault = true;
+ break;
+ case '?': // Unknown option
+ case ':': // Missing argument
+ case 'h':
+ options.printHelp = true;
+ break;
+ case 'H':
+ options.updateHost = optarg;
+ break;
+ case 'c':
+ options.character = optarg;
+ break;
+ case 'P':
+ options.password = optarg;
+ break;
+ case 's':
+ options.serverName = optarg;
+ break;
+ case 'p':
+ options.serverPort = (short) atoi(optarg);
+ break;
+ case 'u':
+ options.skipUpdate = true;
+ break;
+ case 'U':
+ options.username = optarg;
+ break;
+ case 'v':
+ options.printVersion = true;
+ break;
+ case 'S':
+ options.localDataDir = optarg;
+ break;
+ case 'O':
+ options.noOpenGL = true;
+ break;
+ case 'l':
+ options.logFileName = std::string(optarg);
+ break;
+ case 'L':
+ options.chatLogDir = std::string(optarg);
+ case 'i':
+ options.screenshotDir = optarg;
+ break;
+ case 'm':
+ options.safeMode = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // when there are still options left use the last
+ // one as branding file
+ if (optind < argc)
+ {
+ options.brandingPath = argv[optind];
+ }
+}
+
+#ifdef WIN32
+extern "C" char const *_nl_locale_name_default(void);
+#endif
+
+static void initInternationalization()
+{
+#if ENABLE_NLS
+#ifdef WIN32
+ putenv(("LANG=" + std::string(_nl_locale_name_default())).c_str());
+ // mingw doesn't like LOCALEDIR to be defined for some reason
+ bindtextdomain("manaplus", "translations/");
+#else
+ bindtextdomain("manaplus", LOCALEDIR);
+#endif
+ setlocale(LC_MESSAGES, "");
+ bind_textdomain_codeset("manaplus", "UTF-8");
+ textdomain("manaplus");
+#endif
+}
+
+static void xmlNullLogger(void *ctx _UNUSED_, const char *msg _UNUSED_, ...)
+{
+ // Does nothing, that's the whole point of it
+}
+
+// Initialize libxml2 and check for potential ABI mismatches between
+// compiled version and the shared library actually used.
+static void initXML()
+{
+ xmlInitParser();
+ LIBXML_TEST_VERSION;
+
+ // Suppress libxml2 error messages
+ xmlSetGenericErrorFunc(NULL, xmlNullLogger);
+}
+
+
+int main(int argc, char *argv[])
+{
+#if defined(__MINGW32__)
+ // load mingw crash handler. Won't fail if dll is not present.
+ // may load libray from current dir, it may not same as program dir
+ LoadLibrary("exchndl.dll");
+#endif
+
+ // Parse command line options
+ Client::Options options;
+ parseOptions(argc, argv, options);
+
+ if (options.printHelp)
+ {
+ printHelp();
+ return 0;
+ }
+ else if (options.printVersion)
+ {
+ printVersion();
+ return 0;
+ }
+
+ initInternationalization();
+
+ // Initialize PhysicsFS
+ if (!PHYSFS_init(argv[0]))
+ {
+ std::cout << "Error while initializing PhysFS: "
+ << PHYSFS_getLastError() << std::endl;
+ return 1;
+ }
+ atexit((void(*)()) PHYSFS_deinit);
+
+ initXML();
+
+ Client client(options);
+ return client.exec();
+}
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 000000000..480c9d374
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,109 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MAIN_H
+#define MAIN_H
+
+/**
+ * \mainpage
+ *
+ * \section Introduction Introduction
+ *
+ * This is the documentation for the Mana client (http://manasource.org). It is
+ * always a work in progress, with the intent to make it easier for new
+ * developers to grow familiar with the source code.
+ *
+ * \section General General information
+ *
+ * During the game, the current Map is displayed by the main Viewport, which
+ * is the bottom-most widget in the WindowContainer. Aside the viewport, the
+ * window container keeps track of all the \link Window Windows\endlink
+ * displayed during the game. It is the <i>top</i> widget for Guichan.
+ *
+ * A Map is composed of several layers of \link Image Images\endlink (tiles),
+ * a layer with collision information and \link Sprite Sprites\endlink. The
+ * sprites define the visible part of \link Being Beings\endlink and
+ * \link FloorItem FloorItems\endlink, they are drawn from top to bottom
+ * by the map, interleaved with the tiles in the fringe layer.
+ *
+ * The client supports two servers, \link EAthena eAthena\endlink (the TMW
+ * version) and the \link ManaServ Mana server\endlink. To achieve this, the
+ * \link Net network communication layer\endlink is abstracted in many
+ * different interfaces, which have different implementations for each server.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#elif defined WIN32
+#include "winver.h"
+#elif defined __APPLE__
+#define PACKAGE_VERSION "1.0.0"
+#endif
+
+#if defined __APPLE__
+#define PACKAGE_OS "Apple"
+#elif defined __FreeBSD__ || defined __DragonFly__
+#define PACKAGE_OS "FreeBSD"
+#elif defined __NetBSD__
+#define PACKAGE_OS "NetBSD"
+#elif defined __OpenBSD__
+#define PACKAGE_OS "OpenBSD"
+#elif defined __linux__ || defined __linux
+#define PACKAGE_OS "Linux"
+#elif defined __GNU__
+#define PACKAGE_OS "GNU Hurd"
+#elif defined WIN32 || defined _WIN32 || defined __WIN32__ || defined __NT__ \
+ || defined WIN64 || defined _WIN64 || defined __WIN64__ \
+ || defined __MINGW32__ || defined _MSC_VER
+#define PACKAGE_OS "Windows"
+#else
+#define PACKAGE_OS "Other"
+#endif
+
+
+#define ENABLEDEBUGLOG 1
+//define DEBUG_LEAKS
+//define DEBUG_CONFIG 1
+//define DEBUG_FONT 1
+//define DEBUG_FONT_COUNTERS 1
+//define DEBUG_ALPHA_CACHE 1
+
+#define SMALL_VERSION "1.0.12.26"
+#define CHECK_VERSION "01.00.12.26"
+
+
+#define PACKAGE_EXTENDED_VERSION "ManaPlus (" PACKAGE_OS \
+"; %s; 4144 v" SMALL_VERSION ")"
+#define PACKAGE_VERSION_4144 "ManaPlus 4144-" SMALL_VERSION ""
+
+#define FULL_VERSION "ManaPlus 4144 " SMALL_VERSION " " PACKAGE_OS
+
+#ifndef PKG_DATADIR
+#define PKG_DATADIR ""
+#endif
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+#endif
diff --git a/src/mana.rc b/src/mana.rc
new file mode 100644
index 000000000..b7720e2cc
--- /dev/null
+++ b/src/mana.rc
@@ -0,0 +1,23 @@
+#include <windows.h> // include for version info constants
+
+#include "winver.h"
+
+A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "../data/icons/manaplus.ico"
+
+1 VERSIONINFO
+FILEVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
+PRODUCTVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
+//FILETYPE VFT_APP
+{
+ BLOCK "StringFileInfo" {
+ BLOCK "040904E4" {
+ VALUE "CompanyName", "The Mana Development Team"
+ VALUE "FileVersion", PACKAGE_VERSION "4144"
+ VALUE "FileDescription", "ManaPlus"
+ VALUE "LegalCopyright", "2004-2010 (C)"
+ VALUE "OriginalFilename", "manaplus.exe"
+ VALUE "ProductName", "ManaPlus MMORPG Client"
+ VALUE "ProductVersion", PACKAGE_VERSION "4144"
+ }
+ }
+}
diff --git a/src/map.cpp b/src/map.cpp
new file mode 100644
index 000000000..5dd933f0b
--- /dev/null
+++ b/src/map.cpp
@@ -0,0 +1,1654 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "map.h"
+
+#include "actorspritemanager.h"
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "log.h"
+#include "particle.h"
+#include "simpleanimation.h"
+#include "tileset.h"
+#include "localplayer.h"
+
+#include "resources/ambientlayer.h"
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+#include "gui/truetypefont.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "utils/dtor.h"
+#include "utils/mkdir.h"
+#include "utils/stringutils.h"
+
+#include <queue>
+
+#include <sys/stat.h>
+
+bool actorCompare(const Actor *a, const Actor *b);
+
+/**
+ * A location on a tile map. Used for pathfinding, open list.
+ */
+struct Location
+{
+ /**
+ * Constructor.
+ */
+ Location(int px, int py, MetaTile *ptile):
+ x(px), y(py), tile(ptile)
+ {}
+
+ /**
+ * Comparison operator.
+ */
+ bool operator< (const Location &loc) const
+ {
+ return tile->Fcost > loc.tile->Fcost;
+ }
+
+ int x, y;
+ MetaTile *tile;
+};
+
+TileAnimation::TileAnimation(Animation *ani):
+ mLastImage(NULL)
+{
+ mAnimation = new SimpleAnimation(ani);
+}
+
+TileAnimation::~TileAnimation()
+{
+ delete mAnimation;
+ mAnimation = 0;
+}
+
+void TileAnimation::update(int ticks)
+{
+ if (!mAnimation)
+ return;
+
+ // update animation
+ mAnimation->update(ticks);
+
+ // exchange images
+ Image *img = mAnimation->getCurrentImage();
+ if (img != mLastImage)
+ {
+ for (std::list<std::pair<MapLayer*, int> >::iterator i =
+ mAffected.begin(); i != mAffected.end(); i++)
+ {
+ i->first->setTile(i->second, img);
+ }
+ mLastImage = img;
+ }
+}
+
+MapLayer::MapLayer(int x, int y, int width, int height, bool isFringeLayer):
+ mX(x), mY(y),
+ mWidth(width), mHeight(height),
+ mIsFringeLayer(isFringeLayer),
+ mHighlightAttackRange(config.getBoolValue("highlightAttackRange"))
+{
+ const int size = mWidth * mHeight;
+ mTiles = new Image*[size];
+
+ std::fill_n(mTiles, size, (Image*) 0);
+
+ config.addListener("highlightAttackRange", this);
+}
+
+MapLayer::~MapLayer()
+{
+ config.removeListener("highlightAttackRange", this);
+ delete[] mTiles;
+}
+
+void MapLayer::optionChanged(const std::string &value)
+{
+ if (value == "highlightAttackRange")
+ {
+ mHighlightAttackRange =
+ config.getBoolValue("highlightAttackRange");
+ }
+}
+
+void MapLayer::setTile(int x, int y, Image *img)
+{
+ setTile(x + y * mWidth, img);
+}
+
+Image* MapLayer::getTile(int x, int y) const
+{
+ return mTiles[x + y * mWidth];
+}
+
+void MapLayer::draw(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY,
+ const Actors &actors, int debugFlags) const
+{
+ if (!player_node)
+ return;
+
+ startX -= mX;
+ startY -= mY;
+ endX -= mX;
+ endY -= mY;
+
+ if (startX < 0)
+ startX = 0;
+ if (startY < 0)
+ startY = 0;
+ if (endX > mWidth)
+ endX = mWidth;
+ if (endY > mHeight)
+ endY = mHeight;
+
+ Actors::const_iterator ai = actors.begin();
+
+ const int dx = (mX * 32) - scrollX;
+ const int dy = (mY * 32) - scrollY + 32;
+
+ int specialWidth = 0;
+ int specialHeight = 0;
+
+ const bool extraDraw =
+ mIsFringeLayer && mSpecialLayer && mTempLayer;
+
+ if (mIsFringeLayer)
+ {
+ if (mSpecialLayer)
+ {
+ specialWidth = mSpecialLayer->mWidth;
+ specialHeight = mSpecialLayer->mHeight;
+ }
+ }
+
+ for (int y = startY; y < endY; y++)
+ {
+ const int y32 = y * 32;
+ const int yWidth = y * mWidth;
+
+ // If drawing the fringe layer, make sure all actors above this row of
+ // tiles have been drawn
+ if (mIsFringeLayer)
+ {
+ while (ai != actors.end() && (*ai)->getPixelY() <= y32)
+ {
+ (*ai)->draw(graphics, -scrollX, -scrollY);
+ ai++;
+ }
+ }
+
+ if (debugFlags == Map::MAP_SPECIAL3
+ || debugFlags == Map::MAP_BLACKWHITE)
+ {
+ if (extraDraw && y < specialHeight)
+ {
+ //x + y * mWidth
+ int ptr = y * specialWidth;
+ const int py1 = y32 - scrollY;
+ int endX1 = endX;
+ if (endX1 > specialWidth)
+ endX1 = specialWidth;
+ if (endX1 < 0)
+ endX1 = 0;
+
+ for (int x = startX; x < endX1; x++)
+ {
+ const int px1 = x * 32 - scrollX;
+
+ MapItem *item = mSpecialLayer->mTiles[ptr + x];
+ if (item)
+ item->draw(graphics, px1, py1, 32, 32);
+
+ item = mTempLayer->mTiles[ptr + x];
+ if (item)
+ item->draw(graphics, px1, py1, 32, 32);
+ }
+ }
+ }
+ else
+ {
+ const int py0 = y32 + dy;
+ const int py1 = y32 - scrollY;
+
+ for (int x = startX; x < endX; x++)
+ {
+ const int px1 = x * 32 - scrollX;
+ const int tilePtr = x + yWidth;
+ int c = 0;
+ Image *img = mTiles[tilePtr];
+ if (img)
+ {
+ const int px = (x * 32) + dx;
+ const int py = py0 - img->getHeight();
+ if ((debugFlags != Map::MAP_SPECIAL
+ && debugFlags != Map::MAP_SPECIAL2)
+ || img->getHeight() <= 32)
+ {
+ int width = 0;
+ c = getTileDrawWidth(tilePtr, endX - x, width);
+
+ if (!c)
+ {
+ graphics->drawImage(img, px, py);
+ }
+ else
+ {
+ graphics->drawImagePattern(img, px, py,
+ width, img->getHeight());
+ }
+ }
+ }
+
+ if (extraDraw && y < specialHeight)
+ {
+ int c1 = c;
+ if (c1 + x + 1 > specialWidth)
+ c1 = specialWidth - x - 1;
+ if (c1 < 0)
+ c1 = 0;
+
+ int ptr = y * specialWidth + x;
+
+ for (int x1 = 0; x1 < c1 + 1; x1 ++)
+ {
+ MapItem *item1 = mSpecialLayer->mTiles[ptr + x1];
+ MapItem *item2 = mTempLayer->mTiles[ptr + x1];
+ if (item1 || item2)
+ {
+ const int px2 = px1 + (x1 * 32);
+ if (item1 && item1->mType != MapItem::EMPTY)
+ item1->draw(graphics, px2, py1, 32, 32);
+
+ if (item2 && item2->mType != MapItem::EMPTY)
+ item2->draw(graphics, px2, py1, 32, 32);
+ }
+ }
+ }
+ x += c;
+ }
+ }
+ }
+
+ // Draw any remaining actors
+ if (mIsFringeLayer && debugFlags != Map::MAP_SPECIAL3)
+ {
+ while (ai != actors.end())
+ {
+ (*ai)->draw(graphics, -scrollX, -scrollY);
+ ai++;
+ }
+ if (mHighlightAttackRange && player_node)
+ {
+ const int px = player_node->getPixelX() - scrollX - 16;
+ const int py = player_node->getPixelY() - scrollY - 32;
+ const int attackRange = player_node->getAttackRange() * 32;
+
+ int x = px - attackRange;
+ int y = py - attackRange;
+ int w = 2 * attackRange + 32;
+ int h = w;
+ if (attackRange <= 32)
+ {
+ x -= 16;
+ y -= 16;
+ w += 32;
+ h += 32;
+ }
+
+ if (userPalette)
+ {
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::ATTACK_RANGE));
+
+ graphics->fillRectangle(gcn::Rectangle(
+ x, y,
+ w, h));
+
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::ATTACK_RANGE_BORDER));
+
+ graphics->drawRectangle(gcn::Rectangle(
+ x, y,
+ w, h));
+ }
+ }
+ }
+}
+
+int MapLayer::getTileDrawWidth(int tilePtr, int endX, int &width) const
+{
+ Image *img1 = mTiles[tilePtr];
+ int c = 0;
+ if (!img1)
+ {
+ width = 0;
+ return c;
+ }
+ width = img1->getWidth();
+ for (int x = 1; x < endX; x++)
+ {
+ tilePtr ++;
+ Image *img = mTiles[tilePtr];
+ if (img != img1)
+ break;
+ c ++;
+ if (img)
+ width += img->getWidth();
+ }
+ return c;
+}
+
+Map::Map(int width, int height, int tileWidth, int tileHeight):
+ mWidth(width), mHeight(height),
+ mTileWidth(tileWidth), mTileHeight(tileHeight),
+ mMaxTileHeight(height),
+ mHasWarps(false),
+ mDebugFlags(MAP_NORMAL),
+ mOnClosedList(1), mOnOpenList(2),
+ mLastScrollX(0.0f), mLastScrollY(0.0f),
+ mOverlayDetail(config.getIntValue("OverlayDetail")),
+ mOpacity(config.getFloatValue("guialpha")),
+ mPvp(0)
+// mSpritesUpdated(true)
+{
+ const int size = mWidth * mHeight;
+
+ mDebugFlags = 0;
+ mMetaTiles = new MetaTile[size];
+ for (int i = 0; i < NB_BLOCKTYPES; i++)
+ {
+ mOccupation[i] = new int[size];
+ memset(mOccupation[i], 0, size * sizeof(int));
+ }
+ mSpecialLayer = new SpecialLayer(width, height);
+ mTempLayer = new SpecialLayer(width, height, true);
+ config.addListener("OverlayDetail", this);
+ config.addListener("guialpha", this);
+
+#ifdef USE_OPENGL
+ mOpenGL = config.getIntValue("opengl");
+#else
+ mOpenGL = 0;
+#endif
+}
+
+Map::~Map()
+{
+ config.removeListener("OverlayDetail", this);
+ config.removeListener("guialpha", this);
+
+ // delete metadata, layers, tilesets and overlays
+ delete[] mMetaTiles;
+ for (int i = 0; i < NB_BLOCKTYPES; i++)
+ delete[] mOccupation[i];
+
+ delete_all(mLayers);
+ delete_all(mTilesets);
+ delete_all(mForegrounds);
+ delete_all(mBackgrounds);
+ delete_all(mTileAnimations);
+ delete mSpecialLayer;
+ mSpecialLayer = 0;
+ delete mTempLayer;
+ mTempLayer = 0;
+ delete_all(mMapPortals);
+}
+
+void Map::optionChanged(const std::string &value)
+{
+ if (value == "OverlayDetail")
+ mOverlayDetail = config.getIntValue("OverlayDetail");
+ else if (value == "guialpha")
+ mOpacity = config.getFloatValue("guialpha");
+}
+
+void Map::initializeAmbientLayers()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ // search for "foreground*" or "overlay*" (old term) in map properties
+ for (int i = 0; /* terminated by a break */; i++)
+ {
+ std::string name;
+ if (hasProperty("foreground" + toString(i) + "image"))
+ name = "foreground" + toString(i);
+ else if (hasProperty("overlay" + toString(i) + "image"))
+ name = "overlay" + toString(i);
+ else
+ break; // the FOR loop
+
+ Image *img = resman->getImage(getProperty(name + "image"));
+ const float speedX = getFloatProperty(name + "scrollX");
+ const float speedY = getFloatProperty(name + "scrollY");
+ const float parallax = getFloatProperty(name + "parallax");
+ const bool keepRatio = getBoolProperty(name + "keepratio");
+
+ if (img)
+ {
+ mForegrounds.push_back(
+ new AmbientLayer(img, parallax, speedX, speedY, keepRatio));
+
+ // The AmbientLayer takes control over the image.
+ img->decRef();
+ }
+ }
+
+
+ // search for "background*" in map properties
+ for (int i = 0;
+ hasProperty("background" + toString(i) + "image");
+ i++)
+ {
+ const std::string name = "background" + toString(i);
+
+ Image *img = resman->getImage(getProperty(name + "image"));
+ const float speedX = getFloatProperty(name + "scrollX");
+ const float speedY = getFloatProperty(name + "scrollY");
+ const float parallax = getFloatProperty(name + "parallax");
+ const bool keepRatio = getBoolProperty(name + "keepratio");
+
+ if (img)
+ {
+ mBackgrounds.push_back(
+ new AmbientLayer(img, parallax, speedX, speedY, keepRatio));
+
+ // The AmbientLayer takes control over the image.
+ img->decRef();
+ }
+ }
+}
+
+void Map::addLayer(MapLayer *layer)
+{
+ mLayers.push_back(layer);
+}
+
+void Map::addTileset(Tileset *tileset)
+{
+ if (!tileset)
+ return;
+
+ mTilesets.push_back(tileset);
+
+ if (tileset->getHeight() > mMaxTileHeight)
+ mMaxTileHeight = tileset->getHeight();
+}
+
+bool actorCompare(const Actor *a, const Actor *b)
+{
+ if (!a || !b)
+ return false;
+
+ return a->getPixelY() < b->getPixelY();
+}
+
+void Map::update(int ticks)
+{
+ // Update animated tiles
+ for (std::map<int, TileAnimation*>::iterator
+ iAni = mTileAnimations.begin();
+ iAni != mTileAnimations.end(); iAni++)
+ {
+ iAni->second->update(ticks);
+ }
+}
+
+void Map::draw(Graphics *graphics, int scrollX, int scrollY)
+{
+ // Calculate range of tiles which are on-screen
+ int endPixelY = graphics->getHeight() + scrollY + mTileHeight - 1;
+ endPixelY += mMaxTileHeight - mTileHeight;
+ int startX = scrollX / mTileWidth;
+ int startY = scrollY / mTileHeight;
+ int endX = (graphics->getWidth() + scrollX + mTileWidth - 1) / mTileWidth;
+ int endY = endPixelY / mTileHeight;
+
+ // Make sure actors are sorted ascending by Y-coordinate
+ // so that they overlap correctly
+// if (mSpritesUpdated)
+// {
+ mActors.sort(actorCompare);
+// mSpritesUpdated = false;
+// }
+
+ // update scrolling of all ambient layers
+ updateAmbientLayers(static_cast<float>(scrollX),
+ static_cast<float>(scrollY));
+
+ // Draw backgrounds
+ drawAmbientLayers(graphics, BACKGROUND_LAYERS, mOverlayDetail);
+
+ if (mDebugFlags == MAP_BLACKWHITE)
+ {
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::WALKABLE_HIGHLIGHT));
+
+ graphics->fillRectangle(gcn::Rectangle(0, 0,
+ graphics->getWidth(), graphics->getHeight()));
+ }
+
+ // draw the game world
+ Layers::const_iterator layeri = mLayers.begin();
+
+ bool overFringe = false;
+
+ if (mDebugFlags == MAP_SPECIAL3 || mDebugFlags == MAP_BLACKWHITE)
+ {
+ for (; layeri != mLayers.end(); ++layeri)
+ {
+ if ((*layeri)->isFringeLayer())
+ {
+ (*layeri)->setSpecialLayer(mSpecialLayer);
+ (*layeri)->setTempLayer(mTempLayer);
+ (*layeri)->draw(graphics,
+ startX, startY, endX, endY,
+ scrollX, scrollY,
+ mActors, mDebugFlags);
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (; layeri != mLayers.end() && !overFringe; ++layeri)
+ {
+ if ((*layeri)->isFringeLayer())
+ {
+ (*layeri)->setSpecialLayer(mSpecialLayer);
+ (*layeri)->setTempLayer(mTempLayer);
+ if (mDebugFlags == MAP_SPECIAL2)
+ overFringe = true;
+ }
+
+ (*layeri)->draw(graphics,
+ startX, startY, endX, endY,
+ scrollX, scrollY,
+ mActors, mDebugFlags);
+ }
+ }
+
+ // Dont draw if gui opacity == 1
+ if (mOpacity != 1.0f)
+ {
+ // Draws beings with a lower opacity to make them visible
+ // even when covered by a wall or some other elements...
+ Actors::const_iterator ai = mActors.begin();
+ while (ai != mActors.end())
+ {
+ if (Actor *actor = *ai)
+ {
+ if (!mOpenGL && (actor->getTileX() < startX
+ || actor->getTileX() > endX || actor->getTileY() < startY
+ || actor->getTileY() > endY))
+ {
+ ai++;
+ continue;
+ }
+ // For now, just draw actors with only one layer.
+ if (actor->getNumberOfLayers() == 1)
+ {
+ actor->setAlpha(0.3f);
+ actor->draw(graphics, -scrollX, -scrollY);
+ actor->setAlpha(1.0f);
+ }
+ }
+ ai++;
+ }
+ }
+
+ drawAmbientLayers(graphics, FOREGROUND_LAYERS, mOverlayDetail);
+}
+
+void Map::drawCollision(Graphics *graphics, int scrollX, int scrollY,
+ int debugFlags)
+{
+ int endPixelY = graphics->getHeight() + scrollY + mTileHeight - 1;
+ int startX = scrollX / mTileWidth;
+ int startY = scrollY / mTileHeight;
+ int endX = (graphics->getWidth() + scrollX + mTileWidth - 1) / mTileWidth;
+ int endY = endPixelY / mTileHeight;
+
+ if (startX < 0) startX = 0;
+ if (startY < 0) startY = 0;
+ if (endX > mWidth) endX = mWidth;
+ if (endY > mHeight) endY = mHeight;
+
+
+ if (debugFlags < MAP_SPECIAL)
+ {
+ graphics->setColor(gcn::Color(0, 0, 0, 64));
+ graphics->drawNet(
+ startX * mTileWidth - scrollX,
+ startY * mTileHeight - scrollY,
+ endX * mTileWidth - scrollX,
+ endY * mTileHeight - scrollY,
+ 32, 32);
+ }
+
+ for (int y = startY; y < endY; y++)
+ {
+ for (int x = startX; x < endX; x++)
+ {
+ int width = 0;
+ int x0 = x;
+
+ if (!getWalk(x, y, BLOCKMASK_WALL))
+ {
+ width = 32;
+ for (int x2 = x + 1; x < endX; x2 ++)
+ {
+ if (getWalk(x2, y, BLOCKMASK_WALL))
+ break;
+ width += 32;
+ x ++;
+ }
+ }
+
+ if (width && userPalette)
+ {
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::COLLISION_HIGHLIGHT));
+
+ graphics->fillRectangle(gcn::Rectangle(
+ x0 * mTileWidth - scrollX,
+ y * mTileHeight - scrollY,
+ width, 32));
+ }
+ }
+ }
+}
+
+void Map::updateAmbientLayers(float scrollX, float scrollY)
+{
+ static int lastTick = tick_time; // static = only initialized at first call
+
+ if (mLastScrollX == 0.0f && mLastScrollY == 0.0f)
+ {
+ // First call - initialisation
+ mLastScrollX = scrollX;
+ mLastScrollY = scrollY;
+ }
+
+ // Update Overlays
+ float dx = scrollX - mLastScrollX;
+ float dy = scrollY - mLastScrollY;
+ int timePassed = get_elapsed_time(lastTick);
+
+ std::list<AmbientLayer*>::iterator i;
+ for (i = mBackgrounds.begin(); i != mBackgrounds.end(); i++)
+ (*i)->update(timePassed, dx, dy);
+
+ for (i = mForegrounds.begin(); i != mForegrounds.end(); i++)
+ (*i)->update(timePassed, dx, dy);
+
+ mLastScrollX = scrollX;
+ mLastScrollY = scrollY;
+ lastTick = tick_time;
+}
+
+void Map::drawAmbientLayers(Graphics *graphics, LayerType type,
+ int detail)
+{
+ // Detail 0 = no ambient effects except background image
+ if (detail <= 0 && type != BACKGROUND_LAYERS)
+ return;
+
+ // find out which layer list to draw
+ std::list<AmbientLayer*> *layers;
+ switch (type)
+ {
+ case FOREGROUND_LAYERS:
+ layers = &mForegrounds;
+ break;
+ case BACKGROUND_LAYERS:
+ layers = &mBackgrounds;
+ break;
+ default:
+ // New type of ambient layers added here without adding it
+ // to Map::drawAmbientLayers.
+ assert(false);
+ break;
+ }
+
+ // Draw overlays
+ for (std::list<AmbientLayer*>::iterator i = layers->begin();
+ i != layers->end(); i++)
+ {
+ (*i)->draw(graphics, graphics->getWidth(), graphics->getHeight());
+
+ // Detail 1: only one overlay, higher: all overlays
+ if (detail == 1)
+ break;
+ }
+}
+
+Tileset *Map::getTilesetWithGid(int gid) const
+{
+ Tileset *s = NULL;
+ for (Tilesets::const_iterator it = mTilesets.begin(),
+ it_end = mTilesets.end(); it < it_end && (*it)->getFirstGid() <= gid;
+ it++)
+ {
+ s = *it;
+ }
+
+ return s;
+}
+
+void Map::blockTile(int x, int y, BlockType type)
+{
+ if (type == BLOCKTYPE_NONE || !contains(x, y))
+ return;
+
+ const int tileNum = x + y * mWidth;
+
+ if ((++mOccupation[type][tileNum]) > 0)
+ {
+ switch (type)
+ {
+ case BLOCKTYPE_WALL:
+ mMetaTiles[tileNum].blockmask |= BLOCKMASK_WALL;
+ break;
+ case BLOCKTYPE_CHARACTER:
+ mMetaTiles[tileNum].blockmask |= BLOCKMASK_CHARACTER;
+ break;
+ case BLOCKTYPE_MONSTER:
+ mMetaTiles[tileNum].blockmask |= BLOCKMASK_MONSTER;
+ break;
+ default:
+ // Do nothing.
+ break;
+ }
+ }
+}
+
+bool Map::getWalk(int x, int y, unsigned char walkmask) const
+{
+ // You can't walk outside of the map
+ if (!contains(x, y))
+ return false;
+
+ // Check if the tile is walkable
+ return !(mMetaTiles[x + y * mWidth].blockmask & walkmask);
+}
+
+bool Map::occupied(int x, int y) const
+{
+ const ActorSprites &actors = actorSpriteManager->getAll();
+ ActorSpritesConstIterator it, it_end;
+ for (it = actors.begin(), it_end = actors.end(); it != it_end; it++)
+ {
+ const ActorSprite *actor = *it;
+
+//+++ if (actor->getTileX() == x && actor->getTileY() == y
+// && being->getSubType() != 45)
+ if (actor->getTileX() == x && actor->getTileY() == y &&
+ actor->getType() != ActorSprite::FLOOR_ITEM)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Map::contains(int x, int y) const
+{
+ return x >= 0 && y >= 0 && x < mWidth && y < mHeight;
+}
+
+MetaTile *Map::getMetaTile(int x, int y) const
+{
+ return &mMetaTiles[x + y * mWidth];
+}
+
+Actors::iterator Map::addActor(Actor *actor)
+{
+ mActors.push_front(actor);
+// mSpritesUpdated = true;
+ return mActors.begin();
+}
+
+void Map::removeActor(Actors::iterator iterator)
+{
+ mActors.erase(iterator);
+// mSpritesUpdated = true;
+}
+
+const std::string Map::getMusicFile() const
+{
+ return getProperty("music");
+}
+
+const std::string Map::getName() const
+{
+ if (hasProperty("name"))
+ return getProperty("name");
+
+ return getProperty("mapname");
+}
+
+const std::string Map::getFilename() const
+{
+ std::string fileName = getProperty("_filename");
+ int lastSlash = static_cast<int>(fileName.rfind("/")) + 1;
+ int lastDot = static_cast<int>(fileName.rfind("."));
+
+ return fileName.substr(lastSlash, lastDot - lastSlash);
+}
+
+Position Map::checkNodeOffsets(int radius, unsigned char walkMask,
+ const Position &position) const
+{
+ // Pre-computing character's position in tiles
+ const int tx = position.x / 32;
+ const int ty = position.y / 32;
+
+ // Pre-computing character's position offsets.
+ int fx = position.x % 32;
+ int fy = position.y % 32;
+
+ // Compute the being radius:
+ // FIXME: Hande beings with more than 1/2 tile radius by not letting them
+ // go or spawn in too narrow places. The server will have to be aware
+ // of being's radius value (in tiles) to handle this gracefully.
+ if (radius > 32 / 2)
+ radius = 32 / 2;
+ // set a default value if no value returned.
+ if (radius < 1)
+ radius = 32 / 3;
+
+ // We check diagonal first as they are more restrictive.
+ // Top-left border check
+ if (!getWalk(tx - 1, ty - 1, walkMask)
+ && fy < radius && fx < radius)
+ {
+ fx = radius;
+ fy = radius;
+ }
+ // Top-right border check
+ if (!getWalk(tx + 1, ty - 1, walkMask)
+ && (fy < radius) && fx > (32 - radius))
+ {
+ fx = 32 - radius;
+ fy = radius;
+ }
+ // Bottom-left border check
+ if (!getWalk(tx - 1, ty + 1, walkMask)
+ && fy > (32 - radius) && fx < radius)
+ {
+ fx = radius;
+ fy = 32 - radius;
+ }
+ // Bottom-right border check
+ if (!getWalk(tx + 1, ty + 1, walkMask)
+ && fy > (32 - radius) && fx > (32 - radius))
+ {
+ fx = 32 - radius;
+ fy = fx;
+ }
+
+ // Fix coordinates so that the player does not seem to dig into walls.
+ if (fx > (32 - radius) && !getWalk(tx + 1, ty, walkMask))
+ fx = 32 - radius;
+ else if (fx < radius && !getWalk(tx - 1, ty, walkMask))
+ fx = radius;
+ else if (fy > (32 - radius) && !getWalk(tx, ty + 1, walkMask))
+ fy = 32 - radius;
+ else if (fy < radius && !getWalk(tx, ty - 1, walkMask))
+ fy = radius;
+
+ return Position(tx * 32 + fx, ty * 32 + fy);
+}
+
+Path Map::findPixelPath(int startPixelX, int startPixelY, int endPixelX,
+ int endPixelY,
+ int radius, unsigned char walkMask, int maxCost)
+{
+ Path myPath = findPath(startPixelX / 32, startPixelY / 32,
+ endPixelX / 32, endPixelY / 32, walkMask, maxCost);
+
+ // Don't compute empty coordinates.
+ if (myPath.empty())
+ return myPath;
+
+ // Find the starting offset
+ float startOffsetX = static_cast<float>(startPixelX % 32);
+ float startOffsetY = static_cast<float>(startPixelY % 32);
+
+ // Find the ending offset
+ float endOffsetX = static_cast<float>(endPixelX % 32);
+ float endOffsetY = static_cast<float>(endPixelY % 32);
+
+ // Find the distance, and divide it by the number of steps
+ int changeX = (int)((endOffsetX - startOffsetX)
+ / static_cast<float>(myPath.size()));
+ int changeY = (int)((endOffsetY - startOffsetY)
+ / static_cast<float>(myPath.size()));
+
+ // Convert the map path to pixels over tiles
+ // And add interpolation between the starting and ending offsets
+ Path::iterator it = myPath.begin();
+ int i = 0;
+ while (it != myPath.end())
+ {
+ // A position that is valid on the start and end tile is not
+ // necessarily valid on all the tiles in between, so check the offsets.
+ *it = checkNodeOffsets(radius, walkMask,
+ it->x * 32 + startOffsetX + static_cast<float>(changeX * i),
+ it->y * 32 + startOffsetY + static_cast<float>(changeY * i));
+ i++;
+ it++;
+ }
+
+ // Remove the last path node, as it's more clever to go to the destination.
+ // It also permit to avoid zigzag at the end of the path,
+ // especially with mouse.
+ Position destination = checkNodeOffsets(radius, walkMask,
+ endPixelX, endPixelY);
+ myPath.pop_back();
+ myPath.push_back(destination);
+
+ return myPath;
+}
+
+Path Map::findPath(int startX, int startY, int destX, int destY,
+ unsigned char walkmask, int maxCost)
+{
+ static int const basicCost = 100;
+
+ // Path to be built up (empty by default)
+ Path path;
+
+ // Declare open list, a list with open tiles sorted on F cost
+ std::priority_queue<Location> openList;
+
+ // Return when destination not walkable
+ if (!getWalk(destX, destY, walkmask))
+ return path;
+
+ // Reset starting tile's G cost to 0
+ MetaTile *startTile = getMetaTile(startX, startY);
+ startTile->Gcost = 0;
+
+ // Add the start point to the open list
+ openList.push(Location(startX, startY, startTile));
+
+ bool foundPath = false;
+
+ // Keep trying new open tiles until no more tiles to try or target found
+ while (!openList.empty() && !foundPath)
+ {
+ // Take the location with the lowest F cost from the open list.
+ Location curr = openList.top();
+ openList.pop();
+
+ // If the tile is already on the closed list, this means it has already
+ // been processed with a shorter path to the start point (lower G cost)
+ if (curr.tile->whichList == mOnClosedList)
+ continue;
+
+ // Put the current tile on the closed list
+ curr.tile->whichList = mOnClosedList;
+
+ // Check the adjacent tiles
+ for (int dy = -1; dy <= 1; dy++)
+ {
+ for (int dx = -1; dx <= 1; dx++)
+ {
+ // Calculate location of tile to check
+ const int x = curr.x + dx;
+ const int y = curr.y + dy;
+
+ // Skip if if we're checking the same tile we're leaving from,
+ // or if the new location falls outside of the map boundaries
+ if ((dx == 0 && dy == 0) || !contains(x, y))
+ continue;
+
+ MetaTile *newTile = getMetaTile(x, y);
+
+ // Skip if the tile is on the closed list or is not walkable
+ // unless its the destination tile
+ if (!newTile || newTile->whichList == mOnClosedList ||
+ ((newTile->blockmask & walkmask)
+ && !(x == destX && y == destY))
+ || (newTile->blockmask & BLOCKMASK_WALL))
+ {
+ continue;
+ }
+
+ // When taking a diagonal step, verify that we can skip the
+ // corner.
+ if (dx != 0 && dy != 0)
+ {
+ MetaTile *t1 = getMetaTile(curr.x, curr.y + dy);
+ MetaTile *t2 = getMetaTile(curr.x + dx, curr.y);
+
+ if (!t1 || !t2 || ((t1->blockmask | t2->blockmask)
+ & BLOCKMASK_WALL))
+ {
+ continue;
+ }
+ }
+
+ // Calculate G cost for this route, ~sqrt(2) for moving diagonal
+ int Gcost = curr.tile->Gcost +
+ (dx == 0 || dy == 0 ? basicCost : basicCost * 362 / 256);
+
+ /* Demote an arbitrary direction to speed pathfinding by
+ adding a defect (TODO: change depending on the desired
+ visual effect, e.g. a cross-product defect toward
+ destination).
+ Important: as long as the total defect along any path is
+ less than the basicCost, the pathfinder will still find one
+ of the shortest paths! */
+ if (dx == 0 || dy == 0)
+ {
+ // Demote horizontal and vertical directions, so that two
+ // consecutive directions cannot have the same Fcost.
+ ++Gcost;
+ }
+
+ // It costs extra to walk through a being (needs to be enough
+ // to make it more attractive to walk around).
+// if (occupied(x, y))
+// {
+// Gcost += 3 * basicCost;
+// }
+
+ // Skip if Gcost becomes too much
+ // Warning: probably not entirely accurate
+ if (maxCost > 0 && Gcost > maxCost * basicCost)
+ continue;
+
+ if (newTile->whichList != mOnOpenList)
+ {
+ // Found a new tile (not on open nor on closed list)
+
+ /* Update Hcost of the new tile. The pathfinder does not
+ work reliably if the heuristic cost is higher than the
+ real cost. In particular, using Manhattan distance is
+ forbidden here. */
+ int dx = std::abs(x - destX), dy = std::abs(y - destY);
+ newTile->Hcost = std::abs(dx - dy) * basicCost +
+ std::min(dx, dy) * (basicCost * 362 / 256);
+
+ // Set the current tile as the parent of the new tile
+ newTile->parentX = curr.x;
+ newTile->parentY = curr.y;
+
+ // Update Gcost and Fcost of new tile
+ newTile->Gcost = Gcost;
+ newTile->Fcost = Gcost + newTile->Hcost;
+
+ if (x != destX || y != destY)
+ {
+ // Add this tile to the open list
+ newTile->whichList = mOnOpenList;
+ openList.push(Location(x, y, newTile));
+ }
+ else
+ {
+ // Target location was found
+ foundPath = true;
+ }
+ }
+ else if (Gcost < newTile->Gcost)
+ {
+ // Found a shorter route.
+ // Update Gcost and Fcost of the new tile
+ newTile->Gcost = Gcost;
+ newTile->Fcost = Gcost + newTile->Hcost;
+
+ // Set the current tile as the parent of the new tile
+ newTile->parentX = curr.x;
+ newTile->parentY = curr.y;
+
+ // Add this tile to the open list (it's already
+ // there, but this instance has a lower F score)
+ openList.push(Location(x, y, newTile));
+ }
+ }
+ }
+ }
+
+ // Two new values to indicate whether a tile is on the open or closed list,
+ // this way we don't have to clear all the values between each pathfinding.
+ mOnClosedList += 2;
+ mOnOpenList += 2;
+
+ // If a path has been found, iterate backwards using the parent locations
+ // to extract it.
+ if (foundPath)
+ {
+ int pathX = destX;
+ int pathY = destY;
+
+ while (pathX != startX || pathY != startY)
+ {
+ // Add the new path node to the start of the path list
+ path.push_front(Position(pathX, pathY));
+
+ // Find out the next parent
+ MetaTile *tile = getMetaTile(pathX, pathY);
+ pathX = tile->parentX;
+ pathY = tile->parentY;
+ }
+ }
+
+ return path;
+}
+
+void Map::addParticleEffect(const std::string &effectFile,
+ int x, int y, int w, int h)
+{
+ ParticleEffectData newEffect;
+ newEffect.file = effectFile;
+ newEffect.x = x;
+ newEffect.y = y;
+ newEffect.w = w;
+ newEffect.h = h;
+ particleEffects.push_back(newEffect);
+}
+
+void Map::initializeParticleEffects(Particle *particleEngine)
+{
+ if (!particleEngine)
+ return;
+
+ Particle *p;
+
+ if (config.getBoolValue("particleeffects"))
+ {
+ for (std::list<ParticleEffectData>::iterator
+ i = particleEffects.begin();
+ i != particleEffects.end(); i++)
+ {
+ p = particleEngine->addEffect(i->file, i->x, i->y);
+ if (p && i->w > 0 && i->h > 0)
+ p->adjustEmitterSize(i->w, i->h);
+ }
+ }
+}
+
+void Map::addExtraLayer()
+{
+ if (!mSpecialLayer)
+ {
+ logger->log1("No special layer");
+ return;
+ }
+ std::string mapFileName = getUserMapDirectory() + "/extralayer.txt";
+ logger->log("try load extra layer: " + mapFileName);
+ struct stat statbuf;
+ if (!stat(mapFileName.c_str(), &statbuf) && S_ISREG(statbuf.st_mode))
+ {
+ std::ifstream mapFile;
+ mapFile.open(mapFileName.c_str(), std::ios::in);
+ char line[201];
+ std::string buf;
+ while (mapFile.getline(line, 200))
+ {
+ std::string buf;
+ std::string str = line;
+ if (!str.empty())
+ {
+ std::string x;
+ std::string y;
+ std::string type1;
+ std::string comment;
+ std::stringstream ss(str);
+ ss >> x;
+ ss >> y;
+ ss >> type1;
+ std::vector<int> tokens;
+ ss >> comment;
+ while (ss >> buf)
+ comment += " " + buf;
+
+ int type = atoi(type1.c_str());
+/*
+ MapItem *item = new MapItem(atoi(type.c_str()), comment);
+ int x1 = atoi(x.c_str());
+ int y1 = atoi(y.c_str());
+ mSpecialLayer->setTile(x1, y1, item);
+*/
+ if (comment.empty())
+ {
+ if (type < MapItem::ARROW_UP
+ || type > MapItem::ARROW_RIGHT)
+ {
+ comment = "unknown";
+ }
+ }
+ if (type == MapItem::PORTAL)
+ {
+ updatePortalTile(comment, type, atoi(x.c_str()),
+ atoi(y.c_str()), false);
+ }
+ else if (type == MapItem::HOME)
+ {
+ updatePortalTile(comment, type, atoi(x.c_str()),
+ atoi(y.c_str()));
+ }
+ else
+ {
+ addPortalTile(comment, type, atoi(x.c_str()),
+ atoi(y.c_str()));
+ }
+ }
+ }
+ mapFile.close();
+ }
+}
+
+void Map::saveExtraLayer()
+{
+ if (!mSpecialLayer)
+ {
+ logger->log1("No special layer");
+ return;
+ }
+ std::string mapFileName = getUserMapDirectory() + "/extralayer.txt";
+ logger->log("try save extra layer: " + mapFileName);
+
+ if (mkdir_r(getUserMapDirectory().c_str()))
+ {
+ logger->log(strprintf("%s doesn't exist and can't be created! "
+ "Exiting.", getUserMapDirectory().c_str()));
+ return;
+ }
+
+ std::ofstream mapFile;
+ mapFile.open(mapFileName.c_str(), std::ios::binary);
+ if (!mapFile.is_open())
+ {
+ logger->log1("Unable to open extralayer.txt for writing");
+ return;
+ }
+
+ int width = mSpecialLayer->mWidth;
+ int height = mSpecialLayer->mHeight;
+
+ for (int x = 0; x < width; x ++)
+ {
+ for (int y = 0; y < height; y ++)
+ {
+ MapItem *item = mSpecialLayer->getTile(x, y);
+ if (item && item->mType != MapItem::EMPTY
+ && item->mType != MapItem::HOME)
+ {
+ mapFile << x << " " << y << " " << (int)item->mType
+ << " " << item->mComment << std::endl;
+ }
+ }
+ }
+ mapFile.close();
+}
+
+std::string Map::getUserMapDirectory() const
+{
+ return Client::getServerConfigDirectory() + "/" + getProperty("_filename");
+}
+
+void Map::addPortal(const std::string &name, int type,
+ int x, int y, int dx, int dy)
+{
+ addPortalTile(name, type, (x / 32) + (dx / 64), (y / 32) + (dy / 64));
+}
+
+void Map::addPortalTile(const std::string &name, int type, int x, int y)
+{
+ MapItem *item = new MapItem(type, name, x, y);
+ if (mSpecialLayer)
+ mSpecialLayer->setTile(x, y, item);
+
+ item = new MapItem(type, name, x, y);
+ mMapPortals.push_back(item);
+}
+
+void Map::updatePortalTile(const std::string &name, int type,
+ int x, int y, bool addNew)
+{
+ MapItem *item = findPortalXY(x, y);
+ if (item)
+ {
+ item->mComment = name;
+ item->setType(type);
+ item->mX = x;
+ item->mY = y;
+ if (mSpecialLayer)
+ {
+ item = new MapItem(type, name, x, y);
+ mSpecialLayer->setTile(x, y, item);
+ }
+ }
+ else if (addNew)
+ {
+ addPortalTile(name, type, x, y);
+ }
+}
+
+MapItem *Map::findPortalXY(int x, int y)
+{
+ std::list<MapItem*>::iterator it;
+ std::list<MapItem*>::iterator it_end;
+
+ for (it = mMapPortals.begin(), it_end = mMapPortals.end();
+ it != it_end; it++)
+ {
+ MapItem *item = *it;
+ if (item->mX == x && item->mY == y)
+ return item;
+ }
+ return 0;
+}
+
+TileAnimation *Map::getAnimationForGid(int gid) const
+{
+ std::map<int, TileAnimation*>::const_iterator
+ i = mTileAnimations.find(gid);
+ return (i == mTileAnimations.end()) ? NULL : i->second;
+}
+
+void Map::setPvpMode(int mode)
+{
+ int oldMode = mPvp;
+
+ if (!mode)
+ mPvp = 0;
+ else
+ mPvp |= mode;
+
+ if (mPvp != oldMode && player_node)
+ {
+ switch (mPvp)
+ {
+ case 0:
+ player_node->setSpeech("pvp off, gvg off", SPEECH_TIME);
+ break;
+ case 1:
+ player_node->setSpeech("pvp on", SPEECH_TIME);
+ break;
+ case 2:
+ player_node->setSpeech("gvg on", SPEECH_TIME);
+ break;
+ case 3:
+ player_node->setSpeech("pvp on, gvg on", SPEECH_TIME);
+ break;
+ default:
+ player_node->setSpeech("unknown pvp", SPEECH_TIME);
+ break;
+ }
+ }
+}
+
+SpecialLayer::SpecialLayer(int width, int height, bool drawSprites):
+ mWidth(width), mHeight(height)
+{
+ const int size = mWidth * mHeight;
+ mTiles = new MapItem*[size];
+ std::fill_n(mTiles, size, (MapItem*) 0);
+ mDrawSprites = drawSprites;
+}
+
+SpecialLayer::~SpecialLayer()
+{
+ for (int f = 0; f < mWidth * mHeight; f ++)
+ {
+ delete mTiles[f];
+ mTiles[f] = 0;
+ }
+ delete[] mTiles;
+}
+
+MapItem* SpecialLayer::getTile(int x, int y) const
+{
+ if (x < 0 || x >= mWidth ||
+ y < 0 || y >= mHeight)
+ {
+ return 0;
+ }
+ return mTiles[x + y * mWidth];
+}
+
+void SpecialLayer::setTile(int x, int y, MapItem *item)
+{
+ if (x < 0 || x >= mWidth ||
+ y < 0 || y >= mHeight)
+ {
+ return;
+ }
+
+ int idx = x + y * mWidth;
+ delete mTiles[idx];
+ if (item)
+ item->setPos(x, y);
+ mTiles[idx] = item;
+}
+
+void SpecialLayer::setTile(int x, int y, int type)
+{
+ if (x < 0 || x >= mWidth ||
+ y < 0 || y >= mHeight)
+ {
+ return;
+ }
+
+ int idx = x + y * mWidth;
+ if (mTiles[idx])
+ {
+ mTiles[idx]->setType(type);
+ }
+ else
+ {
+ delete mTiles[idx];
+ mTiles[idx] = new MapItem(type);
+ }
+ mTiles[idx]->setPos(x, y);
+}
+
+void SpecialLayer::addRoad(Path road)
+{
+ for (Path::const_iterator i = road.begin(), i_end = road.end();
+ i != i_end; ++i)
+ {
+ Position pos = (*i);
+ MapItem *item = getTile(pos.x, pos.y);
+ if (!item)
+ {
+ item = new MapItem(MapItem::ROAD);
+ setTile(pos.x, pos.y, item);
+ }
+ else
+ {
+ item->setType(MapItem::ROAD);
+ }
+ }
+}
+
+void SpecialLayer::clean()
+{
+ for (int f = 0; f < mWidth * mHeight; f ++)
+ {
+ MapItem *item = mTiles[f];
+ if (item)
+ item->setType(MapItem::EMPTY);
+ }
+}
+
+void SpecialLayer::draw(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY)
+{
+ if (startX < 0)
+ startX = 0;
+ if (startY < 0)
+ startY = 0;
+ if (endX > mWidth)
+ endX = mWidth;
+ if (endY > mHeight)
+ endY = mHeight;
+
+// MapSprites::const_iterator si = sprites.begin();
+
+ for (int y = startY; y < endY; y++)
+ {
+ for (int x = startX; x < endX; x++)
+ itemDraw(graphics, x, y, scrollX, scrollY);
+ }
+}
+
+void SpecialLayer::itemDraw(Graphics *graphics, int x, int y,
+ int scrollX, int scrollY)
+{
+ MapItem *item = getTile(x, y);
+ if (item)
+ {
+ const int px = x * 32 - scrollX;
+ const int py = y * 32 - scrollY;
+ item->draw(graphics, px, py, 32, 32);
+ }
+}
+
+
+MapItem::MapItem():
+ mImage(0), mComment(""), mName(""), mX(-1), mY(-1)
+{
+ setType(EMPTY);
+}
+
+MapItem::MapItem(int type):
+ mImage(0), mComment(""), mName(""), mX(-1), mY(-1)
+{
+ setType(type);
+}
+
+MapItem::MapItem(int type, std::string comment):
+ mImage(0), mComment(comment), mName(""), mX(-1), mY(-1)
+{
+ setType(type);
+}
+
+MapItem::MapItem(int type, std::string comment, int x, int y):
+ mImage(0), mComment(comment), mName(""), mX(x), mY(y)
+{
+ setType(type);
+}
+
+MapItem::~MapItem()
+{
+ if (mImage)
+ mImage->decRef();
+}
+
+void MapItem::setType(int type)
+{
+ std::string name = "";
+ mType = type;
+ if (mImage)
+ mImage->decRef();
+
+ switch (type)
+ {
+ case ARROW_UP:
+ name = "graphics/sprites/arrow_up.gif";
+ break;
+ case ARROW_DOWN:
+ name = "graphics/sprites/arrow_down.gif";
+ break;
+ case ARROW_LEFT:
+ name = "graphics/sprites/arrow_left.gif";
+ break;
+ case ARROW_RIGHT:
+ name = "graphics/sprites/arrow_right.gif";
+ break;
+ default:
+ break;
+ }
+
+ if (name != "")
+ {
+ ResourceManager *resman = ResourceManager::getInstance();
+ mImage = resman->getImage(name);
+ }
+ else
+ {
+ mImage = 0;
+ }
+}
+
+void MapItem::setPos(int x, int y)
+{
+ mX = x;
+ mY = y;
+}
+
+void MapItem::draw(Graphics *graphics, int x, int y, int dx, int dy)
+{
+ if (mImage)
+ graphics->drawImage(mImage, x, y);
+
+ switch(mType)
+ {
+ case ROAD:
+ case CROSS:
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::ROAD_POINT));
+ graphics->fillRectangle(gcn::Rectangle(x + dx / 3, y + dy / 3,
+ dx / 3, dy / 3));
+ break;
+ case HOME:
+ {
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::HOME_PLACE));
+ graphics->fillRectangle(gcn::Rectangle(
+ x, y,
+ dx, dy));
+ graphics->setColor(userPalette->getColorWithAlpha(
+ UserPalette::HOME_PLACE_BORDER));
+ graphics->drawRectangle(gcn::Rectangle(
+ x, y,
+ dx, dy));
+ break;
+ }
+ default:
+ break;
+ }
+ if (!mName.empty() && mType != PORTAL && mType != EMPTY)
+ {
+ gcn::Font *font = gui->getFont();
+ if (font)
+ {
+ graphics->setColor(userPalette->getColor(UserPalette::BEING));
+ font->drawString(graphics, mName, x, y);
+ }
+ }
+}
+
diff --git a/src/map.h b/src/map.h
new file mode 100644
index 000000000..a51ecab6c
--- /dev/null
+++ b/src/map.h
@@ -0,0 +1,611 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MAP_H
+#define MAP_H
+
+#include "actor.h"
+#include "configlistener.h"
+#include "position.h"
+#include "properties.h"
+
+#include <list>
+#include <string>
+#include <vector>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Animation;
+class AmbientLayer;
+class Graphics;
+class MapLayer;
+class Particle;
+class SimpleAnimation;
+class Tileset;
+class SpecialLayer;
+class MapItem;
+
+typedef std::vector<Tileset*> Tilesets;
+typedef std::vector<MapLayer*> Layers;
+
+/**
+ * A meta tile stores additional information about a location on a tile map.
+ * This is information that doesn't need to be repeated for each tile in each
+ * layer of the map.
+ */
+struct MetaTile
+{
+ /**
+ * Constructor.
+ */
+ MetaTile() : Fcost(0), Gcost(0), Hcost(0), whichList(0),
+ parentX(0), parentY(0), blockmask(0)
+ {}
+
+ // Pathfinding members
+ int Fcost; /**< Estimation of total path cost */
+ int Gcost; /**< Cost from start to this location */
+ int Hcost; /**< Estimated cost to goal */
+ int whichList; /**< No list, open list or closed list */
+ int parentX; /**< X coordinate of parent tile */
+ int parentY; /**< Y coordinate of parent tile */
+ unsigned char blockmask; /**< Blocking properties of this tile */
+};
+
+/*
+struct MapBox
+{
+ MapBox() : name(""), x(0), y(0)
+ {
+ }
+
+ MapBox(std::string name1, int x1, int y1):
+ name(name1), x(x1), y(y1)
+ {
+ }
+
+ std::string name;
+ int x;
+ int y;
+};
+*/
+
+/**
+ * Animation cycle of a tile image which changes the map accordingly.
+ */
+class TileAnimation
+{
+ public:
+ TileAnimation(Animation *ani);
+ ~TileAnimation();
+ void update(int ticks = 1);
+ void addAffectedTile(MapLayer *layer, int index)
+ { mAffected.push_back(std::make_pair(layer, index)); }
+ private:
+ std::list<std::pair<MapLayer*, int> > mAffected;
+ SimpleAnimation *mAnimation;
+ Image *mLastImage;
+};
+
+/**
+ * A map layer. Stores a grid of tiles and their offset, and implements layer
+ * rendering.
+ */
+class MapLayer: public ConfigListener
+{
+ public:
+ /**
+ * Constructor, taking layer origin, size and whether this layer is the
+ * fringe layer. The fringe layer is the layer that draws the actors.
+ * There can be only one fringe layer per map.
+ */
+ MapLayer(int x, int y, int width, int height, bool isFringeLayer);
+
+ /**
+ * Destructor.
+ */
+ ~MapLayer();
+
+ /**
+ * Set tile image, with x and y in layer coordinates.
+ */
+ void setTile(int x, int y, Image *img);
+
+ /**
+ * Set tile image with x + y * width already known.
+ */
+ void setTile(int index, Image *img) { mTiles[index] = img; }
+
+ /**
+ * Get tile image, with x and y in layer coordinates.
+ */
+ Image *getTile(int x, int y) const;
+
+ /**
+ * Draws this layer to the given graphics context. The coordinates are
+ * expected to be in map range and will be translated to local layer
+ * coordinates and clipped to the layer's dimensions.
+ *
+ * The given actors are only drawn when this layer is the fringe
+ * layer.
+ */
+ void draw(Graphics *graphics,
+ int startX, int startY,
+ int endX, int endY,
+ int scrollX, int scrollY,
+ const Actors &actors,
+ int mDebugFlags) const;
+
+ bool isFringeLayer()
+ { return mIsFringeLayer; }
+
+ void setSpecialLayer(SpecialLayer *val)
+ { mSpecialLayer = val; }
+
+ void setTempLayer(SpecialLayer *val)
+ { mTempLayer = val; }
+
+ int getWidth()
+ { return mWidth; }
+
+ int getHeight()
+ { return mHeight; }
+
+// void setTileInfo(int x, int y, int width, int cnt);
+
+// void getTileInfo(int x, int y, int &width, int &cnt) const;
+
+ void optionChanged(const std::string &value);
+
+ int getTileDrawWidth(int tilePtr, int endX, int &width) const;
+
+// void initTileInfo();
+
+ private:
+ int mX, mY;
+ int mWidth, mHeight;
+ bool mIsFringeLayer; /**< Whether the actors are drawn. */
+ bool mHighlightAttackRange;
+ Image **mTiles;
+// int *mTilesWidth;
+// int *mTilesCount;
+ SpecialLayer *mSpecialLayer;
+ SpecialLayer *mTempLayer;
+};
+
+/**
+ * A tile map.
+ */
+class Map : public Properties, public ConfigListener
+{
+ public:
+ enum BlockType
+ {
+ BLOCKTYPE_NONE = -1,
+ BLOCKTYPE_WALL,
+ BLOCKTYPE_CHARACTER,
+ BLOCKTYPE_MONSTER,
+ NB_BLOCKTYPES
+ };
+
+ enum BlockMask
+ {
+ BLOCKMASK_WALL = 0x80, // = bin 1000 0000
+ BLOCKMASK_CHARACTER = 0x01, // = bin 0000 0001
+ BLOCKMASK_MONSTER = 0x02 // = bin 0000 0010
+ };
+
+ enum DebugType
+ {
+ MAP_NORMAL = 0,
+ MAP_DEBUG = 1,
+ MAP_SPECIAL = 2,
+ MAP_SPECIAL2 = 3,
+ MAP_SPECIAL3 = 4,
+ MAP_BLACKWHITE = 5
+ };
+
+ /**
+ * Constructor, taking map and tile size as parameters.
+ */
+ Map(int width, int height, int tileWidth, int tileHeight);
+
+ /**
+ * Destructor.
+ */
+ ~Map();
+
+ /**
+ * Initialize ambient layers. Has to be called after all the properties
+ * are set.
+ */
+ void initializeAmbientLayers();
+
+ /**
+ * Updates animations. Called as needed.
+ */
+ void update(int ticks = 1);
+
+ /**
+ * Draws the map to the given graphics output. This method draws all
+ * layers, actors and overlay effects.
+ *
+ * TODO: For efficiency reasons, this method could take into account
+ * the clipping rectangle set on the Graphics object. However,
+ * currently the map is always drawn full-screen.
+ */
+ void draw(Graphics *graphics, int scrollX, int scrollY);
+
+ /**
+ * Visualizes collision layer for debugging
+ */
+ void drawCollision(Graphics *graphics, int scrollX, int scrollY,
+ int debugFlags);
+
+ /**
+ * Adds a layer to this map. The map takes ownership of the layer.
+ */
+ void addLayer(MapLayer *layer);
+
+ /**
+ * Adds a tileset to this map. The map takes ownership of the tileset.
+ */
+ void addTileset(Tileset *tileset);
+
+ /**
+ * Finds the tile set that a tile with the given global id is part of.
+ */
+ Tileset *getTilesetWithGid(int gid) const;
+
+ /**
+ * Get tile reference.
+ */
+ MetaTile *getMetaTile(int x, int y) const;
+
+ /**
+ * Marks a tile as occupied.
+ */
+ void blockTile(int x, int y, BlockType type);
+
+ /**
+ * Gets walkability for a tile with a blocking bitmask. When called
+ * without walkmask, only blocks against colliding tiles.
+ */
+ bool getWalk(int x, int y,
+ unsigned char walkmask = BLOCKMASK_WALL) const;
+
+ /**
+ * Tells whether a tile is occupied by a being.
+ */
+ bool occupied(int x, int y) const;
+
+ /**
+ * Returns the width of this map in tiles.
+ */
+ int getWidth() const { return mWidth; }
+
+ /**
+ * Returns the height of this map in tiles.
+ */
+ int getHeight() const { return mHeight; }
+
+ /**
+ * Returns the tile width of this map.
+ */
+ int getTileWidth() const
+ { return mTileWidth; }
+
+ /**
+ * Returns the tile height used by this map.
+ */
+ int getTileHeight() const
+ { return mTileHeight; }
+
+ const std::string getMusicFile() const;
+ const std::string getName() const;
+
+ /**
+ * Gives the map id based on filepath (ex: 009-1)
+ */
+ const std::string getFilename() const;
+
+ /**
+ * Check the current position against surrounding blocking tiles, and
+ * correct the position offset within tile when needed.
+ */
+ Position checkNodeOffsets(int radius, unsigned char walkMask,
+ const Position &position) const;
+
+ Position checkNodeOffsets(int radius, unsigned char walkMask,
+ int x, int y) const
+ { return checkNodeOffsets(radius, walkMask, Position(x, y)); }
+
+ /**
+ * Find a pixel path from one location to the next.
+ */
+ Path findPixelPath(int startPixelX, int startPixelY,
+ int destPixelX, int destPixelY,
+ int radius, unsigned char walkmask,
+ int maxCost = 20);
+
+ /**
+ * Find a path from one location to the next.
+ */
+ Path findPath(int startX, int startY, int destX, int destY,
+ unsigned char walkmask, int maxCost = 20);
+
+ /**
+ * Adds a particle effect
+ */
+ void addParticleEffect(const std::string &effectFile,
+ int x, int y, int w = 0, int h = 0);
+
+ /**
+ * Initializes all added particle effects
+ */
+ void initializeParticleEffects(Particle* particleEngine);
+
+ /**
+ * Adds a tile animation to the map
+ */
+ void addAnimation(int gid, TileAnimation *animation)
+ { mTileAnimations[gid] = animation; }
+
+ void setDebugFlags(int n)
+ { mDebugFlags = n; }
+
+ int getDebugFlags() const
+ { return mDebugFlags; }
+
+ void addExtraLayer();
+
+ void saveExtraLayer();
+
+ SpecialLayer *getTempLayer()
+ { return mTempLayer; }
+
+ SpecialLayer *getSpecialLayer()
+ { return mSpecialLayer; }
+
+ void setHasWarps(bool n)
+ { mHasWarps = n; }
+
+ bool getHasWarps()
+ { return mHasWarps; }
+
+ std::string getUserMapDirectory() const;
+
+ void addPortal(const std::string &name, int type,
+ int x, int y, int dx, int dy);
+
+ void addPortalTile(const std::string &name, int type, int x, int y);
+
+ void updatePortalTile(const std::string &name, int type,
+ int x, int y, bool addNew = true);
+
+ std::list<MapItem*> &getPortals()
+ { return mMapPortals; }
+
+ /**
+ * Gets the tile animation for a specific gid
+ */
+ TileAnimation *getAnimationForGid(int gid) const;
+
+ void optionChanged(const std::string &value);
+
+ MapItem *findPortalXY(int x, int y);
+
+ int getActorsCount() const
+ { return mActors.size(); }
+
+ void setPvpMode(int mode);
+
+ protected:
+ friend class Actor;
+
+ /**
+ * Adds an actor to the map.
+ */
+ Actors::iterator addActor(Actor *actor);
+
+ /**
+ * Removes an actor from the map.
+ */
+ void removeActor(Actors::iterator iterator);
+
+ private:
+
+ enum LayerType
+ {
+ FOREGROUND_LAYERS = 0,
+ BACKGROUND_LAYERS
+ };
+
+ /**
+ * Updates scrolling of ambient layers. Has to be called each game tick.
+ */
+ void updateAmbientLayers(float scrollX, float scrollY);
+
+ /**
+ * Draws the foreground or background layers to the given graphics output.
+ */
+ void drawAmbientLayers(Graphics *graphics, LayerType type,
+ int detail);
+
+ /**
+ * Tells whether the given coordinates fall within the map boundaries.
+ */
+ bool contains(int x, int y) const;
+
+ /**
+ * Blockmasks for different entities
+ */
+ int *mOccupation[NB_BLOCKTYPES];
+
+ int mWidth, mHeight;
+ int mTileWidth, mTileHeight;
+ int mMaxTileHeight;
+ MetaTile *mMetaTiles;
+ Layers mLayers;
+ Tilesets mTilesets;
+ Actors mActors;
+ bool mHasWarps;
+
+ // debug flags
+ int mDebugFlags;
+
+ // Pathfinding members
+ int mOnClosedList, mOnOpenList;
+
+ // Overlay data
+ std::list<AmbientLayer*> mBackgrounds;
+ std::list<AmbientLayer*> mForegrounds;
+ float mLastScrollX;
+ float mLastScrollY;
+// bool mSpritesUpdated;
+
+ // Particle effect data
+ struct ParticleEffectData
+ {
+ std::string file;
+ int x;
+ int y;
+ int w;
+ int h;
+ };
+ std::list<ParticleEffectData> particleEffects;
+
+ std::list<MapItem*> mMapPortals;
+
+ std::map<int, TileAnimation*> mTileAnimations;
+
+ int mOverlayDetail;
+ float mOpacity;
+ int mOpenGL;
+ int mPvp;
+
+ SpecialLayer *mSpecialLayer;
+ SpecialLayer *mTempLayer;
+};
+
+
+class SpecialLayer
+{
+ public:
+ friend class Map;
+ friend class MapLayer;
+
+ SpecialLayer(int width, int height, bool drawSprites = false);
+
+ ~SpecialLayer();
+
+ void draw(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY);
+
+ MapItem* getTile(int x, int y) const;
+
+ void setTile(int x, int y, MapItem* item);
+
+ void setTile(int x, int y, int type);
+
+ void addRoad(Path road);
+
+ void clean();
+
+ void itemDraw(Graphics *graphics, int x, int y,
+ int scrollX, int scrollY);
+
+ private:
+ int mWidth, mHeight;
+ bool mDrawSprites;
+ MapItem **mTiles;
+};
+
+class MapItem
+{
+ public:
+ friend class Map;
+ friend class MapLayer;
+
+ enum ItemType
+ {
+ EMPTY = 0,
+ HOME = 1,
+ ROAD = 2,
+ CROSS = 3,
+ ARROW_UP = 4,
+ ARROW_DOWN = 5,
+ ARROW_LEFT = 6,
+ ARROW_RIGHT = 7,
+ PORTAL = 8
+ };
+
+ MapItem();
+
+ MapItem(int type);
+
+ MapItem(int type, std::string comment);
+
+ MapItem(int type, std::string comment, int x, int y);
+
+ ~MapItem();
+
+ int getType() const
+ { return mType; }
+
+ void setType(int type);
+
+ void setPos(int x, int y);
+
+ int getX() const
+ { return mX; }
+
+ int getY() const
+ { return mY; }
+
+ std::string &getComment()
+ { return mComment; }
+
+ void setComment(std::string comment)
+ { mComment = comment; }
+
+ std::string &getName()
+ { return mName; }
+
+ void setName(std::string name)
+ { mName = name; }
+
+ void draw(Graphics *graphics, int x, int y, int dx, int dy);
+
+ private:
+ int mType;
+ Image *mImage;
+ std::string mComment;
+ std::string mName;
+ int mX;
+ int mY;
+};
+
+#endif
diff --git a/src/mumblemanager.cpp b/src/mumblemanager.cpp
new file mode 100644
index 000000000..6586f9546
--- /dev/null
+++ b/src/mumblemanager.cpp
@@ -0,0 +1,273 @@
+/* Code taken from: http://mumble.sourceforge.net/Link */
+
+#include "mumblemanager.h"
+
+#include "configuration.h"
+#include "log.h"
+
+#include "utils/mathutils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <SDL_syswm.h>
+
+#ifndef WIN32
+#include <sys/mman.h>
+#endif
+
+MumbleManager::MumbleManager() :
+ mLinkedMem(0)
+{
+ mMapBase[0] = mMapBase[1] = mMapBase[2] = 0.;
+ init();
+}
+
+MumbleManager::~MumbleManager()
+{
+ if (mLinkedMem)
+ {
+#ifdef WIN32
+ UnmapViewOfFile(mLinkedMem);
+#elif defined __FreeBSD__ || defined __DragonFly__
+#else
+ munmap(mLinkedMem, sizeof(struct LinkedMem));
+#endif
+ mLinkedMem = 0;
+ }
+}
+
+uint16_t MumbleManager::getMapId(std::string mapName)
+{
+ uint16_t res = 0;
+ if (mapName.size() != 5 || mapName[3] != '-')
+ {
+ res = getCrc16(mapName);
+ }
+ else
+ {
+ mapName = mapName.substr(0, 3) + mapName[4];
+ res = atoi(mapName.c_str());
+ }
+ return res;
+}
+
+void MumbleManager::setMapBase(uint16_t mapid)
+{
+ mMapBase[0] = 10000. * (mapid & 0x1f);
+ mapid >>= 5;
+ mMapBase[1] = 1000. * (mapid & 0x3f);
+ mapid >>= 6;
+ mMapBase[2] = 10000. * (mapid & 0x1f);
+}
+
+void MumbleManager::init()
+{
+#if defined __FreeBSD__ || defined __DragonFly__
+ return;
+#endif
+
+ if (mLinkedMem || !config.getBoolValue("enableMumble"))
+ return;
+
+ logger->log1("MumbleManager::init");
+#ifdef WIN32
+ HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS,
+ FALSE, L"MumbleLink");
+ if (hMapObject == NULL)
+ {
+ logger->log1("MumbleManager::init cant open MumbleLink");
+ return;
+ }
+
+ mLinkedMem = (LinkedMem *) MapViewOfFile(hMapObject,
+ FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));
+
+ if (mLinkedMem == NULL)
+ {
+ CloseHandle(hMapObject);
+ hMapObject = NULL;
+ logger->log1("MumbleManager::init cant map MumbleLink");
+ return;
+ }
+#elif defined __FreeBSD__ || defined __DragonFly__
+#else
+ char memName[256];
+ snprintf(memName, 256, "/MumbleLink.%d", getuid());
+
+ int shmfd = shm_open(memName, O_RDWR, S_IRUSR | S_IWUSR);
+
+ if (shmfd < 0)
+ {
+ logger->log1("MumbleManager::init cant open shared memory MumbleLink");
+ return;
+ }
+
+ mLinkedMem = (LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem),
+ PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0));
+
+ if (mLinkedMem == (void *)(-1))
+ {
+ mLinkedMem = NULL;
+ logger->log1("MumbleManager::init cant map MumbleLink");
+ return;
+ }
+
+#endif
+ wcsncpy(mLinkedMemCache.name, L"Mana", 256);
+ wcsncpy(mLinkedMemCache.description, L"TheManaWorld Plugin", 2048);
+ mLinkedMemCache.uiVersion = 2;
+
+ // Left handed coordinate system.
+ // X positive towards "left".
+ // Y positive towards "up".
+ // Z positive towards "into screen".
+ //
+ // 1 unit = 1 meter
+
+ // Unit vector pointing out of the avatars eyes (here Front looks into scene).
+ /* no way to look "up", 2d */
+ mLinkedMemCache.fAvatarFront[1] = 0.0f;
+
+ // Unit vector pointing out of the top of the avatars head
+ // (here Top looks straight up).
+ /* no way to change this in tmw */
+ mLinkedMemCache.fAvatarTop[0] = 0.0f;
+ mLinkedMemCache.fAvatarTop[1] = 1.0f;
+ mLinkedMemCache.fAvatarTop[2] = 0.0f;
+
+ mLinkedMemCache.fCameraFront[0] = 0.0f;
+ mLinkedMemCache.fCameraFront[1] = 0.0f;
+ mLinkedMemCache.fCameraFront[2] = 1.0f;
+
+ mLinkedMemCache.fCameraTop[0] = 0.0f;
+ mLinkedMemCache.fCameraTop[1] = 1.0f;
+ mLinkedMemCache.fCameraTop[2] = 0.0f;
+
+ mLinkedMemCache.uiTick++;
+}
+
+void MumbleManager::setPlayer(const std::string &userName)
+{
+ if (!mLinkedMem)
+ return;
+
+ // Identifier which uniquely identifies a certain player in a context
+ // (e.g. the ingame Name).
+ mbstowcs(mLinkedMemCache.identity, userName.c_str(), 256);
+ mLinkedMemCache.uiTick ++;
+ memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
+}
+
+void MumbleManager::setAction(int action)
+{
+ if (!mLinkedMem)
+ return;
+
+ switch(action)
+ {
+ case 0: /* STAND */
+ case 1: /* WALK */
+ case 2: /* ATTACK */
+ case 5: /* HURT */
+ mLinkedMemCache.fAvatarPosition[1] = 1.5f;
+ break;
+ case 3: /* SIT */
+ mLinkedMemCache.fAvatarPosition[1] = 1.0f;
+ break;
+ case 4: /* DEAD */
+ default:
+ mLinkedMemCache.fAvatarPosition[1] = 0.0f;
+ break;
+ }
+ mLinkedMemCache.fAvatarPosition[1] += mMapBase[1];
+ mLinkedMemCache.fCameraPosition[1] = mLinkedMemCache.fAvatarPosition[1];
+
+ mLinkedMemCache.uiTick++;
+ memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
+}
+
+void MumbleManager::setPos(int tileX, int tileY, int direction)
+{
+ if (!mLinkedMem)
+ return;
+
+ // Position of the avatar (here standing slightly off the origin)
+ // lm->fAvatarPosition
+
+ /* tmw coordinates work exactly the other way round */
+ mLinkedMemCache.fAvatarPosition[0] = tileX + mMapBase[0];
+ mLinkedMemCache.fAvatarPosition[2] = tileY + mMapBase[2];
+
+ // Same as avatar but for the camera.
+ // lm->fCameraPosition, fCameraFront, fCameraTop
+
+ // Same as avatar but for the camera.
+ mLinkedMemCache.fCameraPosition[0] = mLinkedMemCache.fAvatarPosition[0];
+ mLinkedMemCache.fCameraPosition[2] = mLinkedMemCache.fAvatarPosition[2];
+
+ // Unit vector pointing out of the avatars eyes
+ // (here Front looks into scene).
+ switch(direction)
+ {
+ case 4: /* UP */
+ mLinkedMemCache.fAvatarFront[0] = 0.0f;
+ mLinkedMemCache.fAvatarFront[2] = 1.0f;
+ break;
+ case 1: /* DOWN */
+ mLinkedMemCache.fAvatarFront[0] = 0.0f;
+ mLinkedMemCache.fAvatarFront[2] = -1.0f;
+ break;
+ case 2: /* LEFT */
+ mLinkedMemCache.fAvatarFront[0] = 1.0f;
+ mLinkedMemCache.fAvatarFront[2] = 0.0f;
+ break;
+ case 8: /* RIGHT */
+ mLinkedMemCache.fAvatarFront[0] = -1.0f;
+ mLinkedMemCache.fAvatarFront[2] = 0.0f;
+ break;
+ default:
+ break;
+ }
+
+ mLinkedMemCache.uiTick ++;
+ memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
+}
+
+void MumbleManager::setMap(const std::string &mapName)
+{
+ if (!mLinkedMem)
+ return;
+
+ // Context should be equal for players which should be able to hear each
+ // other positional and differ for those who shouldn't
+ // (e.g. it could contain the server+port and team)
+
+ setMapBase(getMapId(mapName));
+ setAction(0); /* update y coordinate */
+}
+
+void MumbleManager::setServer(const std::string &serverName)
+{
+ if (!mLinkedMem)
+ return;
+
+ unsigned size = serverName.size();
+ if (size > sizeof(mLinkedMemCache.context) - 1)
+ size = sizeof(mLinkedMemCache.context) - 1;
+
+ memset(mLinkedMemCache.context, 0, sizeof(mLinkedMemCache.context));
+ memcpy(mLinkedMemCache.context, serverName.c_str(), size);
+ mLinkedMemCache.context[size] = '\0';
+ mLinkedMemCache.context_len = size;
+ mLinkedMemCache.uiTick ++;
+ memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
+}
diff --git a/src/mumblemanager.h b/src/mumblemanager.h
new file mode 100644
index 000000000..a3eddee02
--- /dev/null
+++ b/src/mumblemanager.h
@@ -0,0 +1,57 @@
+/* Code taken from: http://mumble.sourceforge.net/Link */
+
+#ifndef MUMBLEMANAGER_H
+#define MUMBLEMANAGER_H
+
+#include <string>
+#include <stdint.h>
+
+struct LinkedMem
+{
+ uint32_t uiVersion;
+ uint32_t uiTick;
+ float fAvatarPosition[3];
+ float fAvatarFront[3];
+ float fAvatarTop[3];
+ wchar_t name[256];
+ float fCameraPosition[3];
+ float fCameraFront[3];
+ float fCameraTop[3];
+ wchar_t identity[256];
+ uint32_t context_len;
+ char context[256];
+ wchar_t description[2048];
+};
+
+class MumbleManager
+{
+ public:
+ MumbleManager();
+
+ ~MumbleManager();
+
+ void init();
+
+ void setPlayer(const std::string &userName);
+
+ void setAction(int action);
+
+ void setPos(int tileX, int tileY, int direction);
+
+ void setMap(const std::string &mapName);
+
+ void setServer(const std::string &serverName);
+
+ private:
+ uint16_t getMapId(std::string mapName);
+
+ void setMapBase(uint16_t mapid);
+
+ LinkedMem *mLinkedMem;
+ LinkedMem mLinkedMemCache;
+ float mMapBase[3];
+};
+
+extern MumbleManager *mumbleManager;
+
+#endif
diff --git a/src/net/adminhandler.h b/src/net/adminhandler.h
new file mode 100644
index 000000000..7c24554c9
--- /dev/null
+++ b/src/net/adminhandler.h
@@ -0,0 +1,60 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ADMINHANDLER_H
+#define ADMINHANDLER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+
+class AdminHandler
+{
+ public:
+ virtual ~AdminHandler() {}
+
+ virtual void announce(const std::string &text) = 0;
+
+ virtual void localAnnounce(const std::string &text) = 0;
+
+ virtual void hide(bool hide) = 0;
+
+ virtual void kick(int playerId) = 0;
+
+ virtual void kick(const std::string &name) = 0;
+
+ virtual void ban(int playerId) = 0;
+
+ virtual void ban(const std::string &name) = 0;
+
+ virtual void unban(int playerId) = 0;
+
+ virtual void unban(const std::string &name) = 0;
+
+ virtual void mute(int playerId, int type, int limit) = 0;
+
+ // TODO
+};
+
+} // namespace Net
+
+#endif // ADMINHANDLER_H
diff --git a/src/net/beinghandler.h b/src/net/beinghandler.h
new file mode 100644
index 000000000..89f972e6d
--- /dev/null
+++ b/src/net/beinghandler.h
@@ -0,0 +1,43 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef BEINGHANDLER_H
+#define BEINGHANDLER_H
+
+#include "being.h"
+#include "net/messagein.h"
+
+namespace Net
+{
+
+class BeingHandler
+{
+ public:
+ virtual void handleMessage(Net::MessageIn &msg) = 0;
+
+ virtual void requestNameById(int id) = 0;
+
+ virtual void undress(Being *being) = 0;
+};
+
+} // namespace Net
+
+#endif // BEINGHANDLER_H
diff --git a/src/net/buysellhandler.h b/src/net/buysellhandler.h
new file mode 100644
index 000000000..88851e94e
--- /dev/null
+++ b/src/net/buysellhandler.h
@@ -0,0 +1,47 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BUYSELLHANDLER_H
+#define BUYSELLHANDLER_H
+
+#include "net/messagein.h"
+
+#include "being.h"
+#include "shopitem.h"
+
+namespace Net
+{
+
+class BuySellHandler
+{
+ public:
+ virtual void handleMessage(Net::MessageIn &msg) = 0;
+ virtual void requestSellList(std::string nick) = 0;
+ virtual void requestBuyList(std::string nick) = 0;
+ virtual void sendBuyRequest(std::string nick, ShopItem* item,
+ int amount) = 0;
+ virtual void sendSellRequest(std::string nick, ShopItem* item,
+ int amount) = 0;
+};
+
+} // namespace Net
+
+#endif // BUYSELLHANDLER_H
diff --git a/src/net/charhandler.cpp b/src/net/charhandler.cpp
new file mode 100644
index 000000000..699d930a2
--- /dev/null
+++ b/src/net/charhandler.cpp
@@ -0,0 +1,37 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/charhandler.h"
+
+#include "gui/charselectdialog.h"
+
+using namespace Net;
+
+void CharHandler::updateCharSelectDialog()
+{
+ if (mCharSelectDialog)
+ mCharSelectDialog->setCharacters(mCharacters);
+}
+
+void CharHandler::unlockCharSelectDialog()
+{
+ if (mCharSelectDialog)
+ mCharSelectDialog->unlock();
+}
diff --git a/src/net/charhandler.h b/src/net/charhandler.h
new file mode 100644
index 000000000..005d995c8
--- /dev/null
+++ b/src/net/charhandler.h
@@ -0,0 +1,112 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHARHANDLER_H
+#define CHARHANDLER_H
+
+#include "localplayer.h"
+#include "logindata.h"
+#include "playerinfo.h"
+
+#include <iosfwd>
+#include <vector>
+
+class CharCreateDialog;
+class CharSelectDialog;
+
+namespace Net
+{
+
+/**
+ * A structure to hold information about a character.
+ */
+struct Character
+{
+ Character() :
+ slot(0),
+ dummy(0)
+ {
+ }
+
+ ~Character()
+ {
+ delete dummy;
+ dummy = 0;
+ }
+
+ int slot; /**< The index in the list of characters */
+ LocalPlayer *dummy; /**< A dummy representing this character */
+ PlayerInfoBackend data;
+};
+
+typedef std::list<Character*> Characters;
+
+class CharHandler
+{
+ public:
+ virtual ~CharHandler()
+ { }
+
+ virtual void setCharSelectDialog(CharSelectDialog *window) = 0;
+
+ virtual void setCharCreateDialog(CharCreateDialog *window) = 0;
+
+ virtual void requestCharacters() = 0;
+
+ virtual void chooseCharacter(Net::Character *character) = 0;
+
+ virtual void newCharacter(const std::string &name, int slot,
+ bool gender, int hairstyle, int hairColor,
+ const std::vector<int> &stats) = 0;
+
+ virtual void deleteCharacter(Net::Character *character) = 0;
+
+ virtual void switchCharacter() = 0;
+
+ virtual unsigned int baseSprite() const = 0;
+
+ virtual unsigned int hairSprite() const = 0;
+
+ virtual unsigned int maxSprite() const = 0;
+
+ protected:
+ CharHandler():
+ mSelectedCharacter(0),
+ mCharSelectDialog(0),
+ mCharCreateDialog(0)
+ {}
+
+ void updateCharSelectDialog();
+ void unlockCharSelectDialog();
+
+ /** The list of available characters. */
+ Net::Characters mCharacters;
+
+ /** The selected character. */
+ Net::Character *mSelectedCharacter;
+
+ CharSelectDialog *mCharSelectDialog;
+ CharCreateDialog *mCharCreateDialog;
+};
+
+} // namespace Net
+
+#endif // CHARHANDLER_H
diff --git a/src/net/chathandler.h b/src/net/chathandler.h
new file mode 100644
index 000000000..20938c78b
--- /dev/null
+++ b/src/net/chathandler.h
@@ -0,0 +1,71 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef CHATHANDLER_H
+#define CHATHANDLER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+class ChatHandler
+{
+ public:
+ virtual ~ChatHandler()
+ { }
+
+ virtual void talk(const std::string &text) = 0;
+
+ virtual void talkRaw(const std::string &text) = 0;
+
+ virtual void me(const std::string &text) = 0;
+
+ virtual void privateMessage(const std::string &recipient,
+ const std::string &text) = 0;
+
+ virtual void channelList() = 0;
+
+ virtual void enterChannel(const std::string &channel,
+ const std::string &password) = 0;
+
+ virtual void quitChannel(int channelId) = 0;
+
+ virtual void sendToChannel(int channelId, const std::string &text) = 0;
+
+ virtual void userList(const std::string &channel) = 0;
+
+ virtual void setChannelTopic(int channelId,
+ const std::string &text) = 0;
+
+ virtual void setUserMode(int channelId, const std::string &name,
+ int mode) = 0;
+
+ virtual void kickUser(int channelId, const std::string &name) = 0;
+
+ virtual void who() = 0;
+
+ virtual void sendRaw(const std::string &args) = 0;
+
+// virtual ~ChatHandler() {}
+};
+}
+
+#endif // CHATHANDLER_H
diff --git a/src/net/download.cpp b/src/net/download.cpp
new file mode 100644
index 000000000..2d391b783
--- /dev/null
+++ b/src/net/download.cpp
@@ -0,0 +1,355 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/download.h"
+
+#include "configuration.h"
+#include "log.h"
+#include "main.h"
+
+#include "utils/stringutils.h"
+
+#include <curl/curl.h>
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+#include <zlib.h>
+
+const char *DOWNLOAD_ERROR_MESSAGE_THREAD
+ = "Could not create download thread!";
+
+/**
+ * Calculates the Alder-32 checksum for the given file.
+ */
+static unsigned long fadler32(FILE *file)
+{
+ // Obtain file size
+ fseek(file, 0, SEEK_END);
+ long fileSize = ftell(file);
+ rewind(file);
+
+ // Calculate Adler-32 checksum
+ char *buffer = static_cast<char*>(malloc(fileSize));
+ const size_t read = fread(buffer, 1, fileSize, file);
+ unsigned long adler = adler32(0L, Z_NULL, 0);
+ adler = adler32(static_cast<uInt>(adler), (Bytef*)buffer, read);
+ free(buffer);
+
+ return adler;
+}
+
+enum
+{
+ OPTIONS_NONE = 0,
+ OPTIONS_MEMORY = 1
+};
+
+namespace Net
+{
+
+Download::Download(void *ptr, const std::string &url,
+ DownloadUpdate updateFunction, bool ignoreError):
+ mPtr(ptr),
+ mUrl(url),
+ mFileName(""),
+ mWriteFunction(NULL),
+ mUpdateFunction(updateFunction),
+ mThread(NULL),
+ mCurl(NULL),
+ mHeaders(NULL),
+ mIgnoreError(ignoreError)
+{
+ mError = static_cast<char*>(malloc(CURL_ERROR_SIZE + 1));
+ mError[0] = 0;
+
+ mOptions.cancel = false;
+}
+
+Download::~Download()
+{
+ if (mHeaders)
+ curl_slist_free_all(mHeaders);
+
+ int status;
+ if (mThread && SDL_GetThreadID(mThread))
+ SDL_WaitThread(mThread, &status);
+ mThread = 0;
+ free(mError);
+}
+
+void Download::addHeader(const std::string &header)
+{
+ mHeaders = curl_slist_append(mHeaders, header.c_str());
+}
+
+void Download::noCache()
+{
+ addHeader("pragma: no-cache");
+ addHeader("Cache-Control: no-cache");
+}
+
+void Download::setFile(const std::string &filename, Sint64 adler32)
+{
+ mOptions.memoryWrite = false;
+ mFileName = filename;
+
+ if (adler32 > -1)
+ {
+ mAdler = static_cast<unsigned long>(adler32);
+ mOptions.checkAdler = true;
+ }
+ else
+ {
+ mOptions.checkAdler = false;
+ }
+}
+
+void Download::setWriteFunction(WriteFunction write)
+{
+ mOptions.memoryWrite = true;
+ mWriteFunction = write;
+}
+
+bool Download::start()
+{
+ logger->log("Starting download: %s", mUrl.c_str());
+
+ mThread = SDL_CreateThread(downloadThread, this);
+
+ if (!mThread)
+ {
+ logger->log1(DOWNLOAD_ERROR_MESSAGE_THREAD);
+ strcpy(mError, DOWNLOAD_ERROR_MESSAGE_THREAD);
+ mUpdateFunction(mPtr, DOWNLOAD_STATUS_THREAD_ERROR, 0, 0);
+ if (!mIgnoreError)
+ return false;
+ }
+
+ return true;
+}
+
+void Download::cancel()
+{
+ logger->log("Canceling download: %s", mUrl.c_str());
+
+ mOptions.cancel = true;
+ if (mThread && SDL_GetThreadID(mThread))
+ SDL_WaitThread(mThread, NULL);
+
+ mThread = NULL;
+}
+
+char *Download::getError()
+{
+ return mError;
+}
+
+int Download::downloadProgress(void *clientp, double dltotal, double dlnow,
+ double ultotal _UNUSED_, double ulnow _UNUSED_)
+{
+ Download *d = reinterpret_cast<Download*>(clientp);
+ if (!d)
+ return -5;
+
+ if (d->mOptions.cancel)
+ {
+ return d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_CANCELLED,
+ static_cast<size_t>(dltotal),
+ static_cast<size_t>(dlnow));
+ return -5;
+ }
+
+ return d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_IDLE,
+ static_cast<size_t>(dltotal),
+ static_cast<size_t>(dlnow));
+}
+
+int Download::downloadThread(void *ptr)
+{
+ int attempts = 0;
+ bool complete = false;
+ Download *d = reinterpret_cast<Download*>(ptr);
+ CURLcode res;
+ std::string outFilename;
+
+ if (!d)
+ return 0;
+
+ if (!d->mOptions.memoryWrite)
+ outFilename = d->mFileName + ".part";
+
+ while (attempts < 3 && !complete && !d->mOptions.cancel)
+ {
+ FILE *file = NULL;
+
+ d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_STARTING, 0, 0);
+
+ if (d->mOptions.cancel)
+ {
+ //need terminate thread?
+ d->mThread = NULL;
+ return 0;
+ }
+
+ d->mCurl = curl_easy_init();
+
+ if (d->mCurl && !d->mOptions.cancel)
+ {
+ logger->log("Downloading: %s", d->mUrl.c_str());
+
+ curl_easy_setopt(d->mCurl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(d->mCurl, CURLOPT_HTTPHEADER, d->mHeaders);
+// curl_easy_setopt(d->mCurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+
+ if (d->mOptions.memoryWrite)
+ {
+ curl_easy_setopt(d->mCurl, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(d->mCurl, CURLOPT_WRITEFUNCTION,
+ d->mWriteFunction);
+ curl_easy_setopt(d->mCurl, CURLOPT_WRITEDATA, d->mPtr);
+ }
+ else
+ {
+ file = fopen(outFilename.c_str(), "w+b");
+ curl_easy_setopt(d->mCurl, CURLOPT_WRITEDATA, file);
+ }
+
+ curl_easy_setopt(d->mCurl, CURLOPT_USERAGENT,
+ strprintf(PACKAGE_EXTENDED_VERSION,
+ branding.getStringValue("appShort").c_str()).c_str());
+ curl_easy_setopt(d->mCurl, CURLOPT_ERRORBUFFER, d->mError);
+ curl_easy_setopt(d->mCurl, CURLOPT_URL, d->mUrl.c_str());
+ curl_easy_setopt(d->mCurl, CURLOPT_NOPROGRESS, 0);
+ curl_easy_setopt(d->mCurl, CURLOPT_PROGRESSFUNCTION,
+ downloadProgress);
+ curl_easy_setopt(d->mCurl, CURLOPT_PROGRESSDATA, ptr);
+ curl_easy_setopt(d->mCurl, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(d->mCurl, CURLOPT_CONNECTTIMEOUT, 30);
+ curl_easy_setopt(d->mCurl, CURLOPT_TIMEOUT, 1800);
+
+ if ((res = curl_easy_perform(d->mCurl)) != 0
+ && !d->mOptions.cancel)
+ {
+ switch (res)
+ {
+ case CURLE_ABORTED_BY_CALLBACK:
+ d->mOptions.cancel = true;
+ break;
+ case CURLE_COULDNT_CONNECT:
+ default:
+ logger->log("curl error %d: %s host: %s",
+ res, d->mError, d->mUrl.c_str());
+ break;
+ }
+
+ if (d->mOptions.cancel)
+ break;
+
+ d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_ERROR, 0, 0);
+
+ if (!d->mOptions.memoryWrite)
+ {
+ fclose(file);
+ ::remove(outFilename.c_str());
+ }
+ attempts++;
+ continue;
+ }
+
+ curl_easy_cleanup(d->mCurl);
+ d->mCurl = 0;
+
+ if (!d->mOptions.memoryWrite)
+ {
+ // Don't check resources.xml checksum
+ if (d->mOptions.checkAdler)
+ {
+ unsigned long adler = fadler32(file);
+
+ if (d->mAdler != adler)
+ {
+ fclose(file);
+
+ // Remove the corrupted file
+ ::remove(d->mFileName.c_str());
+ logger->log("Checksum for file %s failed: (%lx/%lx)",
+ d->mFileName.c_str(),
+ adler, d->mAdler);
+ attempts++;
+ continue; // Bail out here to avoid the renaming
+ }
+ }
+ fclose(file);
+
+ // Any existing file with this name is deleted first, otherwise
+ // the rename will fail on Windows.
+ ::remove(d->mFileName.c_str());
+ ::rename(outFilename.c_str(), d->mFileName.c_str());
+
+ // Check if we can open it and no errors were encountered
+ // during renaming
+ file = fopen(d->mFileName.c_str(), "rb");
+ if (file)
+ {
+ fclose(file);
+ complete = true;
+ }
+ }
+ else
+ {
+ // It's stored in memory, we're done
+ complete = true;
+ }
+ }
+
+ if (d->mCurl)
+ {
+ curl_easy_cleanup(d->mCurl);
+ d->mCurl = 0;
+ }
+
+ if (d->mOptions.cancel)
+ {
+ //need ternibate thread?
+ d->mThread = NULL;
+ return 0;
+ }
+ attempts++;
+ }
+
+ if (d->mOptions.cancel)
+ {
+ // Nothing to do...
+ }
+ else if (!complete || attempts >= 3)
+ {
+ d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_ERROR, 0, 0);
+ }
+ else
+ {
+ d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_COMPLETE, 0, 0);
+ }
+
+ d->mThread = NULL;
+ return 0;
+}
+
+} // namespace Net
diff --git a/src/net/download.h b/src/net/download.h
new file mode 100644
index 000000000..11bca3238
--- /dev/null
+++ b/src/net/download.h
@@ -0,0 +1,123 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+
+#ifndef NET_DOWNLOAD_H
+#define NET_DOWNLOAD_H
+
+#include <SDL_types.h>
+
+#include <stdio.h>
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+enum DownloadStatus
+{
+ DOWNLOAD_STATUS_CANCELLED = -3,
+ DOWNLOAD_STATUS_THREAD_ERROR = -2,
+ DOWNLOAD_STATUS_ERROR = -1,
+ DOWNLOAD_STATUS_STARTING = 0,
+ DOWNLOAD_STATUS_IDLE,
+ DOWNLOAD_STATUS_COMPLETE
+};
+
+typedef int (*DownloadUpdate)(void *ptr, DownloadStatus status,
+ size_t total, size_t remaining);
+
+// Matches what CURL expects
+typedef size_t (*WriteFunction)( void *ptr, size_t size, size_t nmemb,
+ void *stream);
+
+struct SDL_Thread;
+typedef void CURL;
+struct curl_slist;
+
+namespace Net
+{
+class Download
+{
+ public:
+ Download(void *ptr, const std::string &url,
+ DownloadUpdate updateFunction, bool ignoreError = false);
+
+ ~Download();
+
+ void addHeader(const std::string &header);
+
+ /**
+ * Convience method for adding no-cache headers.
+ */
+ void noCache();
+
+ void setFile(const std::string &filename, Sint64 adler32 = -1);
+
+ void setWriteFunction(WriteFunction write);
+
+ /**
+ * Starts the download thread.
+ * @returns true if thread was created
+ * false if the thread could not be made or download wasn't
+ * properly setup
+ */
+ bool start();
+
+ /**
+ * Cancels the download. Returns immediately, the cancelled status will
+ * be noted in the next avialable update call.
+ */
+ void cancel();
+
+ char *getError();
+
+ void setIgnoreError(bool n)
+ { mIgnoreError = n; }
+
+ private:
+ static int downloadThread(void *ptr);
+ static int downloadProgress(void *clientp, double dltotal,
+ double dlnow, double ultotal,
+ double ulnow);
+ void *mPtr;
+ std::string mUrl;
+ struct
+ {
+ unsigned cancel : 1;
+ unsigned memoryWrite: 1;
+ unsigned checkAdler: 1;
+ } mOptions;
+ std::string mFileName;
+ WriteFunction mWriteFunction;
+ unsigned long mAdler;
+ DownloadUpdate mUpdateFunction;
+ SDL_Thread *mThread;
+ CURL *mCurl;
+ curl_slist *mHeaders;
+ char *mError;
+ bool mIgnoreError;
+};
+
+} // namespace Net
+
+#endif // NET_DOWNLOAD_H
diff --git a/src/net/gamehandler.h b/src/net/gamehandler.h
new file mode 100644
index 000000000..a0208f6c7
--- /dev/null
+++ b/src/net/gamehandler.h
@@ -0,0 +1,62 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MAPHANDLER_H
+#define MAPHANDLER_H
+
+#include "logindata.h"
+
+#include <iosfwd>
+
+namespace Net
+{
+
+class GameHandler
+{
+ public:
+ virtual ~GameHandler()
+ {}
+
+ virtual void connect() = 0;
+
+ virtual bool isConnected() = 0;
+
+ virtual void disconnect() = 0;
+
+ virtual void who() = 0;
+
+ virtual void quit() = 0;
+
+ virtual void ping(int tick) = 0;
+
+ virtual bool removeDeadBeings() const = 0;
+
+ virtual void disconnect2() = 0;
+
+ /**
+ * Tells whether the protocol is using the MP status bar
+ */
+ virtual bool canUseMagicBar() const = 0;
+};
+
+} // namespace Net
+
+#endif // MAPHANDLER_H
diff --git a/src/net/generalhandler.h b/src/net/generalhandler.h
new file mode 100644
index 000000000..9454bc7e1
--- /dev/null
+++ b/src/net/generalhandler.h
@@ -0,0 +1,50 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "client.h"
+#include "main.h"
+
+#ifndef GENERALHANDLER_H
+#define GENERALHANDLER_H
+
+namespace Net
+{
+
+class GeneralHandler
+{
+ public:
+ virtual ~GeneralHandler()
+ { }
+
+ virtual void load() = 0;
+
+ virtual void reload() = 0;
+
+ virtual void unload() = 0;
+
+ virtual void flushNetwork() = 0;
+
+ virtual void clearHandlers() = 0;
+};
+
+} // namespace Net
+
+#endif // GENERALHANDLER_H
diff --git a/src/net/guildhandler.h b/src/net/guildhandler.h
new file mode 100644
index 000000000..6a269ff74
--- /dev/null
+++ b/src/net/guildhandler.h
@@ -0,0 +1,76 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef GUILDHANDLER_H
+#define GUILDHANDLER_H
+
+#include "guild.h"
+
+#include <iosfwd>
+
+class Being;
+
+namespace Net
+{
+
+class GuildHandler
+{
+ public:
+ virtual ~GuildHandler()
+ { }
+
+ virtual bool isSupported()
+ { return false; }
+
+ virtual void create(const std::string &name) = 0;
+
+ virtual void invite(int guildId, const std::string &name) = 0;
+
+ virtual void invite(int guildId, Being *being) = 0;
+
+ virtual void inviteResponse(int guildId, bool response) = 0;
+
+ virtual void leave(int guildId) = 0;
+
+ virtual void kick(GuildMember *member, std::string reason = "") = 0;
+
+ virtual void chat(int guildId, const std::string &text) = 0;
+
+ virtual void memberList(int guildId) = 0;
+
+ virtual void info(int guildId) = 0;
+
+ virtual void changeMemberPostion(GuildMember *member, int level) = 0;
+
+ virtual void requestAlliance(int guildId, int otherGuildId) = 0;
+
+ virtual void requestAllianceResponse(int guildId, int otherGuildId,
+ bool response) = 0;
+
+ virtual void endAlliance(int guildId, int otherGuildId) = 0;
+
+ virtual void changeNotice(int guildId, std::string msg1,
+ std::string msg2) = 0;
+};
+
+}
+
+#endif // GUILDHANDLER_H
diff --git a/src/net/inventoryhandler.h b/src/net/inventoryhandler.h
new file mode 100644
index 000000000..18ec6968b
--- /dev/null
+++ b/src/net/inventoryhandler.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef INVENTORYHANDLER_H
+#define INVENTORYHANDLER_H
+
+#include "inventory.h"
+#include "item.h"
+
+#include <iosfwd>
+
+namespace Net
+{
+
+class InventoryHandler
+{
+ public:
+ virtual ~InventoryHandler()
+ { }
+
+ virtual void equipItem(const Item *item) = 0;
+
+ virtual void unequipItem(const Item *item) = 0;
+
+ virtual void useItem(const Item *item) = 0;
+
+ virtual void dropItem(const Item *item, int amount) = 0;
+
+ virtual bool canSplit(const Item *item) = 0;
+
+ virtual void splitItem(const Item *item, int amount) = 0;
+
+ virtual void moveItem(int oldIndex, int newIndex) = 0;
+
+ virtual void openStorage(int type) = 0;
+
+ virtual void closeStorage(int type) = 0;
+
+ //void changeCart() = 0;
+
+ virtual void moveItem(int source, int slot, int amount,
+ int destination) = 0;
+
+ // TODO: fix/remove me
+ virtual size_t getSize(int type) const = 0;
+
+ virtual int convertFromServerSlot(int eAthenaSlot) = 0;
+
+// virtual ~InventoryHandler() {}
+};
+
+} // namespace Net
+
+#endif // INVENTORYHANDLER_H
diff --git a/src/net/logindata.h b/src/net/logindata.h
new file mode 100644
index 000000000..5617cea32
--- /dev/null
+++ b/src/net/logindata.h
@@ -0,0 +1,95 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LOGINDATA_H
+#define LOGINDATA_H
+
+#include "being.h"
+
+#include "net/serverinfo.h"
+
+#include <string>
+
+class LoginData
+{
+ public:
+ LoginData():
+ username(""),
+ password(""),
+ newPassword(""),
+ updateHost(""),
+ updateType(0),
+ email(""),
+ captchaResponse(""),
+ gender(GENDER_UNSPECIFIED),
+ remember(false),
+ registerLogin(false)
+ {
+ resetCharacterSlots();
+ }
+
+ enum UpdateType
+ {
+ Upd_Normal = 0,
+ Upd_Close = 1,
+ Upd_Skip = 2,
+ Upd_Custom = 4
+ };
+
+ std::string username;
+ std::string password;
+ std::string newPassword;
+ std::string updateHost;
+ int updateType;
+
+ std::string email;
+ std::string captchaResponse;
+
+ Gender gender;
+
+ bool remember; /**< Whether to store the username. */
+ bool registerLogin; /**< Whether an account
+ is being registered. */
+
+ unsigned short characterSlots; /**< The number of character slots */
+
+ void clear()
+ {
+ username.clear();
+ password.clear();
+ newPassword.clear();
+ updateHost.clear();
+ updateType = Upd_Normal;
+ email.clear();
+ captchaResponse.clear();
+ gender = GENDER_UNSPECIFIED;
+ resetCharacterSlots();
+ }
+ /**
+ * Initialize character slots to 3 for TmwAthena compatibility
+ */
+ void resetCharacterSlots()
+ {
+ characterSlots = 3; // Default value, used for TmwAthena.
+ }
+};
+
+#endif // LOGINDATA_H
diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h
new file mode 100644
index 000000000..5511e46a4
--- /dev/null
+++ b/src/net/loginhandler.h
@@ -0,0 +1,112 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef LOGINHANDLER_H
+#define LOGINHANDLER_H
+
+#include "net/logindata.h"
+#include "net/serverinfo.h"
+#include "net/worldinfo.h"
+
+#include <iosfwd>
+#include <vector>
+
+namespace Net
+{
+
+class LoginHandler
+{
+ public:
+ /**
+ * This enum describes options specific to either eAthena or Manaserv.
+ * By querying for these flags, the GUI can adapt to the current
+ * server type dynamically.
+ */
+ enum OptionalAction
+ {
+ Unregister = 0x1,
+ ChangeEmail = 0x2,
+ SetEmailOnRegister = 0x4,
+ SetGenderOnRegister = 0x8
+ };
+
+ void setServer(const ServerInfo &server)
+ { mServer = server; }
+
+ ServerInfo getServer() const
+ { return mServer; }
+
+ virtual void connect() = 0;
+
+ virtual bool isConnected() = 0;
+
+ virtual void disconnect() = 0;
+
+ /**
+ * @see OptionalAction
+ */
+ virtual int supportedOptionalActions() const = 0;
+
+ virtual bool isRegistrationEnabled() = 0;
+
+ virtual void getRegistrationDetails() = 0;
+
+ virtual unsigned int getMinUserNameLength() const
+ { return 4; }
+
+ virtual unsigned int getMaxUserNameLength() const
+ { return 25; }
+
+ virtual unsigned int getMinPasswordLength() const
+ { return 4; }
+
+ virtual unsigned int getMaxPasswordLength() const
+ { return 255; }
+
+ virtual void loginAccount(LoginData *loginData) = 0;
+
+ virtual void logout() = 0;
+
+ virtual void changeEmail(const std::string &email) = 0;
+
+ virtual void changePassword(const std::string &username,
+ const std::string &oldPassword,
+ const std::string &newPassword) = 0;
+
+ virtual void chooseServer(unsigned int server) = 0;
+
+ virtual void registerAccount(LoginData *loginData) = 0;
+
+ virtual void unregisterAccount(const std::string &username,
+ const std::string &password) = 0;
+
+ virtual Worlds getWorlds() const = 0;
+
+ virtual ~LoginHandler ()
+ { }
+
+ protected:
+ ServerInfo mServer;
+};
+
+} // namespace Net
+
+#endif // LOGINHANDLER_H
diff --git a/src/net/manaserv/adminhandler.cpp b/src/net/manaserv/adminhandler.cpp
new file mode 100644
index 000000000..cd71f00a2
--- /dev/null
+++ b/src/net/manaserv/adminhandler.cpp
@@ -0,0 +1,93 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/adminhandler.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+extern Net::AdminHandler *adminHandler;
+
+namespace ManaServ
+{
+
+extern Connection *chatServerConnection;
+
+AdminHandler::AdminHandler()
+{
+ adminHandler = this;
+}
+
+void AdminHandler::announce(const std::string &text)
+{
+ MessageOut msg(PCMSG_ANNOUNCE);
+ msg.writeString(text);
+ chatServerConnection->send(msg);
+}
+
+void AdminHandler::localAnnounce(const std::string &text _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::hide(bool hide _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::kick(int playerId _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::kick(const std::string &name _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::ban(int playerId _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::ban(const std::string &name _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::unban(int playerId _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::unban(const std::string &name _UNUSED_)
+{
+ // TODO
+}
+
+void AdminHandler::mute(int playerId _UNUSED_, int type _UNUSED_,
+ int limit _UNUSED_)
+{
+ // TODO
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/adminhandler.h b/src/net/manaserv/adminhandler.h
new file mode 100644
index 000000000..596ccbccd
--- /dev/null
+++ b/src/net/manaserv/adminhandler.h
@@ -0,0 +1,64 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_ADMINHANDLER_H
+#define NET_MANASERV_ADMINHANDLER_H
+
+#include "net/adminhandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class AdminHandler : public Net::AdminHandler
+{
+ public:
+ AdminHandler();
+
+ void announce(const std::string &text);
+
+ void localAnnounce(const std::string &text);
+
+ void hide(bool hide);
+
+ void kick(int playerId);
+
+ void kick(const std::string &name);
+
+ void ban(int playerId);
+
+ void ban(const std::string &name);
+
+ void unban(int playerId);
+
+ void unban(const std::string &name);
+
+ void mute(int playerId, int type, int limit);
+};
+
+} // namespace ManaServ
+
+#endif
diff --git a/src/net/manaserv/attributes.cpp b/src/net/manaserv/attributes.cpp
new file mode 100644
index 000000000..7cc0e053d
--- /dev/null
+++ b/src/net/manaserv/attributes.cpp
@@ -0,0 +1,411 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/attributes.h"
+
+#include "log.h"
+#include "playerinfo.h"
+
+#include "gui/statuswindow.h"
+
+#include "resources/itemdb.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <list>
+#include <map>
+
+#define DEFAULT_ATTRIBUTESDB_FILE "attributes.xml"
+#define DEFAULT_POINTS 60
+#define DEFAULT_MIN_PTS 1
+#define DEFAULT_MAX_PTS 20
+
+namespace ManaServ
+{
+namespace Attributes
+{
+ typedef struct
+ {
+ unsigned int id;
+ std::string name;
+ std::string description;
+ /** Whether the attribute value can be modified by the player */
+ bool modifiable;
+ /**< Attribute scope. */
+ std::string scope;
+ /** The playerInfo core Id the attribute is linked with or -1 if not */
+ int playerInfoId;
+ } Attribute;
+
+ /** Map for attributes. */
+ typedef std::map<unsigned int, Attribute> AttributeMap;
+ static AttributeMap attributes;
+
+ /** tags = effects on attributes. */
+ typedef std::map< std::string, std::string > TagMap;
+ static TagMap tags;
+
+ /** List of modifiable attribute names used at character's creation. */
+ static std::vector<std::string> attributeLabels;
+
+ /** Characters creation points. */
+ static unsigned int creationPoints = 0;
+ static unsigned int attributeMinimum = 0;
+ static unsigned int attributeMaximum = 0;
+
+ unsigned int getCreationPoints()
+ { return creationPoints; }
+
+ unsigned int getAttributeMinimum()
+ { return attributeMinimum; }
+
+ unsigned int getAttributeMaximum()
+ { return attributeMaximum; }
+
+ std::vector<std::string>& getLabels()
+ { return attributeLabels; }
+
+ /**
+ * Fills the list of base attribute labels.
+ */
+ static void fillLabels()
+ {
+ // Fill up the modifiable attribute label list.
+ attributeLabels.clear();
+ AttributeMap::const_iterator it, it_end;
+ for (it = attributes.begin(), it_end = attributes.end();
+ it != it_end; it++)
+ {
+ if (it->second.modifiable && (it->second.scope == "character"
+ || it->second.scope == "being"))
+ {
+ attributeLabels.push_back(it->second.name + ":");
+ }
+ }
+ }
+
+ /**
+ * Fills the list of base attribute labels.
+ */
+ static int getPlayerInfoIdFromAttrType(std::string attrType)
+ {
+ toLower(attrType);
+ if (attrType == "level")
+ return ::LEVEL;
+ else if (attrType == "hp")
+ return ::HP;
+ else if (attrType == "max-hp")
+ return ::MAX_HP;
+ else if (attrType == "mp")
+ return ::MP;
+ else if (attrType == "max-mp")
+ return ::MAX_MP;
+ else if (attrType == "exp")
+ return ::EXP;
+ else if (attrType == "exp-needed")
+ return ::EXP_NEEDED;
+ else if (attrType == "money")
+ return ::MONEY;
+ else if (attrType == "total-weight")
+ return ::TOTAL_WEIGHT;
+ else if (attrType == "max-weight")
+ return ::MAX_WEIGHT;
+ else if (attrType == "skill-points")
+ return ::SKILL_POINTS;
+ else if (attrType == "char-points")
+ return ::CHAR_POINTS;
+ else if (attrType == "corr-points")
+ return ::CORR_POINTS;
+ else if (attrType == "none")
+ return -2; // Used to hide the attribute display.
+
+ return -1; // Not linked to a playerinfo stat.
+ }
+
+ int getPlayerInfoIdFromAttrId(int attrId)
+ {
+ AttributeMap::const_iterator it = attributes.find(attrId);
+
+ if (it != attributes.end())
+ return it->second.playerInfoId;
+
+ return -1;
+ }
+
+ static void loadBuiltins()
+ {
+ {
+ Attribute a;
+ a.id = 16;
+ a.name = _("Strength");
+ a.description = "";
+ a.modifiable = true;
+ a.scope = "character";
+ a.playerInfoId = -1;
+
+ attributes[a.id] = a;
+ tags.insert(std::make_pair("str", _("Strength %+.1f")));
+ }
+
+ {
+ Attribute a;
+ a.id = 17;
+ a.name = _("Agility");
+ a.description = "";
+ a.modifiable = true;
+ a.scope = "character";
+ a.playerInfoId = -1;
+
+ attributes[a.id] = a;
+ tags.insert(std::make_pair("agi", _("Agility %+.1f")));
+ }
+
+ {
+ Attribute a;
+ a.id = 18;
+ a.name = _("Dexterity");
+ a.description = "";
+ a.modifiable = true;
+ a.scope = "character";
+ a.playerInfoId = -1;
+
+ attributes[a.id] = a;
+ tags.insert(std::make_pair("dex", _("Dexterity %+.1f")));
+ }
+
+ {
+ Attribute a;
+ a.id = 19;
+ a.name = _("Vitality");
+ a.description = "";
+ a.modifiable = true;
+ a.scope = "character";
+ a.playerInfoId = -1;
+
+ attributes[a.id] = a;
+ tags.insert(std::make_pair("vit", _("Vitality %+.1f")));
+ }
+
+ {
+ Attribute a;
+ a.id = 20;
+ a.name = _("Intelligence");
+ a.description = "";
+ a.modifiable = true;
+ a.scope = "character";
+ a.playerInfoId = -1;
+
+ attributes[a.id] = a;
+ tags.insert(std::make_pair("int", _("Intelligence %+.1f")));
+ }
+
+ {
+ Attribute a;
+ a.id = 21;
+ a.name = _("Willpower");
+ a.description = "";
+ a.modifiable = true;
+ a.scope = "character";
+ a.playerInfoId = -1;
+
+ attributes[a.id] = a;
+ tags.insert(std::make_pair("wil", _("Willpower %+.1f")));
+ }
+ }
+
+ void load()
+ {
+ logger->log("Initializing attributes database...");
+
+ XML::Document doc(DEFAULT_ATTRIBUTESDB_FILE);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "attributes"))
+ {
+ logger->log("Attributes: Error while loading "
+ DEFAULT_ATTRIBUTESDB_FILE ". Using Built-ins.");
+ loadBuiltins();
+ fillLabels();
+ return;
+ }
+
+ for_each_xml_child_node(node, rootNode)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "attribute"))
+ {
+ int id = XML::getProperty(node, "id", 0);
+
+ if (!id)
+ {
+ logger->log("Attributes: Invalid or missing stat ID in "
+ DEFAULT_ATTRIBUTESDB_FILE "!");
+ continue;
+ }
+ else if (attributes.find(id) != attributes.end())
+ {
+ logger->log("Attributes: Redefinition of stat ID %d", id);
+ }
+
+ std::string name = XML::getProperty(node, "name", "");
+
+ if (name.empty())
+ {
+ logger->log("Attributes: Invalid or missing stat name in "
+ DEFAULT_ATTRIBUTESDB_FILE "!");
+ continue;
+ }
+
+ // Create the attribute.
+ Attribute a;
+ a.id = id;
+ a.name = name;
+ a.description = XML::getProperty(node, "desc", "");
+ a.modifiable = XML::getBoolProperty(node, "modifiable", false);
+ a.scope = XML::getProperty(node, "scope", "none");
+ a.playerInfoId = getPlayerInfoIdFromAttrType(
+ XML::getProperty(node, "player-info", ""));
+
+ attributes[id] = a;
+
+ unsigned int count = 0;
+ for_each_xml_child_node(effectNode, node)
+ {
+ if (!xmlStrEqual(effectNode->name, BAD_CAST "modifier"))
+ continue;
+ ++count;
+ std::string tag = XML::getProperty(effectNode, "tag", "");
+ if (tag.empty())
+ {
+ if (name.empty())
+ {
+ logger->log("Attribute modifier in attribute"
+ " %u:%s: Empty name definition "
+ "on empty tag definition, skipping.",
+ a.id, a.name.c_str());
+ --count;
+ continue;
+ }
+ tag = name.substr(0, name.size() > 3
+ ? 3 : name.size());
+ tag = toLower(tag) + toString(count);
+ }
+
+ std::string effect = XML::getProperty(
+ effectNode, "effect", "");
+
+ if (effect.empty())
+ {
+ if (name.empty())
+ {
+ logger->log("Attribute modifier in attribute"
+ " %u:%s: Empty name definition "
+ "on empty effect definition, skipping.",
+ a.id, a.name.c_str());
+ --count;
+ continue;
+ }
+ else
+ {
+ effect = name + " %+f";
+ }
+ }
+ tags.insert(std::make_pair(tag, effect));
+ }
+ logger->log("Found %d tags for attribute %d.", count, id);
+
+ }// End attribute
+ else if (xmlStrEqual(node->name, BAD_CAST "points"))
+ {
+ creationPoints = XML::getProperty(
+ node, "start", DEFAULT_POINTS);
+ attributeMinimum = XML::getProperty(
+ node, "minimum", DEFAULT_MIN_PTS);
+ attributeMaximum = XML::getProperty(
+ node, "maximum", DEFAULT_MAX_PTS);
+ logger->log("Loaded points: start: %i, min: %i, max: %i.",
+ creationPoints, attributeMinimum, attributeMaximum);
+ }
+ else
+ {
+ continue;
+ }
+ }
+ logger->log("Found %d tags for %d attributes.", int(tags.size()),
+ int(attributes.size()));
+
+ fillLabels();
+
+ // Sanity checks on starting points
+ float modifiableAttributeCount = (float) attributeLabels.size();
+ float averageValue = 1;
+ if (modifiableAttributeCount)
+ averageValue = ((float) creationPoints) / modifiableAttributeCount;
+
+ if (averageValue > attributeMaximum || averageValue < attributeMinimum
+ || creationPoints < 1)
+ {
+ logger->log("Attributes: Character's point values make "
+ "the character's creation impossible. "
+ "Switch back to defaults.");
+ creationPoints = DEFAULT_POINTS;
+ attributeMinimum = DEFAULT_MIN_PTS;
+ attributeMaximum = DEFAULT_MAX_PTS;
+ }
+ }
+
+ void unload()
+ {
+ attributes.clear();
+ }
+
+ void informItemDB()
+ {
+ std::list<ItemDB::Stat> dbStats;
+
+ TagMap::const_iterator it, it_end;
+ for (it = tags.begin(), it_end = tags.end(); it != it_end; ++it)
+ dbStats.push_back(ItemDB::Stat(it->first, it->second));
+
+ ItemDB::setStatsList(dbStats);
+ }
+
+ void informStatusWindow()
+ {
+ if (!statusWindow)
+ return;
+
+ AttributeMap::const_iterator it, it_end;
+ for (it = attributes.begin(), it_end = attributes.end();
+ it != it_end; it++)
+ {
+ if (it->second.playerInfoId == -1
+ && (it->second.scope == "character"
+ || it->second.scope == "being"))
+ {
+ statusWindow->addAttribute(it->second.id, it->second.name,
+ it->second.modifiable, it->second.description);
+ }
+ }
+ }
+
+} // namespace Attributes
+} // namespace ManaServ
diff --git a/src/net/manaserv/attributes.h b/src/net/manaserv/attributes.h
new file mode 100644
index 000000000..216bae411
--- /dev/null
+++ b/src/net/manaserv/attributes.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_ATTRIBUTES_H
+#define NET_MANASERV_ATTRIBUTES_H
+
+#include <string>
+#include <vector>
+
+namespace ManaServ
+{
+
+namespace Attributes
+{
+ void load();
+
+ void unload();
+
+ void informItemDB();
+
+ void informStatusWindow();
+
+ /**
+ * Returns the list of base attribute labels.
+ */
+ std::vector<std::string>& getLabels();
+
+ /**
+ * Give back the corresponding playerinfo Id from the attribute id
+ * defined in the xml file.
+ */
+ int getPlayerInfoIdFromAttrId(int attrId);
+
+ /**
+ * Give the attribute points given to a character
+ * at its creation.
+ */
+ unsigned int getCreationPoints();
+
+ /**
+ * Give the minimum attribute point possible
+ * at character's creation.
+ */
+ unsigned int getAttributeMinimum();
+
+ /**
+ * Give the maximum attribute point possible
+ * at character's creation.
+ */
+ unsigned int getAttributeMaximum();
+
+} // namespace Attributes
+} // namespace ManaServ
+
+#endif // NET_MANASERV_ATTRIBUTES_H
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp
new file mode 100644
index 000000000..ae6a417e5
--- /dev/null
+++ b/src/net/manaserv/beinghandler.cpp
@@ -0,0 +1,385 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/beinghandler.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "client.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "particle.h"
+
+#include "gui/okdialog.h"
+
+#include "net/messagein.h"
+#include "net/net.h"
+
+#include "net/manaserv/playerhandler.h"
+#include "net/manaserv/protocol.h"
+
+#include "resources/colordb.h"
+
+#include "utils/gettext.h"
+
+extern Net::BeingHandler *beingHandler;
+
+namespace ManaServ
+{
+
+BeingHandler::BeingHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_BEING_ATTACK,
+ GPMSG_BEING_ENTER,
+ GPMSG_BEING_LEAVE,
+ GPMSG_BEINGS_MOVE,
+ GPMSG_BEINGS_DAMAGE,
+ GPMSG_BEING_ACTION_CHANGE,
+ GPMSG_BEING_LOOKS_CHANGE,
+ GPMSG_BEING_DIR_CHANGE,
+ 0
+ };
+ handledMessages = _messages;
+ beingHandler = this;
+}
+
+void BeingHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_BEING_ENTER:
+ handleBeingEnterMessage(msg);
+ break;
+ case GPMSG_BEING_LEAVE:
+ handleBeingLeaveMessage(msg);
+ break;
+ case GPMSG_BEINGS_MOVE:
+ handleBeingsMoveMessage(msg);
+ break;
+ case GPMSG_BEING_ATTACK:
+ handleBeingAttackMessage(msg);
+ break;
+ case GPMSG_BEINGS_DAMAGE:
+ handleBeingsDamageMessage(msg);
+ break;
+ case GPMSG_BEING_ACTION_CHANGE:
+ handleBeingActionChangeMessage(msg);
+ break;
+ case GPMSG_BEING_LOOKS_CHANGE:
+ handleBeingLooksChangeMessage(msg);
+ break;
+ case GPMSG_BEING_DIR_CHANGE:
+ handleBeingDirChangeMessage(msg);
+ break;
+ default:
+ break;
+ }
+}
+
+Vector BeingHandler::giveSpeedInPixelsPerTicks(float speedInTilesPerSeconds)
+{
+ Vector speedInTicks;
+ Game *game = Game::instance();
+ Map *map = 0;
+ if (game)
+ {
+ map = game->getCurrentMap();
+ if (map)
+ {
+ speedInTicks.x = speedInTilesPerSeconds
+ * (float)map->getTileWidth()
+ / 1000 * (float) MILLISECONDS_IN_A_TICK;
+ speedInTicks.y = speedInTilesPerSeconds
+ * (float)map->getTileHeight()
+ / 1000 * (float) MILLISECONDS_IN_A_TICK;
+ }
+ }
+
+ if (!game || !map)
+ {
+ speedInTicks.x = speedInTicks.y = 0;
+ logger->log1("Manaserv::BeingHandler: Speed wasn't given back"
+ " because game/Map not initialized.");
+ }
+ // We don't use z for now.
+ speedInTicks.z = 0;
+
+ return speedInTicks;
+}
+
+static void handleLooks(Being *being, Net::MessageIn &msg)
+{
+ // Order of sent slots. Has to be in sync with the server code.
+ static int const nb_slots = 4;
+ static int const slots[nb_slots] =
+ {
+ SPRITE_WEAPON,
+ SPRITE_HAT,
+ SPRITE_TOPCLOTHES,
+ SPRITE_BOTTOMCLOTHES
+ };
+
+ int mask = msg.readInt8();
+
+ if (mask & (1 << 7))
+ {
+ // The equipment has to be cleared first.
+ for (int i = 0; i < nb_slots; ++i)
+ being->setSprite(slots[i], 0);
+ }
+
+ // Fill slots enumerated by the bitmask.
+ for (int i = 0; i < nb_slots; ++i)
+ {
+ if (!(mask & (1 << i))) continue;
+ int id = msg.readInt16();
+ being->setSprite(slots[i], id, "", (slots[i] == SPRITE_WEAPON));
+ }
+}
+
+void BeingHandler::handleBeingEnterMessage(Net::MessageIn &msg)
+{
+ int type = msg.readInt8();
+ int id = msg.readInt16();
+ Being::Action action = (Being::Action)msg.readInt8();
+ int px = msg.readInt16();
+ int py = msg.readInt16();
+ Being *being;
+
+ switch (type)
+ {
+ case OBJECT_CHARACTER:
+ {
+ std::string name = msg.readString();
+ if (player_node->getName() == name)
+ {
+ being = player_node;
+ being->setId(id);
+ }
+ else
+ {
+ being = actorSpriteManager->createBeing(id,
+ ActorSprite::PLAYER, 0);
+ being->setName(name);
+ }
+ int hs = msg.readInt8(), hc = msg.readInt8();
+ being->setSprite(SPRITE_HAIR, hs * -1, ColorDB::get(hc));
+ being->setGender(msg.readInt8() == GENDER_MALE ?
+ GENDER_MALE : GENDER_FEMALE);
+ handleLooks(being, msg);
+ } break;
+
+ case OBJECT_MONSTER:
+ case OBJECT_NPC:
+ {
+ int subtype = msg.readInt16();
+ being = actorSpriteManager->createBeing(id, type == OBJECT_MONSTER
+ ? ActorSprite::MONSTER : ActorSprite::NPC, subtype);
+ std::string name = msg.readString();
+ if (name.length() > 0) being->setName(name);
+ } break;
+
+ default:
+ return;
+ }
+
+ being->setPosition(px, py);
+ being->setDestination(px, py);
+ being->setAction(action);
+}
+
+void BeingHandler::handleBeingLeaveMessage(Net::MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being)
+ return;
+
+ actorSpriteManager->destroy(being);
+}
+
+void BeingHandler::handleBeingsMoveMessage(Net::MessageIn &msg)
+{
+ while (msg.getUnreadLength())
+ {
+ int id = msg.readInt16();
+ int flags = msg.readInt8();
+ Being *being = actorSpriteManager->findBeing(id);
+ int sx = 0;
+ int sy = 0;
+ int speed = 0;
+
+ if (flags & MOVING_POSITION)
+ {
+ sx = msg.readInt16();
+ sy = msg.readInt16();
+ speed = msg.readInt8();
+ }
+ if (!being || !(flags & (MOVING_POSITION | MOVING_DESTINATION)))
+ {
+ continue;
+ }
+ if (speed)
+ {
+ /*
+ * The being's speed is transfered in tiles per second * 10
+ * to keep it transferable in a Byte.
+ * We set it back to tiles per second and in a float.
+ * Then, we translate it in pixels per ticks, to correspond
+ * with the Being::logic() function calls
+ * @see MILLISECONDS_IN_A_TICK
+ */
+ being->setWalkSpeed(
+ giveSpeedInPixelsPerTicks((float) speed / 10));
+ }
+
+ // Ignore messages from the server for the local player
+ if (being == player_node)
+ continue;
+
+ if (flags & MOVING_POSITION)
+ {
+ being->setDestination(sx, sy);
+ }
+ }
+}
+
+void BeingHandler::handleBeingAttackMessage(Net::MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ const int direction = msg.readInt8();
+ const int attackType = msg.readInt8();
+
+ if (!being)
+ return;
+
+ switch (direction)
+ {
+ case DIRECTION_UP: being->setDirection(Being::UP); break;
+ case DIRECTION_DOWN: being->setDirection(Being::DOWN); break;
+ case DIRECTION_LEFT: being->setDirection(Being::LEFT); break;
+ case DIRECTION_RIGHT: being->setDirection(Being::RIGHT); break;
+ default: break;
+ }
+
+ being->setAction(Being::ATTACK, attackType);
+}
+
+void BeingHandler::handleBeingsDamageMessage(Net::MessageIn &msg)
+{
+ while (msg.getUnreadLength())
+ {
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ int damage = msg.readInt16();
+ if (being)
+ {
+ being->takeDamage(0, damage, Being::HIT);
+ }
+ }
+}
+
+void BeingHandler::handleBeingActionChangeMessage(Net::MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ Being::Action action = (Being::Action) msg.readInt8();
+ if (!being)
+ return;
+
+ being->setAction(action);
+
+ if (action == Being::DEAD && being == player_node)
+ {
+ static char const *const deadMsg[] =
+ {
+ _("You are dead."),
+ _("We regret to inform you that your character was killed in "
+ "battle."),
+ _("You are not that alive anymore."),
+ _("The cold hands of the grim reaper are grabbing for your soul."),
+ _("Game Over!"),
+ _("No, kids. Your character did not really die. It... err... "
+ "went to a better place."),
+ _("Your plan of breaking your enemies weapon by bashing it with "
+ "your throat failed."),
+ _("I guess this did not run too well."),
+ _("Do you want your possessions identified?"), // Nethack reference
+ _("Sadly, no trace of you was ever found..."), // Secret of Mana
+ // reference
+ _("Annihilated."), // Final Fantasy VI reference
+ _("Looks like you got your head handed to you."), // Earthbound
+ // reference
+ _("You screwed up again, dump your body down the tubes and get "
+ "you another one.") // Leisure Suit Larry 1 Reference
+
+ };
+ std::string message(deadMsg[rand() % 13]);
+ message.append(std::string(" ") + _("Press OK to respawn."));
+ OkDialog *dlg = new OkDialog(_("You Died"), message, false);
+ dlg->addActionListener(&(ManaServ::respawnListener));
+ }
+}
+
+void BeingHandler::handleBeingLooksChangeMessage(Net::MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being || being->getType() != ActorSprite::PLAYER)
+ return;
+ handleLooks(being, msg);
+ if (msg.getUnreadLength())
+ {
+ int style = msg.readInt16();
+ int color = msg.readInt16();
+ being->setSprite(SPRITE_HAIR, style * -1, ColorDB::get(color));
+ }
+}
+
+void BeingHandler::handleBeingDirChangeMessage(Net::MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being)
+ return;
+ int data = msg.readInt8();
+
+ // The direction for the player's character is handled on client side.
+ if (being != player_node)
+ {
+ switch (data)
+ {
+ case DIRECTION_UP: being->setDirection(Being::UP); break;
+ case DIRECTION_DOWN: being->setDirection(Being::DOWN); break;
+ case DIRECTION_LEFT: being->setDirection(Being::LEFT); break;
+ case DIRECTION_RIGHT: being->setDirection(Being::RIGHT); break;
+ default: break;
+ }
+ }
+}
+
+void BeingHandler::requestNameById(int id _UNUSED_)
+{
+}
+
+void BeingHandler::undress(Being *being _UNUSED_)
+{
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/beinghandler.h b/src/net/manaserv/beinghandler.h
new file mode 100644
index 000000000..7ed657520
--- /dev/null
+++ b/src/net/manaserv/beinghandler.h
@@ -0,0 +1,73 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_BEINGHANDLER_H
+#define NET_MANASERV_BEINGHANDLER_H
+
+#include "net/manaserv/messagehandler.h"
+
+#include "net/beinghandler.h"
+
+#include "vector.h"
+#include "map.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class BeingHandler : public MessageHandler, public Net::BeingHandler
+{
+ public:
+ BeingHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ /**
+ * Translate a given speed in tiles per seconds
+ * into pixels per ticks.
+ * Used to optimize Being::logic() calls.
+ * @see MILLISECONDS_IN_A_TICKS
+ */
+ static Vector giveSpeedInPixelsPerTicks(float speedInTilesPerSeconds);
+
+ void requestNameById(int id);
+
+ void undress(Being *being);
+
+ private:
+ void handleBeingAttackMessage(Net::MessageIn &msg);
+ void handleBeingEnterMessage(Net::MessageIn &msg);
+ void handleBeingLeaveMessage(Net::MessageIn &msg);
+ void handleBeingsMoveMessage(Net::MessageIn &msg);
+ void handleBeingsDamageMessage(Net::MessageIn &msg);
+ void handleBeingActionChangeMessage(Net::MessageIn &msg);
+ void handleBeingLooksChangeMessage(Net::MessageIn &msg);
+ void handleBeingDirChangeMessage(Net::MessageIn &msg);
+};
+
+} // namespace ManaServ
+
+#endif
diff --git a/src/net/manaserv/buysellhandler.cpp b/src/net/manaserv/buysellhandler.cpp
new file mode 100644
index 000000000..dbfdfd46d
--- /dev/null
+++ b/src/net/manaserv/buysellhandler.cpp
@@ -0,0 +1,132 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/buysellhandler.h"
+
+#include "actorspritemanager.h"
+#include "item.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "shopitem.h"
+
+#include "gui/buy.h"
+#include "gui/chat.h"
+#include "gui/sell.h"
+
+#include "net/messagein.h"
+#include "net/net.h"
+
+#include "net/manaserv/protocol.h"
+
+
+extern Net::BuySellHandler *buySellHandler;
+
+namespace ManaServ
+{
+
+BuySellHandler::BuySellHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_NPC_BUY,
+ GPMSG_NPC_SELL,
+ 0
+ };
+ handledMessages = _messages;
+ buySellHandler = this;
+}
+
+void BuySellHandler::handleMessage(Net::MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being || being->getType() != ActorSprite::NPC)
+ {
+ return;
+ }
+
+ int npcId = being->getId();
+
+ switch (msg.getId())
+ {
+ case GPMSG_NPC_BUY:
+ {
+ BuyDialog* dialog = new BuyDialog(npcId);
+
+ dialog->reset();
+ dialog->setMoney(PlayerInfo::getAttribute(MONEY));
+
+ while (msg.getUnreadLength())
+ {
+ int itemId = msg.readInt16();
+ int amount = msg.readInt16();
+ int value = msg.readInt16();
+ dialog->addItem(itemId, amount, value);
+ }
+ break;
+ }
+
+ case GPMSG_NPC_SELL:
+ {
+ SellDialog* dialog = new SellDialog(npcId);
+
+ dialog->reset();
+ dialog->setMoney(PlayerInfo::getAttribute(MONEY));
+
+ while (msg.getUnreadLength())
+ {
+ int itemId = msg.readInt16();
+ int amount = msg.readInt16();
+ int value = msg.readInt16();
+ dialog->addItem(new Item(itemId, amount, false), value);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void BuySellHandler::requestSellList(std::string nick _UNUSED_)
+{
+ // TODO
+}
+
+void BuySellHandler::requestBuyList(std::string nick _UNUSED_)
+{
+ // TODO
+}
+
+void BuySellHandler::sendBuyRequest(std::string nick _UNUSED_,
+ ShopItem* item _UNUSED_,
+ int amount _UNUSED_)
+{
+ // TODO
+}
+
+void BuySellHandler::sendSellRequest(std::string nick _UNUSED_,
+ ShopItem* item _UNUSED_,
+ int amount _UNUSED_)
+{
+ // TODO
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/buysellhandler.h b/src/net/manaserv/buysellhandler.h
new file mode 100644
index 000000000..0ceebe61f
--- /dev/null
+++ b/src/net/manaserv/buysellhandler.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_BUYSELLHANDLER_H
+#define NET_MANASERV_BUYSELLHANDLER_H
+
+#include "net/manaserv/messagehandler.h"
+
+#include "net/buysellhandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class BuySellHandler : public MessageHandler, public Net::BuySellHandler
+{
+ public:
+ BuySellHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void requestSellList(std::string nick);
+
+ void requestBuyList(std::string nick);
+
+ void sendBuyRequest(std::string nick, ShopItem* item, int amount);
+
+ void sendSellRequest(std::string nick, ShopItem* item, int amount);
+
+};
+
+} // namespace ManaServ
+
+#endif
diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp
new file mode 100644
index 000000000..dd5430c03
--- /dev/null
+++ b/src/net/manaserv/charhandler.cpp
@@ -0,0 +1,406 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/charhandler.h"
+
+#include "client.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/charcreatedialog.h"
+#include "gui/okdialog.h"
+
+#include "net/logindata.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/gamehandler.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+#include "net/manaserv/attributes.h"
+
+#include "resources/colordb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+
+extern Net::CharHandler *charHandler;
+extern ManaServ::GameHandler *gameHandler;
+
+namespace ManaServ
+{
+
+extern Connection *accountServerConnection;
+extern Connection *gameServerConnection;
+extern Connection *chatServerConnection;
+extern std::string netToken;
+extern ServerInfo gameServer;
+extern ServerInfo chatServer;
+
+CharHandler::CharHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ APMSG_CHAR_CREATE_RESPONSE,
+ APMSG_CHAR_DELETE_RESPONSE,
+ APMSG_CHAR_INFO,
+ APMSG_CHAR_SELECT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+ charHandler = this;
+}
+
+CharHandler::~CharHandler()
+{
+ clear();
+}
+
+void CharHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case APMSG_CHAR_CREATE_RESPONSE:
+ handleCharacterCreateResponse(msg);
+ break;
+
+ case APMSG_CHAR_DELETE_RESPONSE:
+ handleCharacterDeleteResponse(msg);
+ break;
+
+ case APMSG_CHAR_INFO:
+ handleCharacterInfo(msg);
+ break;
+
+ case APMSG_CHAR_SELECT_RESPONSE:
+ handleCharacterSelectResponse(msg);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void CharHandler::handleCharacterInfo(Net::MessageIn &msg)
+{
+ CachedCharacterInfo info;
+ info.slot = msg.readInt8();
+ info.name = msg.readString();
+ info.gender = msg.readInt8() == GENDER_MALE ? GENDER_MALE :
+ GENDER_FEMALE;
+ info.hairStyle = msg.readInt8();
+ info.hairColor = msg.readInt8();
+ info.level = msg.readInt16();
+ info.characterPoints = msg.readInt16();
+ info.correctionPoints = msg.readInt16();
+
+
+ while (msg.getUnreadLength() > 0)
+ {
+ int id = msg.readInt32();
+ CachedAttrbiute attr;
+ attr.base = msg.readInt32() / 256.0;
+ attr.mod = msg.readInt32() / 256.0;
+
+ info.attribute[id] = attr;
+ }
+
+ mCachedCharacterInfos.push_back(info);
+
+ updateCharacters();
+}
+
+void CharHandler::handleCharacterCreateResponse(Net::MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
+
+ if (errMsg != ERRMSG_OK)
+ {
+ // Character creation failed
+ std::string errorMessage = "";
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = _("Not logged in.");
+ break;
+ case CREATE_TOO_MUCH_CHARACTERS:
+ errorMessage = _("No empty slot.");
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("Invalid name.");
+ break;
+ case CREATE_EXISTS_NAME:
+ errorMessage = _("Character's name already exists.");
+ break;
+ case CREATE_INVALID_HAIRSTYLE:
+ errorMessage = _("Invalid hairstyle.");
+ break;
+ case CREATE_INVALID_HAIRCOLOR:
+ errorMessage = _("Invalid hair color.");
+ break;
+ case CREATE_INVALID_GENDER:
+ errorMessage = _("Invalid gender.");
+ break;
+ case CREATE_ATTRIBUTES_TOO_HIGH:
+ errorMessage = _("Character's stats are too high.");
+ break;
+ case CREATE_ATTRIBUTES_TOO_LOW:
+ errorMessage = _("Character's stats are too low.");
+ break;
+ case CREATE_ATTRIBUTES_OUT_OF_RANGE:
+ errorMessage = strprintf( _("At least one stat"
+ "is out of the permitted range: (%u - %u)."),
+ Attributes::getAttributeMinimum(),
+ Attributes::getAttributeMaximum());
+ break;
+ case CREATE_INVALID_SLOT:
+ errorMessage = _("Invalid slot number.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ new OkDialog(_("Error"), errorMessage);
+
+ if (mCharCreateDialog)
+ mCharCreateDialog->unlock();
+ }
+ else
+ {
+ // Close the character create dialog
+ if (mCharCreateDialog)
+ {
+ mCharCreateDialog->scheduleDelete();
+ mCharCreateDialog = 0;
+ }
+ }
+}
+
+void CharHandler::handleCharacterDeleteResponse(Net::MessageIn &msg)
+{
+ int errMsg = msg.readInt8();
+ if (errMsg == ERRMSG_OK)
+ {
+ // Character deletion successful
+ delete mSelectedCharacter;
+ mCharacters.remove(mSelectedCharacter);
+// mSelectedCharacter = 0;
+ updateCharSelectDialog();
+ new OkDialog(_("Info"), _("Player deleted."));
+ }
+ else
+ {
+ // Character deletion failed
+ std::string errorMessage = "";
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = _("Not logged in.");
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("Selection out of range.");
+ break;
+ default:
+ errorMessage = strprintf(_("Unknown error (%d)."), errMsg);
+ }
+ new OkDialog(_("Error"), errorMessage);
+ }
+ mSelectedCharacter = 0;
+ unlockCharSelectDialog();
+}
+
+void CharHandler::handleCharacterSelectResponse(Net::MessageIn &msg)
+{
+ int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ netToken = msg.readString(32);
+
+ gameServer.hostname.assign(msg.readString());
+ gameServer.port = msg.readInt16();
+
+ chatServer.hostname.assign(msg.readString());
+ chatServer.port = msg.readInt16();
+
+ logger->log("Game server: %s:%d", gameServer.hostname.c_str(),
+ gameServer.port);
+ logger->log("Chat server: %s:%d", chatServer.hostname.c_str(),
+ chatServer.port);
+
+ // Prevent the selected local player from being deleted
+ player_node = mSelectedCharacter->dummy;
+ PlayerInfo::setBackend(mSelectedCharacter->data);
+ mSelectedCharacter->dummy = 0;
+
+ Client::setState(STATE_CONNECT_GAME);
+ }
+ else if (errMsg == ERRMSG_FAILURE)
+ {
+ errorMessage = _("No gameservers are available.");
+ delete_all(mCharacters);
+ mCharacters.clear();
+ Client::setState(STATE_ERROR);
+ }
+}
+
+void CharHandler::setCharSelectDialog(CharSelectDialog *window)
+{
+ mCharSelectDialog = window;
+ updateCharacters();
+}
+
+void CharHandler::setCharCreateDialog(CharCreateDialog *window)
+{
+ mCharCreateDialog = window;
+
+ if (!mCharCreateDialog)
+ return;
+
+ mCharCreateDialog->setAttributes(Attributes::getLabels(),
+ Attributes::getCreationPoints(),
+ Attributes::getAttributeMinimum(),
+ Attributes::getAttributeMaximum());
+}
+
+void CharHandler::requestCharacters()
+{
+ if (!accountServerConnection->isConnected())
+ {
+ Net::getLoginHandler()->connect();
+ }
+ else
+ {
+ // The characters are already there, continue to character selection
+ Client::setState(STATE_CHAR_SELECT);
+ }
+}
+
+void CharHandler::chooseCharacter(Net::Character *character)
+{
+ mSelectedCharacter = character;
+
+ MessageOut msg(PAMSG_CHAR_SELECT);
+ msg.writeInt8(mSelectedCharacter->slot);
+ accountServerConnection->send(msg);
+}
+
+void CharHandler::newCharacter(const std::string &name,
+ int slot,
+ bool gender,
+ int hairstyle,
+ int hairColor,
+ const std::vector<int> &stats)
+{
+ MessageOut msg(PAMSG_CHAR_CREATE);
+
+ msg.writeString(name);
+ msg.writeInt8(hairstyle);
+ msg.writeInt8(hairColor);
+ msg.writeInt8(gender);
+ msg.writeInt8(slot);
+
+ std::vector<int>::const_iterator it, it_end;
+ for (it = stats.begin(), it_end = stats.end(); it != it_end; it++)
+ msg.writeInt16((*it));
+
+ accountServerConnection->send(msg);
+}
+
+void CharHandler::deleteCharacter(Net::Character *character)
+{
+ mSelectedCharacter = character;
+
+ MessageOut msg(PAMSG_CHAR_DELETE);
+ msg.writeInt8(mSelectedCharacter->slot);
+ accountServerConnection->send(msg);
+}
+
+void CharHandler::switchCharacter()
+{
+ gameHandler->quit(true);
+}
+
+unsigned int CharHandler::baseSprite() const
+{
+ return SPRITE_BASE;
+}
+
+unsigned int CharHandler::hairSprite() const
+{
+ return SPRITE_HAIR;
+}
+
+unsigned int CharHandler::maxSprite() const
+{
+ return SPRITE_VECTOREND;
+}
+
+void CharHandler::updateCharacters()
+{
+ // Delete previous characters
+ delete_all(mCharacters);
+ mCharacters.clear();
+
+ if (!mCharSelectDialog)
+ return;
+
+ // Create new characters and initialize them from the cached infos
+ for (unsigned i = 0; i < mCachedCharacterInfos.size(); ++i)
+ {
+ const CachedCharacterInfo &info = mCachedCharacterInfos.at(i);
+
+ Net::Character *character = new Net::Character;
+ character->slot = info.slot;
+ LocalPlayer *player = character->dummy = new LocalPlayer;
+ player->setName(info.name);
+ player->setGender(info.gender);
+ player->setSprite(SPRITE_HAIR, info.hairStyle * -1,
+ ColorDB::get(info.hairColor));
+ character->data.mAttributes[LEVEL] = info.level;
+ character->data.mAttributes[CHAR_POINTS] = info.characterPoints;
+ character->data.mAttributes[CORR_POINTS] = info.correctionPoints;
+
+ for (CachedAttributes::const_iterator it = info.attribute.begin(),
+ it_end = info.attribute.end(); it != it_end; it++)
+ {
+ character->data.mStats[i].base = it->second.base;
+ character->data.mStats[i].mod = it->second.mod;
+ }
+
+ mCharacters.push_back(character);
+ }
+
+ updateCharSelectDialog();
+}
+
+void CharHandler::clear()
+{
+ setCharCreateDialog(0);
+ setCharSelectDialog(0);
+
+ mCachedCharacterInfos.clear();
+ updateCharacters();
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/charhandler.h b/src/net/manaserv/charhandler.h
new file mode 100644
index 000000000..512cca451
--- /dev/null
+++ b/src/net/manaserv/charhandler.h
@@ -0,0 +1,119 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_CHARSERVERHANDLER_H
+#define NET_MANASERV_CHARSERVERHANDLER_H
+
+#include "gui/charselectdialog.h"
+
+#include "net/charhandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#include <map.h>
+
+class LoginData;
+
+namespace ManaServ
+{
+
+/**
+ * Deals with incoming messages related to character selection.
+ */
+class CharHandler : public MessageHandler, public Net::CharHandler
+{
+ public:
+ CharHandler();
+
+ ~CharHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void setCharSelectDialog(CharSelectDialog *window);
+
+ /**
+ * Sets the character create dialog. The handler will clean up this
+ * dialog when a new character is succesfully created, and will unlock
+ * the dialog when a new character failed to be created.
+ */
+ void setCharCreateDialog(CharCreateDialog *window);
+
+ void requestCharacters();
+
+ void chooseCharacter(Net::Character *character);
+
+ void newCharacter(const std::string &name, int slot,
+ bool gender, int hairstyle, int hairColor,
+ const std::vector<int> &stats);
+
+ void deleteCharacter(Net::Character *character);
+
+ void switchCharacter();
+
+ unsigned int baseSprite() const;
+
+ unsigned int hairSprite() const;
+
+ unsigned int maxSprite() const;
+
+ void clear();
+
+ private:
+ /**
+ * Character information needs to be cached since we receive it before
+ * we have loaded the dynamic data, so we can't resolve load any
+ * sprites yet.
+ */
+ struct CachedAttrbiute
+ {
+ double base;
+ double mod;
+ };
+
+ typedef std::map<int, CachedAttrbiute> CachedAttributes;
+
+ struct CachedCharacterInfo
+ {
+ int slot;
+ std::string name;
+ Gender gender;
+ int hairStyle;
+ int hairColor;
+ int level;
+ int characterPoints;
+ int correctionPoints;
+ CachedAttributes attribute;
+ };
+
+ void handleCharacterInfo(Net::MessageIn &msg);
+ void handleCharacterCreateResponse(Net::MessageIn &msg);
+ void handleCharacterDeleteResponse(Net::MessageIn &msg);
+ void handleCharacterSelectResponse(Net::MessageIn &msg);
+
+ void updateCharacters();
+
+ /** Cached character information */
+ std::vector<CachedCharacterInfo> mCachedCharacterInfos;
+};
+
+} // namespace ManaServ
+
+#endif
diff --git a/src/net/manaserv/chathandler.cpp b/src/net/manaserv/chathandler.cpp
new file mode 100644
index 000000000..5e588c583
--- /dev/null
+++ b/src/net/manaserv/chathandler.cpp
@@ -0,0 +1,472 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/chathandler.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "client.h"
+#include "channel.h"
+#include "channelmanager.h"
+
+#include "gui/chat.h"
+
+#include "gui/widgets/channeltab.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
+#include <iostream>
+
+extern Being *player_node;
+
+extern Net::ChatHandler *chatHandler;
+
+namespace ManaServ
+{
+
+extern Connection *chatServerConnection;
+extern Connection *gameServerConnection;
+extern std::string netToken;
+extern ServerInfo chatServer;
+
+ChatHandler::ChatHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_SAY,
+ CPMSG_ENTER_CHANNEL_RESPONSE,
+ CPMSG_LIST_CHANNELS_RESPONSE,
+ CPMSG_PUBMSG,
+ CPMSG_ANNOUNCEMENT,
+ CPMSG_PRIVMSG,
+ CPMSG_QUIT_CHANNEL_RESPONSE,
+ CPMSG_LIST_CHANNELUSERS_RESPONSE,
+ CPMSG_CHANNEL_EVENT,
+ CPMSG_WHO_RESPONSE,
+ CPMSG_DISCONNECT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+ chatHandler = this;
+}
+
+void ChatHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_SAY:
+ handleGameChatMessage(msg);
+ break;
+
+ case CPMSG_ENTER_CHANNEL_RESPONSE:
+ handleEnterChannelResponse(msg);
+ break;
+
+ case CPMSG_LIST_CHANNELS_RESPONSE:
+ handleListChannelsResponse(msg);
+ break;
+
+ case CPMSG_PRIVMSG:
+ handlePrivateMessage(msg);
+ break;
+
+ case CPMSG_ANNOUNCEMENT:
+ handleAnnouncement(msg);
+ break;
+
+ case CPMSG_PUBMSG:
+ handleChatMessage(msg);
+ break;
+
+ case CPMSG_QUIT_CHANNEL_RESPONSE:
+ handleQuitChannelResponse(msg);
+ break;
+
+ case CPMSG_LIST_CHANNELUSERS_RESPONSE:
+ handleListChannelUsersResponse(msg);
+ break;
+
+ case CPMSG_CHANNEL_EVENT:
+ handleChannelEvent(msg);
+ break;
+
+ case CPMSG_WHO_RESPONSE:
+ handleWhoResponse(msg);
+ break;
+ case CPMSG_DISCONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ // TODO: Handle logout
+ }
+ else
+ {
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Chatserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Chatserver: Unknown error";
+ break;
+ }
+ Client::setState(STATE_ERROR);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void ChatHandler::handleGameChatMessage(Net::MessageIn &msg)
+{
+ short id = msg.readInt16();
+ std::string chatMsg = msg.readString();
+
+ if (id == 0)
+ {
+ localChatTab->chatLog(chatMsg, BY_SERVER);
+ return;
+ }
+
+ Being *being = actorSpriteManager->findBeing(id);
+
+ std::string mes;
+ if (being)
+ {
+ mes = being->getName() + " : " + chatMsg;
+ being->setSpeech(chatMsg, SPEECH_TIME);
+ }
+ else
+ mes = "Unknown : " + chatMsg;
+
+ localChatTab->chatLog(mes, being == player_node
+ ? BY_PLAYER : BY_OTHER);
+}
+
+void ChatHandler::handleEnterChannelResponse(Net::MessageIn &msg)
+{
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ short channelId = msg.readInt16();
+ std::string channelName = msg.readString();
+ std::string announcement = msg.readString();
+ Channel *channel = new Channel(channelId, channelName, announcement);
+ channelManager->addChannel(channel);
+ ChatTab *tab = channel->getTab();
+ tab->chatLog(strprintf(_("Topic: %s"), announcement.c_str()),
+ BY_CHANNEL);
+
+ std::string user;
+ std::string userModes;
+ tab->chatLog(_("Players in this channel:"), BY_CHANNEL);
+ while (msg.getUnreadLength())
+ {
+ user = msg.readString();
+ if (user == "")
+ return;
+ userModes = msg.readString();
+ if (userModes.find('o') != std::string::npos)
+ {
+ user = "@" + user;
+ }
+ tab->chatLog(user, BY_CHANNEL);
+ }
+
+ }
+ else
+ {
+ localChatTab->chatLog(_("Error joining channel."), BY_SERVER);
+ }
+}
+
+void ChatHandler::handleListChannelsResponse(Net::MessageIn &msg)
+{
+ localChatTab->chatLog(_("Listing channels."), BY_SERVER);
+ while (msg.getUnreadLength())
+ {
+ std::string channelName = msg.readString();
+ if (channelName == "")
+ return;
+ std::ostringstream numUsers;
+ numUsers << msg.readInt16();
+ channelName += " - ";
+ channelName += numUsers.str();
+ localChatTab->chatLog(channelName, BY_SERVER);
+ }
+ localChatTab->chatLog(_("End of channel list."), BY_SERVER);
+}
+
+void ChatHandler::handlePrivateMessage(Net::MessageIn &msg)
+{
+ std::string userNick = msg.readString();
+ std::string chatMsg = msg.readString();
+
+ chatWindow->whisper(userNick, chatMsg);
+}
+
+void ChatHandler::handleAnnouncement(Net::MessageIn &msg)
+{
+ std::string chatMsg = msg.readString();
+ localChatTab->chatLog(chatMsg, BY_GM);
+}
+
+void ChatHandler::handleChatMessage(Net::MessageIn &msg)
+{
+ short channelId = msg.readInt16();
+ std::string userNick = msg.readString();
+ std::string chatMsg = msg.readString();
+
+ Channel *channel = channelManager->findById(channelId);
+ channel->getTab()->chatLog(userNick, chatMsg);
+}
+
+void ChatHandler::handleQuitChannelResponse(Net::MessageIn &msg)
+{
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ short channelId = msg.readInt16();
+ Channel *channel = channelManager->findById(channelId);
+ channelManager->removeChannel(channel);
+ }
+}
+
+void ChatHandler::handleListChannelUsersResponse(Net::MessageIn &msg)
+{
+ std::string channelName = msg.readString();
+ std::string userNick;
+ std::string userModes;
+ Channel *channel = channelManager->findByName(channelName);
+ channel->getTab()->chatLog(_("Players in this channel:"),
+ BY_CHANNEL);
+ while (msg.getUnreadLength())
+ {
+ userNick = msg.readString();
+ if (userNick == "")
+ {
+ break;
+ }
+ userModes = msg.readString();
+ if (userModes.find('o') != std::string::npos)
+ {
+ userNick = "@" + userNick;
+ }
+ localChatTab->chatLog(userNick, BY_CHANNEL, channel);
+ }
+}
+
+void ChatHandler::handleChannelEvent(Net::MessageIn &msg)
+{
+ short channelId = msg.readInt16();
+ char eventId = msg.readInt8();
+ std::string line = msg.readString();
+ Channel *channel = channelManager->findById(channelId);
+
+ if (channel)
+ {
+ switch(eventId)
+ {
+ case CHAT_EVENT_NEW_PLAYER:
+ channel->getTab()->chatLog(strprintf(_("%s entered the "
+ "channel."), line.c_str()), BY_CHANNEL);
+ break;
+
+ case CHAT_EVENT_LEAVING_PLAYER:
+ channel->getTab()->chatLog(strprintf(_("%s left the channel."),
+ line.c_str()), BY_CHANNEL);
+ break;
+
+ case CHAT_EVENT_TOPIC_CHANGE:
+ channel->getTab()->chatLog(strprintf(_("Topic: %s"),
+ line.c_str()), BY_CHANNEL);
+ break;
+
+ case CHAT_EVENT_MODE_CHANGE:
+ {
+ int first = line.find(":");
+ int second = line.find(":", first + 1);
+ std::string user1 = line.substr(0, first);
+ std::string user2 = line.substr(first + 1, second);
+ std::string mode = line.substr(second + 1, line.length());
+ channel->getTab()->chatLog(strprintf(_("%s has set mode %s "
+ "on user %s."), user1.c_str(), mode.c_str(),
+ user2.c_str()), BY_CHANNEL);
+ }
+ break;
+
+ case CHAT_EVENT_KICKED_PLAYER:
+ {
+ int first = line.find(":");
+ std::string user1 = line.substr(0, first);
+ std::string user2 = line.substr(first + 1, line.length());
+ channel->getTab()->chatLog(strprintf(_("%s has kicked %s."),
+ user1.c_str(), user2.c_str()), BY_CHANNEL);
+ }
+ break;
+
+ default:
+ channel->getTab()->chatLog(_("Unknown channel event."),
+ BY_CHANNEL);
+ }
+ }
+}
+
+void ChatHandler::handleWhoResponse(Net::MessageIn &msg)
+{
+ std::string userNick;
+
+ while (msg.getUnreadLength())
+ {
+ userNick = msg.readString();
+ if (userNick == "")
+ break;
+ localChatTab->chatLog(userNick, BY_SERVER);
+ }
+}
+
+void ChatHandler::connect()
+{
+ MessageOut msg(PCMSG_CONNECT);
+ msg.writeString(netToken, 32);
+ chatServerConnection->send(msg);
+}
+
+bool ChatHandler::isConnected()
+{
+ return chatServerConnection->isConnected();
+}
+
+void ChatHandler::disconnect()
+{
+ chatServerConnection->disconnect();
+}
+
+void ChatHandler::talk(const std::string &text)
+{
+ MessageOut msg(PGMSG_SAY);
+ msg.writeString(text);
+ gameServerConnection->send(msg);
+}
+
+void ChatHandler::talkRaw(const std::string &text)
+{
+ MessageOut msg(PGMSG_SAY);
+ msg.writeString(text);
+ gameServerConnection->send(msg);
+}
+
+void ChatHandler::me(const std::string &text _UNUSED_)
+{
+ // TODO
+}
+
+void ChatHandler::privateMessage(const std::string &recipient,
+ const std::string &text)
+{
+ MessageOut msg(PCMSG_PRIVMSG);
+ msg.writeString(recipient);
+ msg.writeString(text);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::channelList()
+{
+ MessageOut msg(PCMSG_LIST_CHANNELS);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::enterChannel(const std::string &channel,
+ const std::string &password)
+{
+ MessageOut msg(PCMSG_ENTER_CHANNEL);
+ msg.writeString(channel);
+ msg.writeString(password);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::quitChannel(int channelId)
+{
+ MessageOut msg(PCMSG_QUIT_CHANNEL);
+ msg.writeInt16(channelId);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::sendToChannel(int channelId, const std::string &text)
+{
+ MessageOut msg(PCMSG_CHAT);
+ msg.writeString(text);
+ msg.writeInt16(channelId);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::userList(const std::string &channel)
+{
+ MessageOut msg(PCMSG_LIST_CHANNELUSERS);
+ msg.writeString(channel);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::setChannelTopic(int channelId, const std::string &text)
+{
+ MessageOut msg(PCMSG_TOPIC_CHANGE);
+ msg.writeInt16(channelId);
+ msg.writeString(text);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::setUserMode(int channelId, const std::string &name, int mode)
+{
+ MessageOut msg(PCMSG_USER_MODE);
+ msg.writeInt16(channelId);
+ msg.writeString(name);
+ msg.writeInt8(mode);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::kickUser(int channelId, const std::string &name)
+{
+ MessageOut msg(PCMSG_KICK_USER);
+ msg.writeInt16(channelId);
+ msg.writeString(name);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::who()
+{
+ MessageOut msg(PCMSG_WHO);
+ chatServerConnection->send(msg);
+}
+
+void ChatHandler::sendRaw(const std::string &args _UNUSED_)
+{
+
+}
+} // namespace ManaServ
diff --git a/src/net/manaserv/chathandler.h b/src/net/manaserv/chathandler.h
new file mode 100644
index 000000000..8ffa6d28d
--- /dev/null
+++ b/src/net/manaserv/chathandler.h
@@ -0,0 +1,139 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_CHATHANDLER_H
+#define NET_MANASERV_CHATHANDLER_H
+
+#include "net/chathandler.h"
+#include "net/serverinfo.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class ChatHandler : public MessageHandler, public Net::ChatHandler
+{
+ public:
+ ChatHandler();
+
+ /**
+ * Handle the given message appropriately.
+ */
+ void handleMessage(Net::MessageIn &msg);
+
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
+ void talk(const std::string &text);
+
+ void talkRaw(const std::string &text);
+
+ void me(const std::string &text);
+
+ void privateMessage(const std::string &recipient,
+ const std::string &text);
+
+ void channelList();
+
+ void enterChannel(const std::string &channel,
+ const std::string &password);
+
+ void quitChannel(int channelId);
+
+ void sendToChannel(int channelId, const std::string &text);
+
+ void userList(const std::string &channel);
+
+ void setChannelTopic(int channelId, const std::string &text);
+
+ void setUserMode(int channelId, const std::string &name, int mode);
+
+ void kickUser(int channelId, const std::string &name);
+
+ void who();
+
+ void sendRaw(const std::string &args);
+
+ private:
+ /**
+ * Handle chat messages sent from the game server.
+ */
+ void handleGameChatMessage(Net::MessageIn &msg);
+
+ /**
+ * Handle channel entry responses.
+ */
+ void handleEnterChannelResponse(Net::MessageIn &msg);
+
+ /**
+ * Handle list channels responses.
+ */
+ void handleListChannelsResponse(Net::MessageIn &msg);
+
+ /**
+ * Handle private messages.
+ */
+ void handlePrivateMessage(Net::MessageIn &msg);
+
+ /**
+ * Handle announcements.
+ */
+ void handleAnnouncement(Net::MessageIn &msg);
+
+ /**
+ * Handle chat messages.
+ */
+ void handleChatMessage(Net::MessageIn &msg);
+
+ /**
+ * Handle quit channel responses.
+ */
+ void handleQuitChannelResponse(Net::MessageIn &msg);
+
+ /**
+ * Handle list channel users responses.
+ */
+ void handleListChannelUsersResponse(Net::MessageIn &msg);
+
+ /**
+ * Handle channel events.
+ */
+ void handleChannelEvent(Net::MessageIn &msg);
+
+ /**
+ * Handle who responses.
+ */
+ void handleWhoResponse(Net::MessageIn &msg);
+};
+
+} // namespace ManaServ
+
+#endif
diff --git a/src/net/manaserv/connection.cpp b/src/net/manaserv/connection.cpp
new file mode 100644
index 000000000..944d8a94c
--- /dev/null
+++ b/src/net/manaserv/connection.cpp
@@ -0,0 +1,113 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/connection.h"
+
+#include "log.h"
+
+#include "net/manaserv/internal.h"
+#include "net/manaserv/messageout.h"
+
+#include <string>
+
+namespace ManaServ
+{
+
+Connection::Connection(ENetHost *client):
+ mConnection(0), mClient(client)
+{
+ mPort = 0;
+ connections++;
+}
+
+Connection::~Connection()
+{
+ connections--;
+}
+
+bool Connection::connect(const std::string &address, short port)
+{
+ logger->log("Net::Connection::connect(%s, %i)", address.c_str(), port);
+
+ if (address.empty())
+ {
+ logger->log1("Net::Connection::connect() got empty address!");
+ mState = NET_ERROR;
+ return false;
+ }
+
+ ENetAddress enetAddress;
+
+ enet_address_set_host(&enetAddress, address.c_str());
+ enetAddress.port = port;
+
+ // Initiate the connection, allocating channel 0.
+#if defined(ENET_VERSION) && ENET_VERSION >= ENET_CUTOFF
+ mConnection = enet_host_connect(mClient, &enetAddress, 1, 0);
+#else
+ mConnection = enet_host_connect(mClient, &enetAddress, 1);
+#endif
+
+ if (!mConnection)
+ {
+ logger->log1("Unable to initiate connection to the server.");
+ mState = NET_ERROR;
+ return false;
+ }
+
+ mPort = port;
+
+ return true;
+}
+
+void Connection::disconnect()
+{
+ if (!mConnection)
+ return;
+
+ enet_peer_disconnect(mConnection, 0);
+ enet_host_flush(mClient);
+ enet_peer_reset(mConnection);
+
+ mConnection = 0;
+}
+
+bool Connection::isConnected()
+{
+ return (mConnection) ?
+ (mConnection->state == ENET_PEER_STATE_CONNECTED) : false;
+}
+
+void Connection::send(const ManaServ::MessageOut &msg)
+{
+ if (!isConnected())
+ {
+ logger->log1("Warning: cannot send message to not connected server!");
+ return;
+ }
+
+ ENetPacket *packet = enet_packet_create(msg.getData(),
+ msg.getDataSize(),
+ ENET_PACKET_FLAG_RELIABLE);
+ enet_peer_send(mConnection, 0, packet);
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/connection.h b/src/net/manaserv/connection.h
new file mode 100644
index 000000000..260a177ee
--- /dev/null
+++ b/src/net/manaserv/connection.h
@@ -0,0 +1,89 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_CONNECTION_H
+#define NET_MANASERV_CONNECTION_H
+
+#include "enet/enet.h"
+
+#include <iosfwd>
+
+#ifdef ENET_VERSION_CREATE
+#define ENET_CUTOFF ENET_VERSION_CREATE(1, 3, 0)
+#else
+#define ENET_CUTOFF 0xFFFFFFFF
+#endif
+
+namespace ManaServ
+{
+ class MessageOut;
+
+ /**
+ * \ingroup Network
+ */
+ class Connection
+ {
+ public:
+ enum State
+ {
+ OK = 0,
+ NET_ERROR
+ };
+
+ ~Connection();
+
+ /**
+ * Connects to the given server with the specified address and port.
+ * This method is non-blocking, use isConnected to check whether the
+ * server is connected.
+ */
+ bool connect(const std::string &address, short port);
+
+ /**
+ * Disconnects from the given server.
+ */
+ void disconnect();
+
+ State getState()
+ { return mState; }
+
+ /**
+ * Returns whether the server is connected.
+ */
+ bool isConnected();
+
+ /**
+ * Sends a message.
+ */
+ void send(const ManaServ::MessageOut &msg);
+
+ private:
+ friend Connection *ManaServ::getConnection();
+ Connection(ENetHost *client);
+
+ short mPort;
+ ENetPeer *mConnection;
+ ENetHost *mClient;
+ State mState;
+ };
+}
+
+#endif // NET_MANASERV_CONNECTION_H
diff --git a/src/net/manaserv/defines.h b/src/net/manaserv/defines.h
new file mode 100644
index 000000000..f09175f65
--- /dev/null
+++ b/src/net/manaserv/defines.h
@@ -0,0 +1,77 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MANASERV_DEFINES_H
+#define MANASERV_DEFINES_H
+
+/**
+ * Attributes used during combat. Available to all the beings.
+ */
+enum
+{
+ BASE_ATTR_BEGIN = 0,
+ BASE_ATTR_PHY_ATK_MIN = BASE_ATTR_BEGIN,
+ BASE_ATTR_PHY_ATK_DELTA,
+ /**< Physical attack power. */
+ BASE_ATTR_MAG_ATK, /**< Magical attack power. */
+ BASE_ATTR_PHY_RES, /**< Resistance to physical damage. */
+ BASE_ATTR_MAG_RES, /**< Resistance to magical damage. */
+ BASE_ATTR_EVADE, /**< Ability to avoid hits. */
+ BASE_ATTR_HIT, /**< Ability to hit stuff. */
+ BASE_ATTR_HP, /**< Hit Points (Base value: maximum,
+ Modded value: current) */
+ BASE_ATTR_HP_REGEN, /**< number of HP regenerated every 10 game ticks */
+ BASE_ATTR_END,
+ BASE_ATTR_NB = BASE_ATTR_END - BASE_ATTR_BEGIN,
+
+ BASE_ELEM_BEGIN = BASE_ATTR_END,
+ BASE_ELEM_NEUTRAL = BASE_ELEM_BEGIN,
+ BASE_ELEM_FIRE,
+ BASE_ELEM_WATER,
+ BASE_ELEM_EARTH,
+ BASE_ELEM_AIR,
+ BASE_ELEM_SACRED,
+ BASE_ELEM_DEATH,
+ BASE_ELEM_END,
+ BASE_ELEM_NB = BASE_ELEM_END - BASE_ELEM_BEGIN,
+
+ NB_BEING_ATTRIBUTES = BASE_ELEM_END
+};
+
+/**
+ * Attributes of characters. Used to derive being attributes.
+ */
+enum
+{
+ CHAR_ATTR_BEGIN = NB_BEING_ATTRIBUTES,
+ CHAR_ATTR_STRENGTH = CHAR_ATTR_BEGIN,
+ CHAR_ATTR_AGILITY,
+ CHAR_ATTR_DEXTERITY,
+ CHAR_ATTR_VITALITY,
+ CHAR_ATTR_INTELLIGENCE,
+ CHAR_ATTR_WILLPOWER,
+ CHAR_ATTR_END,
+ CHAR_ATTR_NB = CHAR_ATTR_END - CHAR_ATTR_BEGIN,
+
+ NB_CHARACTER_ATTRIBUTES = CHAR_ATTR_END
+};
+
+#endif // MANASERV_DEFINES_H
diff --git a/src/net/manaserv/effecthandler.cpp b/src/net/manaserv/effecthandler.cpp
new file mode 100644
index 000000000..5e0083744
--- /dev/null
+++ b/src/net/manaserv/effecthandler.cpp
@@ -0,0 +1,80 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/effecthandler.h"
+
+#include "actorspritemanager.h"
+#include "effectmanager.h"
+#include "log.h"
+
+#include "net/messagein.h"
+
+#include "net/manaserv/protocol.h"
+
+namespace ManaServ
+{
+
+EffectHandler::EffectHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_CREATE_EFFECT_POS,
+ GPMSG_CREATE_EFFECT_BEING,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void EffectHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_CREATE_EFFECT_POS:
+ handleCreateEffectPos(msg);
+ break;
+ case GPMSG_CREATE_EFFECT_BEING:
+ handleCreateEffectBeing(msg);
+ break;
+ default:
+ break;
+ }
+}
+
+void EffectHandler::handleCreateEffectPos(Net::MessageIn &msg)
+{
+ int id = msg.readInt16();
+ Uint16 x = msg.readInt16();
+ Uint16 y = msg.readInt16();
+ effectManager->trigger(id, x, y);
+}
+
+void EffectHandler::handleCreateEffectBeing(Net::MessageIn &msg)
+{
+ int eid = msg.readInt16();
+ int bid = msg.readInt16();
+ Being* b = actorSpriteManager->findBeing(bid);
+ if (b)
+ effectManager->trigger(eid, b);
+ else
+ logger->log("Warning: CreateEffect called for unknown being #%d", bid);
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/effecthandler.h b/src/net/manaserv/effecthandler.h
new file mode 100644
index 000000000..5f6c07580
--- /dev/null
+++ b/src/net/manaserv/effecthandler.h
@@ -0,0 +1,44 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_EFFECTSHANDLER_H
+#define NET_MANASERV_EFFECTSHANDLER_H
+
+#include "net/manaserv/messagehandler.h"
+
+namespace ManaServ
+{
+
+class EffectHandler : public MessageHandler
+{
+ public:
+ EffectHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ private:
+ void handleCreateEffectPos(Net::MessageIn &msg);
+ void handleCreateEffectBeing(Net::MessageIn &msg);
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_EFFECTSHANDLER_H
diff --git a/src/net/manaserv/gamehandler.cpp b/src/net/manaserv/gamehandler.cpp
new file mode 100644
index 000000000..9ca6c0d6b
--- /dev/null
+++ b/src/net/manaserv/gamehandler.cpp
@@ -0,0 +1,154 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/gamehandler.h"
+
+#include "client.h"
+#include "localplayer.h"
+
+#include "net/manaserv/chathandler.h"
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+extern Net::GameHandler *gameHandler;
+
+extern ManaServ::ChatHandler *chatHandler;
+
+namespace ManaServ
+{
+
+extern Connection *chatServerConnection;
+extern Connection *gameServerConnection;
+extern std::string netToken;
+extern ServerInfo gameServer;
+extern ServerInfo chatServer;
+
+GameHandler::GameHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_DISCONNECT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+ gameHandler = this;
+}
+
+void GameHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_DISCONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ netToken = msg.readString(32);
+
+ if (!netToken.empty())
+ {
+ Client::setState(STATE_SWITCH_CHARACTER);
+ }
+ else
+ {
+ // TODO: Handle logout
+ }
+ }
+ // Logout failed
+ else
+ {
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Gameserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Gameserver: Unknown error";
+ break;
+ }
+ Client::setState(STATE_ERROR);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void GameHandler::connect()
+{
+ gameServerConnection->connect(gameServer.hostname, gameServer.port);
+
+ // Will already be connected if we just changed gameservers
+ if (!chatServerConnection->isConnected())
+ chatServerConnection->connect(chatServer.hostname, chatServer.port);
+}
+
+bool GameHandler::isConnected()
+{
+ return gameServerConnection->isConnected() &&
+ chatHandler->isConnected();
+}
+
+void GameHandler::disconnect()
+{
+ gameServerConnection->disconnect();
+ // No need if we're just changing gameservers
+ if (Client::getState() != STATE_CHANGE_MAP)
+ chatHandler->disconnect();
+}
+
+void GameHandler::who()
+{
+ // TODO
+}
+
+void GameHandler::quit(bool reconnectAccount)
+{
+ MessageOut msg(PGMSG_DISCONNECT);
+ msg.writeInt8((unsigned char) reconnectAccount);
+ gameServerConnection->send(msg);
+}
+
+void GameHandler::ping(int tick _UNUSED_)
+{
+ // TODO
+}
+
+void GameHandler::gameLoading()
+{
+ MessageOut msg(PGMSG_CONNECT);
+ msg.writeString(netToken, 32);
+ gameServerConnection->send(msg);
+
+ chatHandler->connect();
+
+ // Attack range from item DB
+ player_node->setAttackRange(-1);
+}
+
+void GameHandler::disconnect2()
+{
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/gamehandler.h b/src/net/manaserv/gamehandler.h
new file mode 100644
index 000000000..246a3c736
--- /dev/null
+++ b/src/net/manaserv/gamehandler.h
@@ -0,0 +1,74 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_MAPHANDLER_H
+#define NET_MANASERV_MAPHANDLER_H
+
+#include "net/gamehandler.h"
+#include "net/serverinfo.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class GameHandler : public MessageHandler, public Net::GameHandler
+{
+ public:
+ GameHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
+ void who();
+
+ void quit(bool reconnectAccount);
+
+ void quit() { quit(false); }
+
+ void ping(int tick);
+
+ bool removeDeadBeings() const { return false; }
+
+ void clear();
+
+ void gameLoading();
+
+ /** The ManaServ protocol doesn't use the MP status bar. */
+ bool canUseMagicBar() const { return false; }
+
+ void disconnect2();
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_MAPHANDLER_H
diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp
new file mode 100644
index 000000000..acf731dec
--- /dev/null
+++ b/src/net/manaserv/generalhandler.cpp
@@ -0,0 +1,211 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/generalhandler.h"
+
+#include "client.h"
+
+#include "gui/changeemaildialog.h"
+#include "gui/charselectdialog.h"
+#include "gui/inventorywindow.h"
+#include "gui/register.h"
+#include "gui/skilldialog.h"
+#include "gui/specialswindow.h"
+
+#include "net/manaserv/beinghandler.h"
+#include "net/manaserv/buysellhandler.h"
+#include "net/manaserv/charhandler.h"
+#include "net/manaserv/chathandler.h"
+#include "net/manaserv/connection.h"
+#include "net/manaserv/effecthandler.h"
+#include "net/manaserv/gamehandler.h"
+#include "net/manaserv/guildhandler.h"
+#include "net/manaserv/inventoryhandler.h"
+#include "net/manaserv/itemhandler.h"
+#include "net/manaserv/loginhandler.h"
+#include "net/manaserv/network.h"
+#include "net/manaserv/npchandler.h"
+#include "net/manaserv/partyhandler.h"
+#include "net/manaserv/playerhandler.h"
+#include "net/manaserv/specialhandler.h"
+#include "net/manaserv/attributes.h"
+#include "net/manaserv/tradehandler.h"
+
+#include "utils/gettext.h"
+
+#include <list>
+
+extern Net::GeneralHandler *generalHandler;
+
+extern ManaServ::LoginHandler *loginHandler;
+
+namespace ManaServ
+{
+
+Connection *accountServerConnection = 0;
+Connection *chatServerConnection = 0;
+Connection *gameServerConnection = 0;
+std::string netToken = "";
+ServerInfo gameServer;
+ServerInfo chatServer;
+
+GeneralHandler::GeneralHandler():
+ mBeingHandler(new BeingHandler),
+ mBuySellHandler(new BuySellHandler),
+ mCharHandler(new CharHandler),
+ mChatHandler(new ChatHandler),
+ mEffectHandler(new EffectHandler),
+ mGameHandler(new GameHandler),
+ mGuildHandler(new GuildHandler),
+ mInventoryHandler(new InventoryHandler),
+ mItemHandler(new ItemHandler),
+ mLoginHandler(new LoginHandler),
+ mNpcHandler(new NpcHandler),
+ mPartyHandler(new PartyHandler),
+ mPlayerHandler(new PlayerHandler),
+ mTradeHandler(new TradeHandler),
+ mSpecialHandler(new SpecialHandler)
+{
+ initialize();
+
+ accountServerConnection = getConnection();
+ gameServerConnection = getConnection();
+ chatServerConnection = getConnection();
+
+ generalHandler = this;
+
+ listen(CHANNEL_CLIENT);
+ listen(CHANNEL_GAME);
+}
+
+void GeneralHandler::load()
+{
+ registerHandler(mBeingHandler.get());
+ registerHandler(mBuySellHandler.get());
+ registerHandler(mCharHandler.get());
+ registerHandler(mChatHandler.get());
+ registerHandler(mEffectHandler.get());
+ registerHandler(mGameHandler.get());
+ registerHandler(mGuildHandler.get());
+ registerHandler(mInventoryHandler.get());
+ registerHandler(mItemHandler.get());
+ registerHandler(mLoginHandler.get());
+ registerHandler(mNpcHandler.get());
+ registerHandler(mPartyHandler.get());
+ registerHandler(mPlayerHandler.get());
+ registerHandler(mTradeHandler.get());
+}
+
+void GeneralHandler::reload()
+{
+ static_cast<CharHandler*>(Net::getCharHandler())->clear();
+
+ if (accountServerConnection)
+ accountServerConnection->disconnect();
+
+ if (gameServerConnection)
+ gameServerConnection->disconnect();
+
+ if (chatServerConnection)
+ chatServerConnection->disconnect();
+
+ netToken.clear();
+ gameServer.clear();
+ chatServer.clear();
+
+ Attributes::unload();
+ Attributes::load();
+ Attributes::informItemDB();
+}
+
+void GeneralHandler::unload()
+{
+ clearHandlers();
+
+ if (accountServerConnection)
+ accountServerConnection->disconnect();
+ if (gameServerConnection)
+ gameServerConnection->disconnect();
+ if (chatServerConnection)
+ chatServerConnection->disconnect();
+
+ delete accountServerConnection;
+ accountServerConnection = 0;
+ delete gameServerConnection;
+ gameServerConnection = 0;
+ delete chatServerConnection;
+ chatServerConnection = 0;
+
+ Attributes::unload();
+ finalize();
+}
+
+void GeneralHandler::flushNetwork()
+{
+ flush();
+
+ if (Client::getState() == STATE_SWITCH_CHARACTER &&
+ Net::getLoginHandler()->isConnected())
+ {
+ loginHandler->reconnect();
+ Client::setState(STATE_GET_CHARACTERS);
+ }
+}
+
+void GeneralHandler::clearHandlers()
+{
+ clearNetworkHandlers();
+}
+
+void GeneralHandler::event(Channels channel,
+ const Mana::Event &event)
+{
+ if (channel == CHANNEL_CLIENT)
+ {
+ int newState = event.getInt("newState");
+
+ if (newState == STATE_GAME)
+ {
+ GameHandler *game = static_cast<GameHandler*>(
+ Net::getGameHandler());
+ game->gameLoading();
+ }
+ else if (newState == STATE_LOAD_DATA)
+ {
+ Attributes::load();
+ Attributes::informItemDB();
+ }
+ }
+ else if (channel == CHANNEL_GAME)
+ {
+ if (event.getName() == EVENT_GUIWINDOWSLOADED)
+ {
+ inventoryWindow->setSplitAllowed(true);
+ skillDialog->loadSkills("mana-skills.xml");
+
+ PlayerInfo::setAttribute(EXP_NEEDED, 100);
+
+ Attributes::informStatusWindow();
+ }
+ }
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/generalhandler.h b/src/net/manaserv/generalhandler.h
new file mode 100644
index 000000000..944a3d305
--- /dev/null
+++ b/src/net/manaserv/generalhandler.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_GENERALHANDLER_H
+#define NET_MANASERV_GENERALHANDLER_H
+
+#include "listener.h"
+
+#include "net/generalhandler.h"
+#include "net/net.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class GeneralHandler : public Net::GeneralHandler, public Mana::Listener
+{
+ public:
+ GeneralHandler();
+
+ void load();
+
+ void reload();
+
+ void unload();
+
+ void flushNetwork();
+
+ void clearHandlers();
+
+ void event(Channels channel, const Mana::Event &event);
+
+ protected:
+ MessageHandlerPtr mBeingHandler;
+ MessageHandlerPtr mBuySellHandler;
+ MessageHandlerPtr mCharHandler;
+ MessageHandlerPtr mChatHandler;
+ MessageHandlerPtr mEffectHandler;
+ MessageHandlerPtr mGameHandler;
+ MessageHandlerPtr mGuildHandler;
+ MessageHandlerPtr mInventoryHandler;
+ MessageHandlerPtr mItemHandler;
+ MessageHandlerPtr mLoginHandler;
+ MessageHandlerPtr mNpcHandler;
+ MessageHandlerPtr mPartyHandler;
+ MessageHandlerPtr mPlayerHandler;
+ MessageHandlerPtr mTradeHandler;
+ MessageHandlerPtr mSpecialHandler;
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_GENERALHANDLER_H
diff --git a/src/net/manaserv/guildhandler.cpp b/src/net/manaserv/guildhandler.cpp
new file mode 100644
index 000000000..26af3eff1
--- /dev/null
+++ b/src/net/manaserv/guildhandler.cpp
@@ -0,0 +1,360 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/guildhandler.h"
+
+#include "event.h"
+#include "guild.h"
+#include "log.h"
+#include "localplayer.h"
+#include "channel.h"
+#include "channelmanager.h"
+
+#include "gui/widgets/channeltab.h"
+#include "gui/chat.h"
+#include "gui/socialwindow.h"
+
+#include "net/messagein.h"
+#include "net/net.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <iostream>
+
+extern Net::GuildHandler *guildHandler;
+
+namespace ManaServ
+{
+
+extern Connection *chatServerConnection;
+
+GuildHandler::GuildHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ CPMSG_GUILD_CREATE_RESPONSE,
+ CPMSG_GUILD_INVITE_RESPONSE,
+ CPMSG_GUILD_ACCEPT_RESPONSE,
+ CPMSG_GUILD_GET_MEMBERS_RESPONSE,
+ CPMSG_GUILD_UPDATE_LIST,
+ CPMSG_GUILD_INVITED,
+ CPMSG_GUILD_REJOIN,
+ CPMSG_GUILD_QUIT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+
+ guildHandler = this;
+}
+
+void GuildHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case CPMSG_GUILD_CREATE_RESPONSE:
+ {
+ logger->log1("Received CPMSG_GUILD_CREATE_RESPONSE");
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ // TODO - Acknowledge guild was created
+ SERVER_NOTICE(_("Guild created."))
+ joinedGuild(msg);
+ }
+ else
+ {
+ SERVER_NOTICE(_("Error creating guild."))
+ }
+ } break;
+
+ case CPMSG_GUILD_INVITE_RESPONSE:
+ {
+ logger->log1("Received CPMSG_GUILD_INVITE_RESPONSE");
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ // TODO - Acknowledge invite was sent
+ SERVER_NOTICE(_("Invite sent."))
+ }
+ } break;
+
+ case CPMSG_GUILD_ACCEPT_RESPONSE:
+ {
+ logger->log1("Received CPMSG_GUILD_ACCEPT_RESPONSE");
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ // TODO - Acknowledge accepted into guild
+ joinedGuild(msg);
+ }
+ } break;
+
+ case CPMSG_GUILD_GET_MEMBERS_RESPONSE:
+ {
+ logger->log1("Received CPMSG_GUILD_GET_MEMBERS_RESPONSE");
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ std::string name;
+ bool online;
+ Guild *guild;
+ GuildMember *member;
+
+ short guildId = msg.readInt16();
+ guild = player_node->getGuild(guildId);
+
+ if (!guild)
+ return;
+
+ guild->clearMembers();
+
+ while (msg.getUnreadLength())
+ {
+ name = msg.readString();
+ online = msg.readInt8();
+ if (name != "")
+ {
+ member = guild->addMember(name);
+ member->setOnline(online);
+ }
+ }
+ }
+ } break;
+
+ case CPMSG_GUILD_UPDATE_LIST:
+ {
+ logger->log1("Received CPMSG_GUILD_UPDATE_LIST");
+ short guildId = msg.readInt16();
+ std::string name = msg.readString();
+ char eventId = msg.readInt8();
+ GuildMember *member;
+
+ Guild *guild = player_node->getGuild(guildId);
+ if (guild)
+ {
+ switch(eventId)
+ {
+ case GUILD_EVENT_NEW_PLAYER:
+ member = guild->addMember(name);
+ member->setOnline(true);
+ break;
+
+ case GUILD_EVENT_LEAVING_PLAYER:
+ guild->removeMember(name);
+ break;
+
+ case GUILD_EVENT_ONLINE_PLAYER:
+ member = guild->getMember(name);
+ if (member)
+ {
+ member->setOnline(true);
+ }
+ break;
+
+ case GUILD_EVENT_OFFLINE_PLAYER:
+ member = guild->getMember(name);
+ if (member)
+ {
+ member->setOnline(false);
+ }
+ break;
+
+ default:
+ logger->log1("Invalid guild event");
+ }
+ }
+ } break;
+
+ case CPMSG_GUILD_INVITED:
+ {
+ logger->log1("Received CPMSG_GUILD_INVITED");
+ std::string inviterName = msg.readString();
+ std::string guildName = msg.readString();
+ int guildId = msg.readInt16();
+
+ // Open a dialog asking if the player accepts joining the guild.
+ socialWindow->showGuildInvite(guildName, guildId, inviterName);
+ } break;
+
+ case CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE:
+ {
+ logger->log1("Received CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE");
+
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ // promotion succeeded
+ SERVER_NOTICE(_("Member was promoted successfully."))
+ }
+ else
+ {
+ // promotion failed
+ SERVER_NOTICE(_("Failed to promote member."))
+ }
+ }
+
+ case CPMSG_GUILD_REJOIN:
+ {
+ logger->log1("Received CPMSG_GUILD_REJOIN");
+
+ joinedGuild(msg);
+ } break;
+
+ case CPMSG_GUILD_QUIT_RESPONSE:
+ {
+ logger->log1("Received CPMSG_GUILD_QUIT_RESPONSE");
+
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ // Must remove tab first, as it wont find the guild
+ // name after its removed from the player
+ int guildId = msg.readInt16();
+ Guild *guild = player_node->getGuild(guildId);
+ if (guild)
+ {
+ Channel *channel = channelManager->findByName(
+ guild->getName());
+ channelManager->removeChannel(channel);
+ player_node->removeGuild(guildId);
+ }
+ }
+ } break;
+ default: break;
+ }
+}
+
+void GuildHandler::joinedGuild(Net::MessageIn &msg)
+{
+ std::string guildName = msg.readString();
+ short guildId = msg.readInt16();
+ short permissions = msg.readInt16();
+ short channelId = msg.readInt16();
+ std::string announcement = msg.readString();
+
+ // Add guild to player
+ Guild *guild = Guild::getGuild(guildId);
+ guild->setName(guildName);
+ guild->setRights(permissions);
+ player_node->addGuild(guild);
+ Net::getGuildHandler()->memberList(guildId);
+
+ // Automatically create the guild channel
+ // COMMENT: Should this go here??
+ Channel *channel = new Channel(channelId, guildName, announcement);
+ channelManager->addChannel(channel);
+ channel->getTab()->chatLog(strprintf(_("Topic: %s"), announcement.c_str()),
+ BY_CHANNEL);
+}
+
+void GuildHandler::create(const std::string &name)
+{
+ MessageOut msg(PCMSG_GUILD_CREATE);
+ msg.writeString(name);
+ chatServerConnection->send(msg);
+}
+
+void GuildHandler::invite(int guildId, const std::string &name)
+{
+ MessageOut msg(PCMSG_GUILD_INVITE);
+ msg.writeInt16(guildId);
+ msg.writeString(name);
+ chatServerConnection->send(msg);
+}
+
+void GuildHandler::invite(int guildId, Being *being)
+{
+ invite(guildId, being->getName());
+}
+
+void GuildHandler::inviteResponse(int guildId _UNUSED_, bool response _UNUSED_)
+{
+ /*MessageOut msg(PCMSG_GUILD_ACCEPT);
+ msg.writeString(name);
+ chatServerConnection->send(msg);*/
+}
+
+void GuildHandler::leave(int guildId)
+{
+ MessageOut msg(PCMSG_GUILD_QUIT);
+ msg.writeInt16(guildId);
+ chatServerConnection->send(msg);
+}
+
+void GuildHandler::kick(GuildMember *member _UNUSED_,
+ std::string reason _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::chat(int guildId _UNUSED_, const std::string &text _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::memberList(int guildId)
+{
+ MessageOut msg(PCMSG_GUILD_GET_MEMBERS);
+ msg.writeInt16(guildId);
+ chatServerConnection->send(msg);
+}
+
+void GuildHandler::info(int guildId _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::changeMemberPostion(GuildMember *member _UNUSED_,
+ int level _UNUSED_)
+{
+ /*MessageOut msg(PCMSG_GUILD_PROMOTE_MEMBER);
+ msg.writeInt16(guildId);
+ msg.writeString(name);
+ msg.writeInt8(level);
+ chatServerConnection->send(msg);*/
+}
+
+void GuildHandler::requestAlliance(int guildId _UNUSED_,
+ int otherGuildId _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::requestAllianceResponse(int guildId _UNUSED_,
+ int otherGuildId _UNUSED_,
+ bool response _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::endAlliance(int guildId _UNUSED_, int otherGuildId _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::changeNotice(int guildId _UNUSED_,
+ std::string msg1 _UNUSED_,
+ std::string msg2 _UNUSED_)
+{
+ // TODO
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/guildhandler.h b/src/net/manaserv/guildhandler.h
new file mode 100644
index 000000000..18862398b
--- /dev/null
+++ b/src/net/manaserv/guildhandler.h
@@ -0,0 +1,84 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_GUILDHANDLER_H
+#define NET_MANASERV_GUILDHANDLER_H
+
+#include "net/guildhandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class GuildHandler : public Net::GuildHandler, public MessageHandler
+{
+public:
+ GuildHandler();
+
+ bool isSupported()
+ { return true; }
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void create(const std::string &name);
+
+ void invite(int guildId, const std::string &name);
+
+ void invite(int guidId, Being *being);
+
+ void inviteResponse(int guidId, bool response);
+
+ void leave(int guildId);
+
+ void kick(GuildMember *member, std::string reason = "");
+
+ void chat(int guildId, const std::string &text);
+
+ void memberList(int guildId);
+
+ void info(int guildId _UNUSED_);
+
+ void changeMemberPostion(GuildMember *member, int level);
+
+ void requestAlliance(int guildId, int otherGuildId);
+
+ void requestAllianceResponse(int guildId, int otherGuildId,
+ bool response);
+
+ void endAlliance(int guildId, int otherGuildId);
+
+ void changeNotice(int guildId, std::string msg1,
+ std::string msg2);
+
+protected:
+ void joinedGuild(Net::MessageIn &msg);
+};
+
+} // namespace ManaServ
+
+#endif
diff --git a/src/net/manaserv/internal.cpp b/src/net/manaserv/internal.cpp
new file mode 100644
index 000000000..fcba3fb40
--- /dev/null
+++ b/src/net/manaserv/internal.cpp
@@ -0,0 +1,27 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/internal.h"
+
+namespace ManaServ
+{
+ int connections = 0;
+}
diff --git a/src/net/manaserv/internal.h b/src/net/manaserv/internal.h
new file mode 100644
index 000000000..f600c207e
--- /dev/null
+++ b/src/net/manaserv/internal.h
@@ -0,0 +1,30 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_INTERNAL_H
+#define NET_MANASERV_INTERNAL_H
+
+namespace ManaServ
+{
+ extern int connections;
+}
+
+#endif
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp
new file mode 100644
index 000000000..1d7736f1a
--- /dev/null
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -0,0 +1,219 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/inventoryhandler.h"
+
+#include "equipment.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+
+#include "gui/chat.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+#include "resources/iteminfo.h"
+
+#include "log.h" // <<< REMOVE ME!
+
+extern Net::InventoryHandler *inventoryHandler;
+
+namespace ManaServ
+{
+
+extern Connection *gameServerConnection;
+
+InventoryHandler::InventoryHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_INVENTORY_FULL,
+ GPMSG_INVENTORY,
+ GPMSG_EQUIP,
+ 0
+ };
+ handledMessages = _messages;
+ inventoryHandler = this;
+}
+
+void InventoryHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_INVENTORY_FULL:
+ {
+ PlayerInfo::clearInventory();
+ PlayerInfo::getEquipment()->setBackend(&mEquips);
+ int count = msg.readInt16();
+ while (count--)
+ {
+ unsigned int slot = msg.readInt16();
+ int id = msg.readInt16();
+ unsigned int amount = msg.readInt16();
+ PlayerInfo::setInventoryItem(slot, id, amount, 0);
+ }
+ while (msg.getUnreadLength())
+ {
+ unsigned int slot = msg.readInt8();
+ unsigned int ref = msg.readInt16();
+
+ mEquips.addEquipment(slot, ref);
+ }
+ }
+ break;
+
+ case GPMSG_INVENTORY:
+ while (msg.getUnreadLength())
+ {
+ unsigned int slot = msg.readInt16();
+ int id = msg.readInt16();
+ unsigned int amount = id ? msg.readInt16() : 0;
+ PlayerInfo::setInventoryItem(slot, id, amount, 0);
+ }
+ break;
+
+ case GPMSG_EQUIP:
+ while (msg.getUnreadLength())
+ {
+ unsigned int ref = msg.readInt16();
+ int count = msg.readInt8();
+ while (count--)
+ {
+ unsigned int slot = msg.readInt8();
+ unsigned int used = msg.readInt8();
+
+ mEquips.setEquipment(slot, used, ref);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void InventoryHandler::equipItem(const Item *item)
+{
+ MessageOut msg(PGMSG_EQUIP);
+ msg.writeInt8(item->getInvIndex());
+ gameServerConnection->send(msg);
+}
+
+void InventoryHandler::unequipItem(const Item *item)
+{
+ MessageOut msg(PGMSG_UNEQUIP);
+ msg.writeInt8(item->getInvIndex());
+ gameServerConnection->send(msg);
+
+/*
+ // Tidy equipment directly to avoid weapon still shown bug, for instance
+ int equipSlot = item->getInvIndex();
+ logger->log("Unequipping %d", equipSlot);
+ mEquips.setEquipment(equipSlot, 0);
+*/
+}
+
+void InventoryHandler::useItem(const Item *item)
+{
+ MessageOut msg(PGMSG_USE_ITEM);
+ msg.writeInt8(item->getInvIndex());
+ gameServerConnection->send(msg);
+}
+
+void InventoryHandler::dropItem(const Item *item, int amount)
+{
+ MessageOut msg(PGMSG_DROP);
+ msg.writeInt8(item->getInvIndex());
+ msg.writeInt8(amount);
+ gameServerConnection->send(msg);
+}
+
+bool InventoryHandler::canSplit(const Item *item)
+{
+ return item && !item->isEquipment() && item->getQuantity() > 1;
+}
+
+void InventoryHandler::splitItem(const Item *item, int amount)
+{
+ int newIndex = PlayerInfo::getInventory()->getFreeSlot();
+ if (newIndex > Inventory::NO_SLOT_INDEX)
+ {
+ MessageOut msg(PGMSG_MOVE_ITEM);
+ msg.writeInt8(item->getInvIndex());
+ msg.writeInt8(newIndex);
+ msg.writeInt8(amount);
+ gameServerConnection->send(msg);
+ }
+}
+
+void InventoryHandler::moveItem(int oldIndex, int newIndex)
+{
+ if (oldIndex == newIndex)
+ return;
+
+ MessageOut msg(PGMSG_MOVE_ITEM);
+ msg.writeInt8(oldIndex);
+ msg.writeInt8(newIndex);
+ msg.writeInt8(PlayerInfo::getInventory()->getItem(oldIndex)
+ ->getQuantity());
+ gameServerConnection->send(msg);
+}
+
+void InventoryHandler::openStorage(int type _UNUSED_)
+{
+ // TODO
+}
+
+void InventoryHandler::closeStorage(int type _UNUSED_)
+{
+ // TODO
+}
+
+void InventoryHandler::moveItem(int source _UNUSED_, int slot _UNUSED_,
+ int amount _UNUSED_, int destination _UNUSED_)
+{
+ // TODO
+}
+
+size_t InventoryHandler::getSize(int type) const
+{
+ switch (type)
+ {
+ case Inventory::INVENTORY:
+ case Inventory::TRADE:
+ return 50;
+ case Inventory::STORAGE:
+ return 300;
+ default:
+ return 0;
+ }
+}
+
+int InventoryHandler::convertFromServerSlot(int eAthenaSlot)
+{
+ return eAthenaSlot;
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
new file mode 100644
index 000000000..07d168ce7
--- /dev/null
+++ b/src/net/manaserv/inventoryhandler.h
@@ -0,0 +1,109 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_INVENTORYHANDLER_H
+#define NET_MANASERV_INVENTORYHANDLER_H
+
+#include "equipment.h"
+
+#include "net/inventoryhandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class EquipBackend : public Equipment::Backend
+{
+ public:
+ EquipBackend()
+ { memset(mEquipment, 0, sizeof(mEquipment)); }
+
+ Item *getEquipment(int index) const
+ { return mEquipment[index]; }
+
+ void clear()
+ {
+ for (int i = 0; i < EQUIPMENT_SIZE; ++i)
+ delete mEquipment[i];
+
+ std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0);
+ }
+
+ void setEquipment(unsigned int slot, unsigned int used, int reference)
+ {
+ printf("Equip: %d at %dx%d\n", reference, slot, used);
+ }
+
+ void addEquipment(unsigned int slot, int reference)
+ {
+ printf("Equip: %d at %d\n", reference, slot);
+ }
+
+ private:
+ Item *mEquipment[EQUIPMENT_SIZE];
+};
+
+class InventoryHandler : public MessageHandler, Net::InventoryHandler
+{
+ public:
+ InventoryHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void equipItem(const Item *item);
+
+ void unequipItem(const Item *item);
+
+ void useItem(const Item *item);
+
+ void dropItem(const Item *item, int amount);
+
+ bool canSplit(const Item *item);
+
+ void splitItem(const Item *item, int amount);
+
+ void moveItem(int oldIndex, int newIndex);
+
+ void openStorage(int type);
+
+ void closeStorage(int type);
+
+ void moveItem(int source, int slot, int amount,
+ int destination);
+
+ size_t getSize(int type) const;
+
+ int convertFromServerSlot(int eAthenaSlot);
+
+ private:
+ EquipBackend mEquips;
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_INVENTORYHANDLER_H
diff --git a/src/net/manaserv/itemhandler.cpp b/src/net/manaserv/itemhandler.cpp
new file mode 100644
index 000000000..73320ecfb
--- /dev/null
+++ b/src/net/manaserv/itemhandler.cpp
@@ -0,0 +1,90 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/itemhandler.h"
+
+#include "actorspritemanager.h"
+
+#include "net/manaserv/protocol.h"
+#include "net/manaserv/messagein.h"
+
+#include "game.h"
+#include "map.h"
+#include "log.h"
+
+namespace ManaServ
+{
+
+ItemHandler::ItemHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_ITEMS,
+ GPMSG_ITEM_APPEAR,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void ItemHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_ITEM_APPEAR:
+ case GPMSG_ITEMS:
+ {
+ while (msg.getUnreadLength())
+ {
+ int itemId = msg.readInt16();
+ int x = msg.readInt16();
+ int y = msg.readInt16();
+ int id = (x << 16) | y; // dummy id
+
+ if (itemId)
+ {
+ if (Game *game = Game::instance())
+ {
+ if (Map *map = game->getCurrentMap())
+ {
+ actorSpriteManager->createItem(id, itemId,
+ x / map->getTileWidth(),
+ y / map->getTileHeight(),
+ 0);
+ }
+ else
+ {
+ logger->log(
+ "ItemHandler: An item wasn't created "
+ "because of Game/Map not initialized...");
+ }
+ }
+ }
+ else if (FloorItem *item = actorSpriteManager->findItem(id))
+ {
+ actorSpriteManager->destroy(item);
+ }
+ }
+ } break;
+ default: break;
+ }
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/itemhandler.h b/src/net/manaserv/itemhandler.h
new file mode 100644
index 000000000..58f3695fd
--- /dev/null
+++ b/src/net/manaserv/itemhandler.h
@@ -0,0 +1,40 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_ITEMHANDLER_H
+#define NET_MANASERV_ITEMHANDLER_H
+
+#include "net/manaserv/messagehandler.h"
+
+namespace ManaServ
+{
+
+class ItemHandler : public MessageHandler
+{
+ public:
+ ItemHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_ITEMHANDLER_H
diff --git a/src/net/manaserv/loginhandler.cpp b/src/net/manaserv/loginhandler.cpp
new file mode 100644
index 000000000..1588d762d
--- /dev/null
+++ b/src/net/manaserv/loginhandler.cpp
@@ -0,0 +1,479 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/loginhandler.h"
+
+#include "client.h"
+#include "log.h"
+
+#include "net/logindata.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/sha256.h"
+
+extern Net::LoginHandler *loginHandler;
+
+namespace ManaServ
+{
+
+extern Connection *accountServerConnection;
+extern std::string netToken;
+
+LoginHandler::LoginHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ APMSG_LOGIN_RESPONSE,
+ APMSG_REGISTER_RESPONSE,
+ APMSG_RECONNECT_RESPONSE,
+ APMSG_PASSWORD_CHANGE_RESPONSE,
+ APMSG_EMAIL_CHANGE_RESPONSE,
+ APMSG_LOGOUT_RESPONSE,
+ APMSG_UNREGISTER_RESPONSE,
+ APMSG_REGISTER_INFO_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+ loginHandler = this;
+}
+
+void LoginHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case APMSG_LOGIN_RESPONSE:
+ handleLoginResponse(msg);
+ break;
+
+ case APMSG_REGISTER_RESPONSE:
+ handleRegisterResponse(msg);
+ break;
+
+ case APMSG_RECONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful login
+ if (errMsg == ERRMSG_OK)
+ {
+ Client::setState(STATE_CHAR_SELECT);
+ }
+ // Login failed
+ else
+ {
+ switch (errMsg)
+ {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("Wrong magic_token.");
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = _("Already logged in.");
+ break;
+ case LOGIN_BANNED:
+ errorMessage = _("Account banned.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ Client::setState(STATE_ERROR);
+ }
+ }
+ break;
+
+ case APMSG_PASSWORD_CHANGE_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful pass change
+ if (errMsg == ERRMSG_OK)
+ {
+ Client::setState(STATE_CHANGEPASSWORD_SUCCESS);
+ }
+ // pass change failed
+ else
+ {
+ switch (errMsg)
+ {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("New password incorrect.");
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = _("Old password incorrect.");
+ break;
+ case ERRMSG_NO_LOGIN:
+ errorMessage =
+ _("Account not connected. Please login first.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ Client::setState(STATE_ACCOUNTCHANGE_ERROR);
+ }
+ }
+ break;
+
+ case APMSG_EMAIL_CHANGE_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful pass change
+ if (errMsg == ERRMSG_OK)
+ {
+ Client::setState(STATE_CHANGEEMAIL_SUCCESS);
+ }
+ // pass change failed
+ else
+ {
+ switch (errMsg)
+ {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("New email address incorrect.");
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = _("Old email address incorrect.");
+ break;
+ case ERRMSG_NO_LOGIN:
+ errorMessage =
+ _("Account not connected. Please login first.");
+ break;
+ case ERRMSG_EMAIL_ALREADY_EXISTS:
+ errorMessage =
+ _("The new email address already exists.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ Client::setState(STATE_ACCOUNTCHANGE_ERROR);
+ }
+ }
+ break;
+ case APMSG_LOGOUT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ // TODO: handle logout
+ }
+ // Logout failed
+ else
+ {
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Accountserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Accountserver: Unknown error";
+ break;
+ }
+ Client::setState(STATE_ERROR);
+ }
+ }
+ break;
+ case APMSG_UNREGISTER_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful unregistration
+ if (errMsg == ERRMSG_OK)
+ {
+ Client::setState(STATE_UNREGISTER);
+ }
+ // Unregistration failed
+ else
+ {
+ switch (errMsg)
+ {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage =
+ "Accountserver: Wrong username or password";
+ break;
+ default:
+ errorMessage = "Accountserver: Unknown error";
+ break;
+ }
+ Client::setState(STATE_ACCOUNTCHANGE_ERROR);
+ }
+ }
+ break;
+
+ case APMSG_REGISTER_INFO_RESPONSE:
+ {
+ int allowed = msg.readInt8();
+
+ if (allowed)
+ {
+ mMinUserNameLength = msg.readInt8();
+ mMaxUserNameLength = msg.readInt8();
+ std::string captchaURL = msg.readString();
+ std::string captchaInstructions = msg.readString();
+
+ printf("%s: %s\n", captchaURL.c_str(), captchaInstructions.c_str());
+
+ Client::setState(STATE_REGISTER);
+ }
+ else
+ {
+ errorMessage = msg.readString();
+
+ if (errorMessage.empty())
+ errorMessage = _("Client registration is not allowed. "
+ "Please contact server administration.");
+ Client::setState(STATE_LOGIN_ERROR);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void LoginHandler::handleLoginResponse(Net::MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ readServerInfo(msg);
+ // No worlds atm, but future use :-D
+ Client::setState(STATE_WORLD_SELECT);
+ }
+ else
+ {
+ switch (errMsg)
+ {
+ case LOGIN_INVALID_VERSION:
+ errorMessage = _("Client version is too old.");
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("Wrong username or password.");
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = _("Already logged in.");
+ break;
+ case LOGIN_BANNED:
+ errorMessage = _("Account banned");
+ break;
+ case LOGIN_INVALID_TIME:
+ errorMessage = _("Login attempt too soon after previous "
+ "attempt.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ Client::setState(STATE_LOGIN_ERROR);
+ }
+}
+
+void LoginHandler::handleRegisterResponse(Net::MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ readServerInfo(msg);
+ Client::setState(STATE_WORLD_SELECT);
+ }
+ else
+ {
+ switch (errMsg)
+ {
+ case REGISTER_INVALID_VERSION:
+ errorMessage = _("Client version is too old.");
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("Wrong username, password or email address.");
+ break;
+ case REGISTER_EXISTS_USERNAME:
+ errorMessage = _("Username already exists.");
+ break;
+ case REGISTER_EXISTS_EMAIL:
+ errorMessage = _("Email address already exists.");
+ break;
+ case REGISTER_CAPTCHA_WRONG:
+ errorMessage = _("You took too long with the captcha or your "
+ "response was incorrect.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ Client::setState(STATE_LOGIN_ERROR);
+ }
+}
+
+void LoginHandler::readServerInfo(Net::MessageIn &msg)
+{
+ // Safety check for outdated manaserv versions (remove me later)
+ if (msg.getUnreadLength() == 0)
+ return;
+
+ // Set the update host when included in the message
+ const std::string updateHost = msg.readString();
+ if (!updateHost.empty())
+ mLoginData->updateHost = updateHost;
+ else
+ logger->log1("Warning: server does not have an update host set!");
+
+ // Read the client data folder for dynamic data loading.
+ // This is only used by the QT client.
+ msg.readString();
+
+ // Read the number of character slots
+ mLoginData->characterSlots = msg.readInt8();
+}
+
+void LoginHandler::connect()
+{
+ accountServerConnection->connect(mServer.hostname, mServer.port);
+}
+
+bool LoginHandler::isConnected()
+{
+ return accountServerConnection->isConnected();
+}
+
+void LoginHandler::disconnect()
+{
+ accountServerConnection->disconnect();
+
+ if (Client::getState() == STATE_CONNECT_GAME)
+ {
+ Client::setState(STATE_GAME);
+ }
+}
+
+bool LoginHandler::isRegistrationEnabled()
+{
+ return true;
+}
+
+void LoginHandler::getRegistrationDetails()
+{
+ MessageOut msg(PAMSG_REQUEST_REGISTER_INFO);
+ accountServerConnection->send(msg);
+}
+
+unsigned int LoginHandler::getMinUserNameLength() const
+{
+ return mMinUserNameLength;
+}
+
+unsigned int LoginHandler::getMaxUserNameLength() const
+{
+ return mMaxUserNameLength;
+}
+
+void LoginHandler::loginAccount(LoginData *loginData)
+{
+ mLoginData = loginData;
+
+ MessageOut msg(PAMSG_LOGIN);
+
+ msg.writeInt32(0); // client version
+ msg.writeString(loginData->username);
+ msg.writeString(sha256(loginData->username + loginData->password));
+
+ accountServerConnection->send(msg);
+}
+
+void LoginHandler::logout()
+{
+ MessageOut msg(PAMSG_LOGOUT);
+ accountServerConnection->send(msg);
+}
+
+void LoginHandler::changeEmail(const std::string &email)
+{
+ MessageOut msg(PAMSG_EMAIL_CHANGE);
+
+ // Email is sent clearly so the server can validate the data.
+ // Encryption is assumed server-side.
+ msg.writeString(email);
+
+ accountServerConnection->send(msg);
+}
+
+void LoginHandler::changePassword(const std::string &username,
+ const std::string &oldPassword,
+ const std::string &newPassword)
+{
+ MessageOut msg(PAMSG_PASSWORD_CHANGE);
+
+ // Change password using SHA2 encryption
+ msg.writeString(sha256(username + oldPassword));
+ msg.writeString(sha256(username + newPassword));
+
+ accountServerConnection->send(msg);
+}
+
+void LoginHandler::chooseServer(unsigned int server _UNUSED_)
+{
+ // TODO
+}
+
+void LoginHandler::registerAccount(LoginData *loginData)
+{
+ mLoginData = loginData;
+
+ MessageOut msg(PAMSG_REGISTER);
+
+ msg.writeInt32(0); // client version
+ msg.writeString(loginData->username);
+ // Use a hashed password for privacy reasons
+ msg.writeString(sha256(loginData->username + loginData->password));
+ msg.writeString(loginData->email);
+ msg.writeString(loginData->captchaResponse);
+
+ accountServerConnection->send(msg);
+}
+
+void LoginHandler::unregisterAccount(const std::string &username,
+ const std::string &password)
+{
+ MessageOut msg(PAMSG_UNREGISTER);
+
+ msg.writeString(username);
+ msg.writeString(sha256(username + password));
+
+ accountServerConnection->send(msg);
+}
+
+Worlds LoginHandler::getWorlds() const
+{
+ return Worlds();
+}
+
+void LoginHandler::reconnect()
+{
+ MessageOut msg(PAMSG_RECONNECT);
+ msg.writeString(netToken, 32);
+ accountServerConnection->send(msg);
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/loginhandler.h b/src/net/manaserv/loginhandler.h
new file mode 100644
index 000000000..1c47184a7
--- /dev/null
+++ b/src/net/manaserv/loginhandler.h
@@ -0,0 +1,99 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_LOGINHANDLER_H
+#define NET_MANASERV_LOGINHANDLER_H
+
+#include "net/loginhandler.h"
+#include "net/serverinfo.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class LoginData;
+
+namespace ManaServ
+{
+
+class LoginHandler : public MessageHandler, public Net::LoginHandler
+{
+ public:
+ LoginHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
+ int supportedOptionalActions() const
+ { return Unregister | ChangeEmail | SetEmailOnRegister; }
+
+ bool isRegistrationEnabled();
+
+ void getRegistrationDetails();
+
+ unsigned int getMinUserNameLength() const;
+
+ unsigned int getMaxUserNameLength() const;
+
+ void loginAccount(LoginData *loginData);
+
+ void logout();
+
+ void changeEmail(const std::string &email);
+
+ void changePassword(const std::string &username,
+ const std::string &oldPassword,
+ const std::string &newPassword);
+
+ void chooseServer(unsigned int server);
+
+ void registerAccount(LoginData *loginData);
+
+ void unregisterAccount(const std::string &username,
+ const std::string &password);
+
+ Worlds getWorlds() const;
+
+ void reconnect();
+
+ private:
+ void handleLoginResponse(Net::MessageIn &msg);
+ void handleRegisterResponse(Net::MessageIn &msg);
+
+ void readServerInfo(Net::MessageIn &msg);
+
+ LoginData *mLoginData;
+ unsigned int mMinUserNameLength;
+ unsigned int mMaxUserNameLength;
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_LOGINHANDLER_H
diff --git a/src/net/manaserv/messagehandler.cpp b/src/net/manaserv/messagehandler.cpp
new file mode 100644
index 000000000..2f4d53dc6
--- /dev/null
+++ b/src/net/manaserv/messagehandler.cpp
@@ -0,0 +1,36 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/messagehandler.h"
+
+#include "net/manaserv/network.h"
+
+#include <cassert>
+
+namespace ManaServ
+{
+
+MessageHandler::~MessageHandler()
+{
+ unregisterHandler(this);
+}
+
+}
diff --git a/src/net/manaserv/messagehandler.h b/src/net/manaserv/messagehandler.h
new file mode 100644
index 000000000..2181438f3
--- /dev/null
+++ b/src/net/manaserv/messagehandler.h
@@ -0,0 +1,44 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_MESSAGEHANDLER_H
+#define NET_MANASERV_MESSAGEHANDLER_H
+
+#include "net/messagehandler.h"
+
+namespace ManaServ
+{
+
+/**
+ * \ingroup Network
+ */
+class MessageHandler : public Net::MessageHandler
+{
+ public:
+ ~MessageHandler();
+
+};
+
+typedef const std::auto_ptr<MessageHandler> MessageHandlerPtr;
+
+}
+
+#endif // NET_MANASERV_MESSAGEHANDLER_H
diff --git a/src/net/manaserv/messagein.cpp b/src/net/manaserv/messagein.cpp
new file mode 100644
index 000000000..458aae740
--- /dev/null
+++ b/src/net/manaserv/messagein.cpp
@@ -0,0 +1,62 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/messagein.h"
+
+#include "enet/enet.h"
+
+namespace ManaServ
+{
+
+MessageIn::MessageIn(const char *data, unsigned int length):
+ Net::MessageIn(data, length)
+{
+ // Read the message ID
+ mId = readInt16();
+}
+
+Sint16 MessageIn::readInt16()
+{
+ Sint16 value = -1;
+ if (mPos + 2 <= mLength)
+ {
+ uint16_t t;
+ memcpy(&t, mData + mPos, 2);
+ value = (unsigned short) ENET_NET_TO_HOST_16(t);
+ }
+ mPos += 2;
+ return value;
+}
+
+int MessageIn::readInt32()
+{
+ int value = -1;
+ if (mPos + 4 <= mLength)
+ {
+ uint32_t t;
+ memcpy(&t, mData + mPos, 4);
+ value = ENET_NET_TO_HOST_32(t);
+ }
+ mPos += 4;
+ return value;
+}
+
+}
diff --git a/src/net/manaserv/messagein.h b/src/net/manaserv/messagein.h
new file mode 100644
index 000000000..e3528e5bf
--- /dev/null
+++ b/src/net/manaserv/messagein.h
@@ -0,0 +1,49 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_MESSAGEIN_H
+#define NET_MANASERV_MESSAGEIN_H
+
+#include "net/messagein.h"
+
+namespace ManaServ
+{
+
+/**
+ * Used for parsing an incoming message.
+ *
+ * \ingroup Network
+ */
+class MessageIn : public Net::MessageIn
+{
+ public:
+ /**
+ * Constructor.
+ */
+ MessageIn(const char *data, unsigned int length);
+
+ Sint16 readInt16(); /**< Reads a short. */
+ int readInt32(); /**< Reads a long. */
+};
+
+}
+
+#endif // NET_MANASERV_MESSAGEIN_H
diff --git a/src/net/manaserv/messageout.cpp b/src/net/manaserv/messageout.cpp
new file mode 100644
index 000000000..f4856e640
--- /dev/null
+++ b/src/net/manaserv/messageout.cpp
@@ -0,0 +1,65 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/messageout.h"
+
+#include "enet/enet.h"
+
+#include <cstring>
+#include <string>
+
+namespace ManaServ
+{
+
+MessageOut::MessageOut(short id):
+ Net::MessageOut(id)
+{
+ writeInt16(id);
+}
+
+MessageOut::~MessageOut()
+{
+ free(mData);
+}
+
+void MessageOut::expand(size_t bytes)
+{
+ mData = (char*)realloc(mData, mPos + bytes);
+ mDataSize = mPos + bytes;
+}
+
+void MessageOut::writeInt16(Sint16 value)
+{
+ expand(2);
+ uint16_t t = ENET_HOST_TO_NET_16(value);
+ memcpy(mData + mPos, &t, 2);
+ mPos += 2;
+}
+
+void MessageOut::writeInt32(Sint32 value)
+{
+ expand(4);
+ uint32_t t = ENET_HOST_TO_NET_32(value);
+ memcpy(mData + mPos, &t, 4);
+ mPos += 4;
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/messageout.h b/src/net/manaserv/messageout.h
new file mode 100644
index 000000000..00ae069de
--- /dev/null
+++ b/src/net/manaserv/messageout.h
@@ -0,0 +1,59 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_MESSAGEOUT_H
+#define NET_MANASERV_MESSAGEOUT_H
+
+#include "net/messageout.h"
+
+namespace ManaServ
+{
+
+class MessageOut : public Net::MessageOut
+{
+ public:
+ /**
+ * Constructor.
+ */
+ MessageOut(short id);
+
+ /**
+ * Destructor.
+ */
+ ~MessageOut();
+
+ void writeInt16(Sint16 value); /**< Writes a short. */
+ void writeInt32(Sint32 value); /**< Writes a long. */
+
+ protected:
+ /**
+ * Expand the packet data to be able to hold more data.
+ *
+ * NOTE: For performance enhancements this method could allocate extra
+ * memory in advance instead of expanding size every time more data is
+ * added.
+ */
+ void expand(size_t size);
+};
+
+}
+
+#endif // NET_MANASERV_MESSAGEOUT_H
diff --git a/src/net/manaserv/network.cpp b/src/net/manaserv/network.cpp
new file mode 100644
index 000000000..c8389bb82
--- /dev/null
+++ b/src/net/manaserv/network.cpp
@@ -0,0 +1,178 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/network.h"
+
+#include "log.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/internal.h"
+#include "net/manaserv/messagehandler.h"
+#include "net/manaserv/messagein.h"
+
+#include "enet/enet.h"
+
+#include <map>
+
+/**
+ * The local host which is shared for all outgoing connections.
+ */
+namespace
+{
+ ENetHost *client;
+}
+
+namespace ManaServ
+{
+
+typedef std::map<unsigned short, MessageHandler*> MessageHandlers;
+typedef MessageHandlers::iterator MessageHandlerIterator;
+static MessageHandlers mMessageHandlers;
+
+void initialize()
+{
+ if (enet_initialize())
+ {
+ logger->error("Failed to initialize ENet.");
+ }
+
+#if defined(ENET_VERSION) && ENET_VERSION >= ENET_CUTOFF
+ client = enet_host_create(NULL, 3, 0, 0, 0);
+#else
+ client = enet_host_create(NULL, 3, 0, 0);
+#endif
+
+ if (!client)
+ {
+ logger->error("Failed to create the local host.");
+ }
+}
+
+void finalize()
+{
+ if (!client)
+ return; // Wasn't initialized at all
+
+ if (connections)
+ {
+ logger->error("Tried to shutdown the network subsystem while there "
+ "are network connections left!");
+ }
+
+ clearNetworkHandlers();
+ enet_deinitialize();
+}
+
+Connection *getConnection()
+{
+ if (!client)
+ {
+ logger->error("Tried to instantiate a network object before "
+ "initializing the network subsystem!");
+ }
+
+ return new Connection(client);
+}
+
+void registerHandler(MessageHandler *handler)
+{
+ for (const Uint16 *i = handler->handledMessages; *i; i++)
+ {
+ mMessageHandlers[*i] = handler;
+ }
+}
+
+void unregisterHandler(MessageHandler *handler)
+{
+ for (const Uint16 *i = handler->handledMessages; *i; i++)
+ {
+ mMessageHandlers.erase(*i);
+ }
+}
+
+void clearNetworkHandlers()
+{
+ mMessageHandlers.clear();
+}
+
+
+/**
+ * Dispatches a message to the appropriate message handler and
+ * destroys it afterwards.
+ */
+namespace
+{
+ void dispatchMessage(ENetPacket *packet)
+ {
+ MessageIn msg((const char *)packet->data, packet->dataLength);
+
+ MessageHandlerIterator iter = mMessageHandlers.find(msg.getId());
+
+ if (iter != mMessageHandlers.end())
+ {
+ //logger->log("Received packet %x (%i B)",
+ // msg.getId(), msg.getLength());
+ iter->second->handleMessage(msg);
+ }
+ else
+ {
+ logger->log("Unhandled packet %x (%i B)",
+ msg.getId(), msg.getLength());
+ }
+
+ // Clean up the packet now that we're done using it.
+ enet_packet_destroy(packet);
+ }
+}
+
+void flush()
+{
+ ENetEvent event;
+
+ // Check if there are any new events
+ while (enet_host_service(client, &event, 0) > 0)
+ {
+ switch (event.type)
+ {
+ case ENET_EVENT_TYPE_CONNECT:
+ logger->log("Connected to port %d.", event.peer->address.port);
+ // Store any relevant server information here.
+ event.peer->data = 0;
+ break;
+
+ case ENET_EVENT_TYPE_RECEIVE:
+ dispatchMessage(event.packet);
+ break;
+
+ case ENET_EVENT_TYPE_DISCONNECT:
+ logger->log1("Disconnected.");
+ // Reset the server information.
+ event.peer->data = 0;
+ break;
+
+ case ENET_EVENT_TYPE_NONE:
+ default:
+ break;
+ }
+ }
+}
+
+}
diff --git a/src/net/manaserv/network.h b/src/net/manaserv/network.h
new file mode 100644
index 000000000..149f484e5
--- /dev/null
+++ b/src/net/manaserv/network.h
@@ -0,0 +1,75 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_NETWORK_H
+#define NET_MANASERV_NETWORK_H
+
+#include <iosfwd>
+
+/**
+ * \ingroup Network
+ */
+namespace ManaServ
+{
+ class MessageHandler;
+ class MessageOut;
+
+ class Connection;
+
+ /**
+ * Initializes the network subsystem.
+ */
+ void initialize();
+
+ /**
+ * Finalizes the network subsystem.
+ */
+ void finalize();
+
+ /**
+ * Returns a new Connection object. Should be deleted by the caller.
+ */
+ Connection *getConnection();
+
+ /**
+ * Registers a message handler. A message handler handles a certain
+ * subset of incoming messages.
+ */
+ void registerHandler(MessageHandler *handler);
+
+ /**
+ * Unregisters a message handler.
+ */
+ void unregisterHandler(MessageHandler *handler);
+
+ /**
+ * Clears all registered message handlers.
+ */
+ void clearNetworkHandlers();
+
+ /*
+ * Handles all events and dispatches incoming messages to the
+ * registered handlers
+ */
+ void flush();
+} // namespace ManaServ
+
+#endif
diff --git a/src/net/manaserv/npchandler.cpp b/src/net/manaserv/npchandler.cpp
new file mode 100644
index 000000000..6d4010e83
--- /dev/null
+++ b/src/net/manaserv/npchandler.cpp
@@ -0,0 +1,237 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/npchandler.h"
+
+#include "actorspritemanager.h"
+
+#include "gui/npcdialog.h"
+#include "gui/npcpostdialog.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+extern Net::NpcHandler *npcHandler;
+
+namespace ManaServ
+{
+
+extern Connection *gameServerConnection;
+
+NpcHandler::NpcHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_NPC_CHOICE,
+ GPMSG_NPC_POST,
+ GPMSG_NPC_MESSAGE,
+ GPMSG_NPC_ERROR,
+ GPMSG_NPC_CLOSE,
+ GPMSG_NPC_NUMBER,
+ GPMSG_NPC_STRING,
+ 0
+ };
+ handledMessages = _messages;
+ npcHandler = this;
+}
+
+void NpcHandler::handleMessage(Net::MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being || being->getType() != ActorSprite::NPC)
+ {
+ return;
+ }
+
+ int npcId = being->getId();
+ NpcDialogs::iterator diag = mNpcDialogs.find(npcId);
+ NpcDialog *dialog;
+
+ if (diag == mNpcDialogs.end())
+ {
+ if (msg.getId() == GPMSG_NPC_ERROR || msg.getId() == GPMSG_NPC_CLOSE)
+ return; // Dialog is pointless in these cases
+
+ dialog = new NpcDialog(npcId);
+ Wrapper wrap;
+ wrap.dialog = dialog;
+ mNpcDialogs[npcId] = wrap;
+ }
+ else
+ {
+ dialog = diag->second.dialog;
+ }
+
+ switch (msg.getId())
+ {
+ case GPMSG_NPC_CHOICE:
+ dialog->choiceRequest();
+ while (msg.getUnreadLength())
+ {
+ dialog->addChoice(msg.readString());
+ }
+ break;
+
+ case GPMSG_NPC_NUMBER:
+ {
+ int min_num = msg.readInt32();
+ int max_num = msg.readInt32();
+ dialog->integerRequest(msg.readInt32(), min_num, max_num);
+ break;
+ }
+
+ case GPMSG_NPC_STRING:
+ dialog->textRequest("");
+ break;
+
+ case GPMSG_NPC_POST:
+ {
+ new NpcPostDialog(npcId);
+ break;
+ }
+
+ case GPMSG_NPC_ERROR:
+ dialog->close();
+ if (diag != mNpcDialogs.end())
+ {
+ mNpcDialogs.erase(diag);
+ }
+ break;
+
+ case GPMSG_NPC_MESSAGE:
+ dialog->addText(msg.readString(msg.getUnreadLength()));
+ dialog->showNextButton();
+ break;
+
+ case GPMSG_NPC_CLOSE:
+ dialog->showCloseButton();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void NpcHandler::talk(int npcId)
+{
+ MessageOut msg(PGMSG_NPC_TALK);
+ msg.writeInt16(npcId);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::nextDialog(int npcId)
+{
+ MessageOut msg(PGMSG_NPC_TALK_NEXT);
+ msg.writeInt16(npcId);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::closeDialog(int npcId)
+{
+ MessageOut msg(PGMSG_NPC_TALK_NEXT);
+ msg.writeInt16(npcId);
+ gameServerConnection->send(msg);
+
+ NpcDialogs::iterator it = mNpcDialogs.find(npcId);
+ if (it != mNpcDialogs.end())
+ {
+ (*it).second.dialog->close();
+ mNpcDialogs.erase(it);
+ }
+}
+
+void NpcHandler::listInput(int npcId, unsigned char value)
+{
+ MessageOut msg(PGMSG_NPC_SELECT);
+ msg.writeInt16(npcId);
+ msg.writeInt8(value);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::integerInput(int npcId, int value)
+{
+ MessageOut msg(PGMSG_NPC_NUMBER);
+ msg.writeInt16(npcId);
+ msg.writeInt32(value);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::stringInput(int npcId, const std::string &value)
+{
+ MessageOut msg(PGMSG_NPC_STRING);
+ msg.writeInt16(npcId);
+ msg.writeString(value);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::sendLetter(int npcId _UNUSED_, const std::string &recipient,
+ const std::string &text)
+{
+ MessageOut msg(PGMSG_NPC_POST_SEND);
+ msg.writeString(recipient);
+ msg.writeString(text);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::startShopping(int beingId _UNUSED_)
+{
+ // TODO
+}
+
+void NpcHandler::buy(int beingId _UNUSED_)
+{
+ // TODO
+}
+
+void NpcHandler::sell(int beingId _UNUSED_)
+{
+ // TODO
+}
+
+void NpcHandler::buyItem(int beingId _UNUSED_, int itemId, int amount)
+{
+ MessageOut msg(PGMSG_NPC_BUYSELL);
+ msg.writeInt16(itemId);
+ msg.writeInt16(amount);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::sellItem(int beingId _UNUSED_, int itemId, int amount)
+{
+ MessageOut msg(PGMSG_NPC_BUYSELL);
+ msg.writeInt16(itemId);
+ msg.writeInt16(amount);
+ gameServerConnection->send(msg);
+}
+
+void NpcHandler::endShopping(int beingId _UNUSED_)
+{
+ // TODO
+}
+
+void NpcHandler::clearDialogs()
+{
+ mNpcDialogs.clear();
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/npchandler.h b/src/net/manaserv/npchandler.h
new file mode 100644
index 000000000..5f47ee388
--- /dev/null
+++ b/src/net/manaserv/npchandler.h
@@ -0,0 +1,89 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_NPCHANDLER_H
+#define NET_MANASERV_NPCHANDLER_H
+
+#include "net/npchandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#include <map>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class NpcDialog;
+
+namespace ManaServ
+{
+
+class NpcHandler : public MessageHandler, public Net::NpcHandler
+{
+ public:
+ NpcHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void talk(int npcId);
+
+ void nextDialog(int npcId);
+
+ void closeDialog(int npcId);
+
+ void listInput(int npcId, unsigned char value);
+
+ void integerInput(int npcId, int value);
+
+ void stringInput(int npcId, const std::string &value);
+
+ void sendLetter(int npcId, const std::string &recipient,
+ const std::string &text);
+
+ void startShopping(int beingId);
+
+ void buy(int beingId);
+
+ void sell(int beingId);
+
+ void buyItem(int beingId, int itemId, int amount);
+
+ void sellItem(int beingId, int itemId, int amount);
+
+ void endShopping(int beingId);
+
+ void clearDialogs();
+
+ private:
+ typedef struct
+ {
+ NpcDialog* dialog;
+ } Wrapper;
+ typedef std::map<int, Wrapper> NpcDialogs;
+ NpcDialogs mNpcDialogs;
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_NPCHANDLER_H
diff --git a/src/net/manaserv/partyhandler.cpp b/src/net/manaserv/partyhandler.cpp
new file mode 100644
index 000000000..3aec20b6b
--- /dev/null
+++ b/src/net/manaserv/partyhandler.cpp
@@ -0,0 +1,197 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/partyhandler.h"
+
+#include "event.h"
+#include "log.h"
+#include "localplayer.h"
+
+#include "gui/socialwindow.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <iostream>
+
+#define PARTY_ID 1
+
+extern Net::PartyHandler *partyHandler;
+
+namespace ManaServ
+{
+
+extern Connection *chatServerConnection;
+
+PartyHandler::PartyHandler():
+ mParty(Party::getParty(PARTY_ID))
+{
+ static const Uint16 _messages[] =
+ {
+ CPMSG_PARTY_INVITE_RESPONSE,
+ CPMSG_PARTY_INVITED,
+ CPMSG_PARTY_ACCEPT_INVITE_RESPONSE,
+ CPMSG_PARTY_QUIT_RESPONSE,
+ CPMSG_PARTY_NEW_MEMBER,
+ CPMSG_PARTY_MEMBER_LEFT,
+ CPMSG_PARTY_REJECTED,
+ 0
+ };
+ handledMessages = _messages;
+ partyHandler = this;
+}
+
+void PartyHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case CPMSG_PARTY_INVITE_RESPONSE:
+ {
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+
+ }
+ } break;
+
+ case CPMSG_PARTY_INVITED:
+ {
+ socialWindow->showPartyInvite(msg.readString());
+ } break;
+
+ case CPMSG_PARTY_ACCEPT_INVITE_RESPONSE:
+ {
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ //
+ SERVER_NOTICE(_("Joined party."));
+ }
+ }
+
+ case CPMSG_PARTY_QUIT_RESPONSE:
+ {
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ mParty->clearMembers();
+ player_node->setParty(NULL);
+ }
+ } break;
+
+ case CPMSG_PARTY_NEW_MEMBER:
+ {
+ int id = msg.readInt16(); // being id
+ std::string name = msg.readString();
+
+ SERVER_NOTICE(strprintf(_("%s joined the party."),
+ name.c_str()));
+
+ if (id == player_node->getId())
+ player_node->setParty(mParty);
+
+ mParty->addMember(id, name);
+ } break;
+
+ case CPMSG_PARTY_MEMBER_LEFT:
+ {
+ mParty->removeMember(msg.readString());
+ } break;
+
+ case CPMSG_PARTY_REJECTED:
+ {
+ std::string name = msg.readString();
+ SERVER_NOTICE(strprintf(
+ _("%s rejected your invite."), name.c_str()));
+ } break;
+ default:
+ break;
+ }
+}
+
+void PartyHandler::create(const std::string &name _UNUSED_)
+{
+ // TODO
+}
+
+void PartyHandler::join(int partyId _UNUSED_)
+{
+ // TODO
+}
+
+void PartyHandler::invite(Being *being)
+{
+ invite(being->getName());
+}
+
+void PartyHandler::invite(const std::string &name)
+{
+ MessageOut msg(PCMSG_PARTY_INVITE);
+
+ msg.writeString(name);
+
+ chatServerConnection->send(msg);
+}
+
+void PartyHandler::inviteResponse(const std::string &inviter, bool accept)
+{
+ MessageOut msg = MessageOut(accept ? PCMSG_PARTY_ACCEPT_INVITE :
+ PCMSG_PARTY_REJECT_INVITE);
+
+ msg.writeString(inviter);
+
+ chatServerConnection->send(msg);
+}
+
+void PartyHandler::leave()
+{
+ MessageOut msg(PCMSG_PARTY_QUIT);
+
+ chatServerConnection->send(msg);
+}
+
+void PartyHandler::kick(Being *being _UNUSED_)
+{
+ // TODO
+}
+
+void PartyHandler::kick(const std::string &name _UNUSED_)
+{
+ // TODO
+}
+
+void PartyHandler::chat(const std::string &text _UNUSED_)
+{
+ // TODO
+}
+
+void PartyHandler::requestPartyMembers()
+{
+ //MessageOut msg(PCMSG_GUILD_GET_MEMBERS);
+
+ //msg.writeInt16(guildId);
+
+ //chatServerConnection->send(msg);
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/partyhandler.h b/src/net/manaserv/partyhandler.h
new file mode 100644
index 000000000..b2c8ce49e
--- /dev/null
+++ b/src/net/manaserv/partyhandler.h
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_PARTYHANDLER_H
+#define NET_MANASERV_PARTYHANDLER_H
+
+#include "net/partyhandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#include "party.h"
+
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class PartyHandler : public MessageHandler, public Net::PartyHandler
+{
+public:
+ PartyHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void create(const std::string &name = "");
+
+ void join(int partyId);
+
+ void invite(Being *being);
+
+ void invite(const std::string &name);
+
+ void inviteResponse(const std::string &inviter, bool accept);
+
+ void leave();
+
+ void kick(Being *being);
+
+ void kick(const std::string &name);
+
+ void chat(const std::string &text);
+
+ void requestPartyMembers();
+
+ PartyShare getShareExperience() { return PARTY_SHARE_NO; }
+
+ void setShareExperience(PartyShare share _UNUSED_) {}
+
+ PartyShare getShareItems() { return PARTY_SHARE_NO; }
+
+ void setShareItems(PartyShare share _UNUSED_) {}
+private:
+ Party *mParty;
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_PARTYHANDLER_H
diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp
new file mode 100644
index 000000000..3af82486c
--- /dev/null
+++ b/src/net/manaserv/playerhandler.cpp
@@ -0,0 +1,440 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/playerhandler.h"
+#include "net/manaserv/beinghandler.h"
+
+#include "client.h"
+#include "effectmanager.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "particle.h"
+#include "playerinfo.h"
+#include "configuration.h"
+
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/okdialog.h"
+#include "gui/viewport.h"
+
+#include "net/net.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/defines.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/npchandler.h"
+#include "net/manaserv/protocol.h"
+#include "net/manaserv/attributes.h"
+
+/**
+ * Max. distance we are willing to scroll after a teleport;
+ * everything beyond will reset the port hard.
+ * 32 is the nominal tile width/height.
+ * @todo: Make this parameter read from config.
+ */
+static const int MAP_TELEPORT_SCROLL_DISTANCE = 8 * 32;
+
+extern Net::PlayerHandler *playerHandler;
+
+namespace ManaServ
+{
+
+void RespawnRequestListener::action(const gcn::ActionEvent &event _UNUSED_)
+{
+ Net::getPlayerHandler()->respawn();
+
+ ManaServ::NpcHandler *handler =
+ static_cast<ManaServ::NpcHandler*>(Net::getNpcHandler());
+ handler->clearDialogs();
+}
+
+extern Connection *gameServerConnection;
+
+PlayerHandler::PlayerHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_PLAYER_MAP_CHANGE,
+ GPMSG_PLAYER_SERVER_CHANGE,
+ GPMSG_PLAYER_ATTRIBUTE_CHANGE,
+ GPMSG_PLAYER_EXP_CHANGE,
+ GPMSG_LEVELUP,
+ GPMSG_LEVEL_PROGRESS,
+ GPMSG_RAISE_ATTRIBUTE_RESPONSE,
+ GPMSG_LOWER_ATTRIBUTE_RESPONSE,
+ GPMSG_SPECIAL_STATUS,
+ 0
+ };
+ handledMessages = _messages;
+ playerHandler = this;
+}
+
+void PlayerHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_PLAYER_MAP_CHANGE:
+ handleMapChangeMessage(msg);
+ break;
+
+ case GPMSG_PLAYER_SERVER_CHANGE:
+ { // TODO: Implement reconnecting to another game server
+ std::string token = msg.readString(32);
+ std::string address = msg.readString();
+ int port = msg.readInt16();
+ logger->log("Changing server to %s:%d", address.c_str(), port);
+ } break;
+
+ case GPMSG_PLAYER_ATTRIBUTE_CHANGE:
+ {
+ logger->log1("ATTRIBUTE UPDATE:");
+ while (msg.getUnreadLength())
+ {
+ int attrId = msg.readInt16();
+ double base = msg.readInt32() / 256.0;
+ double value = msg.readInt32() / 256.0;
+
+ // Set the core player attribute the stat
+ // depending on attribute link.
+ int playerInfoId =
+ Attributes::getPlayerInfoIdFromAttrId(attrId);
+ if (playerInfoId > -1)
+ {
+ PlayerInfo::setAttribute(playerInfoId, value);
+ }
+ else
+ {
+ PlayerInfo::setStatBase(attrId, base);
+ PlayerInfo::setStatMod(attrId, value - base);
+ }
+ }
+ } break;
+
+ case GPMSG_PLAYER_EXP_CHANGE:
+ {
+ logger->log1("EXP Update");
+ while (msg.getUnreadLength())
+ {
+ int skill = msg.readInt16();
+ int current = msg.readInt32();
+ int next = msg.readInt32();
+
+ PlayerInfo::setStatExperience(skill, current, next);
+ }
+ } break;
+
+ case GPMSG_LEVELUP:
+ {
+ PlayerInfo::setAttribute(LEVEL, msg.readInt16());
+ PlayerInfo::setAttribute(CHAR_POINTS, msg.readInt16());
+ PlayerInfo::setAttribute(CORR_POINTS, msg.readInt16());
+ Particle* effect = particleEngine->addEffect(
+ paths.getStringValue("particles")
+ + paths.getStringValue("levelUpEffectFile")
+ , 0, 0);
+ player_node->controlParticle(effect);
+ } break;
+
+
+ case GPMSG_LEVEL_PROGRESS:
+ {
+ PlayerInfo::setAttribute(EXP, msg.readInt8());
+ } break;
+
+
+ case GPMSG_RAISE_ATTRIBUTE_RESPONSE:
+ {
+ int errCode = msg.readInt8();
+ int attrNum = msg.readInt16();
+ switch (errCode)
+ {
+ case ATTRIBMOD_OK:
+ {
+ // feel(acknowledgment);
+ } break;
+ case ATTRIBMOD_INVALID_ATTRIBUTE:
+ {
+ logger->log("Warning: Server denied increase of attribute"
+ " %d (unknown attribute) ", attrNum);
+ } break;
+ case ATTRIBMOD_NO_POINTS_LEFT:
+ {
+ // when the server says "you got no points" it
+ // has to be correct. The server is always right!
+ // undo attribute change and set points to 0
+ logger->log("Warning: Server denied increase of attribute"
+ " %d (no points left) ", attrNum);
+ int attrValue = PlayerInfo::getStatBase(attrNum) - 1;
+ PlayerInfo::setAttribute(CHAR_POINTS, 0);
+ PlayerInfo::setStatBase(attrNum, attrValue);
+ } break;
+ case ATTRIBMOD_DENIED:
+ {
+ // undo attribute change
+ logger->log("Warning: Server denied increase of attribute"
+ " %d (reason unknown) ", attrNum);
+ int points = PlayerInfo::getAttribute(CHAR_POINTS) - 1;
+ PlayerInfo::setAttribute(CHAR_POINTS, points);
+
+ int attrValue = PlayerInfo::getStatBase(attrNum) - 1;
+ PlayerInfo::setStatBase(attrNum, attrValue);
+ } break;
+ default:
+ break;
+ }
+ } break;
+
+ case GPMSG_LOWER_ATTRIBUTE_RESPONSE:
+ {
+ int errCode = msg.readInt8();
+ int attrNum = msg.readInt16();
+ switch (errCode)
+ {
+ case ATTRIBMOD_OK:
+ {
+ // feel(acknowledgment);
+ } break;
+ case ATTRIBMOD_INVALID_ATTRIBUTE:
+ {
+ logger->log("Warning: Server denied reduction of attribute"
+ " %d (unknown attribute) ", attrNum);
+ } break;
+ case ATTRIBMOD_NO_POINTS_LEFT:
+ {
+ // when the server says "you got no points" it
+ // has to be correct. The server is always right!
+ // undo attribute change and set points to 0
+ logger->log("Warning: Server denied reduction of attribute"
+ " %d (no points left) ", attrNum);
+ int attrValue = PlayerInfo::getStatBase(attrNum) + 1;
+ PlayerInfo::setAttribute(CHAR_POINTS, 0);
+ PlayerInfo::setAttribute(CORR_POINTS, 0);
+ PlayerInfo::setStatBase(attrNum, attrValue);
+ break;
+ } break;
+ case ATTRIBMOD_DENIED:
+ {
+ // undo attribute change
+ logger->log("Warning: Server denied reduction of attribute"
+ " %d (reason unknown) ", attrNum);
+ int charaPoints = PlayerInfo::getAttribute(
+ CHAR_POINTS) - 1;
+
+ PlayerInfo::setAttribute(CHAR_POINTS, charaPoints);
+
+ int correctPoints = PlayerInfo::getAttribute(CORR_POINTS)
+ + 1;
+
+ PlayerInfo::setAttribute(CORR_POINTS, correctPoints);
+
+ int attrValue = PlayerInfo::getStatBase(attrNum) + 1;
+ PlayerInfo::setStatBase(attrNum, attrValue);
+ } break;
+ default:
+ break;
+ }
+
+ } break;
+
+ case GPMSG_SPECIAL_STATUS :
+ {
+ while (msg.getUnreadLength())
+ {
+ // { B specialID, L current, L max, L recharge }
+ int id = msg.readInt8();
+ int current = msg.readInt32();
+ int max = msg.readInt32();
+ int recharge = msg.readInt32();
+ PlayerInfo::setSpecialStatus(id, current, max, recharge);
+ }
+ } break;
+ /*
+ case SMSG_PLAYER_ARROW_MESSAGE:
+ {
+ Sint16 type = msg.readInt16();
+
+ switch (type)
+ {
+ case 0:
+ localChatTab->chatLog(_("Equip arrows first."),
+ BY_SERVER);
+ break;
+ default:
+ logger->log("0x013b: Unhandled message %i", type);
+ break;
+ }
+ }
+ break;
+ */
+ default:
+ break;
+ }
+}
+
+void PlayerHandler::handleMapChangeMessage(Net::MessageIn &msg)
+{
+ const std::string mapName = msg.readString();
+ const unsigned short x = msg.readInt16();
+ const unsigned short y = msg.readInt16();
+
+ Game *game = Game::instance();
+ const bool sameMap = (game->getCurrentMapName() == mapName);
+
+ logger->log("Changing map to %s (%d, %d)", mapName.c_str(), x, y);
+
+ // Switch the actual map, deleting the previous one
+ game->changeMap(mapName);
+
+ const Vector &playerPos = player_node->getPosition();
+ float scrollOffsetX = 0.0f;
+ float scrollOffsetY = 0.0f;
+
+ /* Scroll if neccessary */
+ if (!sameMap
+ || (abs(x - (int) playerPos.x) > MAP_TELEPORT_SCROLL_DISTANCE)
+ || (abs(y - (int) playerPos.y) > MAP_TELEPORT_SCROLL_DISTANCE))
+ {
+ scrollOffsetX = x - (int) playerPos.x;
+ scrollOffsetY = y - (int) playerPos.y;
+ }
+
+ player_node->setAction(Being::STAND);
+ player_node->setPosition(x, y);
+ player_node->setDestination(x, y);
+
+ logger->log("Adjust scrolling by %d,%d", (int) scrollOffsetX,
+ (int) scrollOffsetY);
+ viewport->scrollBy(scrollOffsetX, scrollOffsetY);
+}
+
+void PlayerHandler::attack(int id, bool keep _UNUSED_)
+{
+ MessageOut msg(PGMSG_ATTACK);
+ msg.writeInt16(id);
+ gameServerConnection->send(msg);
+}
+
+void PlayerHandler::stopAttack()
+{
+
+}
+
+void PlayerHandler::emote(int emoteId _UNUSED_)
+{
+ // TODO
+}
+
+void PlayerHandler::increaseAttribute(int attr)
+{
+ MessageOut msg(PGMSG_RAISE_ATTRIBUTE);
+ msg.writeInt16(attr);
+ gameServerConnection->send(msg);
+}
+
+void PlayerHandler::decreaseAttribute(int attr)
+{
+ MessageOut msg(PGMSG_LOWER_ATTRIBUTE);
+ msg.writeInt16(attr);
+ gameServerConnection->send(msg);
+}
+
+void PlayerHandler::increaseSkill(int skillId _UNUSED_)
+{
+ // Not used atm
+}
+
+void PlayerHandler::pickUp(FloorItem *floorItem)
+{
+ if (floorItem)
+ {
+ int id = floorItem->getId();
+ MessageOut msg(PGMSG_PICKUP);
+ msg.writeInt16(id >> 16);
+ msg.writeInt16(id & 0xFFFF);
+ gameServerConnection->send(msg);
+ }
+}
+
+void PlayerHandler::setDirection(char direction)
+{
+ MessageOut msg(PGMSG_DIRECTION_CHANGE);
+ msg.writeInt8(direction);
+ gameServerConnection->send(msg);
+}
+
+void PlayerHandler::setDestination(int x, int y, int /* direction */)
+{
+ MessageOut msg(PGMSG_WALK);
+ msg.writeInt16(x);
+ msg.writeInt16(y);
+ gameServerConnection->send(msg);
+}
+
+void PlayerHandler::changeAction(Being::Action action)
+{
+ player_node->setAction(action);
+
+ MessageOut msg(PGMSG_ACTION_CHANGE);
+ msg.writeInt8(action);
+ gameServerConnection->send(msg);
+}
+
+void PlayerHandler::respawn()
+{
+ MessageOut msg(PGMSG_RESPAWN);
+ gameServerConnection->send(msg);
+}
+
+void PlayerHandler::ignorePlayer(const std::string &player _UNUSED_,
+ bool ignore _UNUSED_)
+{
+ // TODO
+}
+
+void PlayerHandler::ignoreAll(bool ignore _UNUSED_)
+{
+ // TODO
+}
+
+bool PlayerHandler::canUseMagic()
+{
+ return true;
+}
+
+bool PlayerHandler::canCorrectAttributes()
+{
+ return true;
+}
+
+int PlayerHandler::getJobLocation()
+{
+ return -1;
+}
+
+Vector PlayerHandler::getDefaultWalkSpeed()
+{
+ // Return translation in pixels per ticks.
+ return ManaServ::BeingHandler::giveSpeedInPixelsPerTicks(6.0f);
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h
new file mode 100644
index 000000000..ddd510714
--- /dev/null
+++ b/src/net/manaserv/playerhandler.h
@@ -0,0 +1,85 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_PLAYERHANDLER_H
+#define NET_MANASERV_PLAYERHANDLER_H
+
+#include "net/playerhandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#include <guichan/actionlistener.hpp>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+struct RespawnRequestListener : public gcn::ActionListener
+{
+ void action(const gcn::ActionEvent &event);
+};
+
+static RespawnRequestListener respawnListener;
+
+class PlayerHandler : public MessageHandler, public Net::PlayerHandler
+{
+ public:
+ PlayerHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void attack(int id, bool keep = false);
+ void stopAttack();
+ void emote(int emoteId);
+
+ void increaseAttribute(int attr);
+ void decreaseAttribute(int attr);
+ void increaseSkill(int skillId);
+
+ void pickUp(FloorItem *floorItem);
+ void setDirection(char direction);
+ void setDestination(int x, int y, int direction = -1);
+ void changeAction(Being::Action action);
+
+ void respawn();
+
+ void ignorePlayer(const std::string &player, bool ignore);
+ void ignoreAll(bool ignore);
+
+ bool canUseMagic();
+ bool canCorrectAttributes();
+
+ int getJobLocation();
+
+ Vector getDefaultWalkSpeed();
+
+ private:
+ void handleMapChangeMessage(Net::MessageIn &msg);
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_PLAYERHANDLER_H
diff --git a/src/net/manaserv/protocol.h b/src/net/manaserv/protocol.h
new file mode 100644
index 000000000..2b5efd69c
--- /dev/null
+++ b/src/net/manaserv/protocol.h
@@ -0,0 +1,392 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MANASERV_PROTOCOL_H
+#define MANASERV_PROTOCOL_H
+
+/**
+ * Enumerated type for communicated messages:
+ *
+ * - PAMSG_*: from client to account server
+ * - APMSG_*: from account server to client
+ * - PCMSG_*: from client to chat server
+ * - CPMSG_*: from chat server to client
+ * - PGMSG_*: from client to game server
+ * - GPMSG_*: from game server to client
+ * - GAMSG_*: from game server to account server
+ *
+ * Components: B byte, W word, D double word, S variable-size string
+ * C tile-based coordinates (B*3)
+ *
+ * Hosts: P (player's client), A (account server), C (char server),
+ * G (game server)
+ *
+ * TODO - Document specific error codes for each packet
+ */
+enum {
+ // Login/Register
+ PAMSG_REGISTER = 0x0000, // D version, S username, S password, S email, S captcha response
+ APMSG_REGISTER_RESPONSE = 0x0002, // B error, S updatehost, S Client data URL, B Character slots
+ PAMSG_UNREGISTER = 0x0003, // S username, S password
+ APMSG_UNREGISTER_RESPONSE = 0x0004, // B error
+ PAMSG_REQUEST_REGISTER_INFO = 0x0005, //
+ APMSG_REGISTER_INFO_RESPONSE = 0x0006, // B byte registration Allowed, byte minNameLength, byte maxNameLength, string captchaURL, string captchaInstructions
+ PAMSG_LOGIN = 0x0010, // D version, S username, S password
+ APMSG_LOGIN_RESPONSE = 0x0012, // B error, S updatehost, S Client data URL, B Character slots
+ PAMSG_LOGOUT = 0x0013, // -
+ APMSG_LOGOUT_RESPONSE = 0x0014, // B error
+ PAMSG_CHAR_CREATE = 0x0020, // S name, B hair style, B hair color, B gender, B slot, W*6 stats
+ APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error
+ PAMSG_CHAR_DELETE = 0x0022, // B slot
+ APMSG_CHAR_DELETE_RESPONSE = 0x0023, // B error
+ // B slot, S name, B gender, B hair style, B hair color, W level,
+ // W character points, W correction points,
+ // {D attr id, D base value (in 1/256ths) D mod value (in 256ths) }*
+ APMSG_CHAR_INFO = 0x0024, // ^
+ PAMSG_CHAR_SELECT = 0x0026, // B slot
+ APMSG_CHAR_SELECT_RESPONSE = 0x0027, // B error, B*32 token, S game address, W game port, S chat address, W chat port
+ PAMSG_EMAIL_CHANGE = 0x0030, // S email
+ APMSG_EMAIL_CHANGE_RESPONSE = 0x0031, // B error
+ PAMSG_PASSWORD_CHANGE = 0x0034, // S old password, S new password
+ APMSG_PASSWORD_CHANGE_RESPONSE = 0x0035, // B error
+
+ PGMSG_CONNECT = 0x0050, // B*32 token
+ GPMSG_CONNECT_RESPONSE = 0x0051, // B error
+ PCMSG_CONNECT = 0x0053, // B*32 token
+ CPMSG_CONNECT_RESPONSE = 0x0054, // B error
+
+ PGMSG_DISCONNECT = 0x0060, // B reconnect account
+ GPMSG_DISCONNECT_RESPONSE = 0x0061, // B error, B*32 token
+ PCMSG_DISCONNECT = 0x0063, // -
+ CPMSG_DISCONNECT_RESPONSE = 0x0064, // B error
+
+ PAMSG_RECONNECT = 0x0065, // B*32 token
+ APMSG_RECONNECT_RESPONSE = 0x0066, // B error
+
+ // Game
+ GPMSG_PLAYER_MAP_CHANGE = 0x0100, // S filename, W x, W y
+ GPMSG_PLAYER_SERVER_CHANGE = 0x0101, // B*32 token, S game address, W game port
+ PGMSG_PICKUP = 0x0110, // W*2 position
+ PGMSG_DROP = 0x0111, // B slot, B amount
+ PGMSG_EQUIP = 0x0112, // B slot
+ PGMSG_UNEQUIP = 0x0113, // B slot
+ PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount
+ GPMSG_INVENTORY = 0x0120, // { W slot, W item id [, W amount] (if item id is nonzero) }*
+ GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount } { B equip slot, W invy slot}*
+ GPMSG_EQUIP = 0x0122, // { W Invy slot, B equip slot type count { B equip slot, B number used} }*
+ GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, D base value (in 1/256ths), D modified value (in 1/256ths)}*
+ GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }*
+ GPMSG_LEVELUP = 0x0150, // W new level, W character points, W correction points
+ GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup
+ PGMSG_RAISE_ATTRIBUTE = 0x0160, // W attribute
+ GPMSG_RAISE_ATTRIBUTE_RESPONSE = 0x0161, // B error, W attribute
+ PGMSG_LOWER_ATTRIBUTE = 0x0170, // W attribute
+ GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, W attribute
+ PGMSG_RESPAWN = 0x0180, // -
+ GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position
+ // character: S name, B hair style, B hair color, B gender, B item bitmask, { W item id }*
+ // monster: W type id
+ // npc: W type id
+ GPMSG_BEING_LEAVE = 0x0201, // W being id
+ GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position
+ GPMSG_BEING_LOOKS_CHANGE = 0x0210, // W weapon, W hat, W top clothes, W bottom clothes
+ PGMSG_WALK = 0x0260, // W*2 destination
+ PGMSG_ACTION_CHANGE = 0x0270, // B Action
+ GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
+ PGMSG_DIRECTION_CHANGE = 0x0272, // B Direction
+ GPMSG_BEING_DIR_CHANGE = 0x0273, // W being id, B direction
+ GPMSG_BEING_HEALTH_CHANGE = 0x0274, // W being id, W hp, W max hp
+ GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, W*2 position, B speed] }*
+ GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
+ PGMSG_ATTACK = 0x0290, // W being id
+ GPMSG_BEING_ATTACK = 0x0291, // W being id, B direction, B attacktype
+ PGMSG_USE_SPECIAL = 0x0292, // B specialID
+ GPMSG_SPECIAL_STATUS = 0x0293, // { B specialID, D current, D max, D recharge }
+ PGMSG_SAY = 0x02A0, // S text
+ GPMSG_SAY = 0x02A1, // W being id, S text
+ GPMSG_NPC_CHOICE = 0x02B0, // W being id, { S text }*
+ GPMSG_NPC_MESSAGE = 0x02B1, // W being id, B* text
+ PGMSG_NPC_TALK = 0x02B2, // W being id
+ PGMSG_NPC_TALK_NEXT = 0x02B3, // W being id
+ PGMSG_NPC_SELECT = 0x02B4, // W being id, B choice
+ GPMSG_NPC_BUY = 0x02B5, // W being id, { W item id, W amount, W cost }*
+ GPMSG_NPC_SELL = 0x02B6, // W being id, { W item id, W amount, W cost }*
+ PGMSG_NPC_BUYSELL = 0x02B7, // W item id, W amount
+ GPMSG_NPC_ERROR = 0x02B8, // B error
+ GPMSG_NPC_CLOSE = 0x02B9, // W being id
+ GPMSG_NPC_POST = 0x02D0, // W being id
+ PGMSG_NPC_POST_SEND = 0x02D1, // W being id, { S name, S text, W item id }
+ GPMSG_NPC_POST_GET = 0x02D2, // W being id, { S name, S text, W item id }
+ PGMSG_NPC_NUMBER = 0x02D3, // W being id, D number
+ PGMSG_NPC_STRING = 0x02D4, // W being id, S string
+ GPMSG_NPC_NUMBER = 0x02D5, // W being id, D max, D min, D default
+ GPMSG_NPC_STRING = 0x02D6, // W being id
+ PGMSG_TRADE_REQUEST = 0x02C0, // W being id
+ GPMSG_TRADE_REQUEST = 0x02C1, // W being id
+ GPMSG_TRADE_START = 0x02C2, // -
+ GPMSG_TRADE_COMPLETE = 0x02C3, // -
+ PGMSG_TRADE_CANCEL = 0x02C4, // -
+ GPMSG_TRADE_CANCEL = 0x02C5, // -
+ PGMSG_TRADE_AGREED = 0x02C6, // -
+ GPMSG_TRADE_AGREED = 0x02C7, // -
+ PGMSG_TRADE_CONFIRM = 0x02C8, // -
+ GPMSG_TRADE_CONFIRM = 0x02C9, // -
+ PGMSG_TRADE_ADD_ITEM = 0x02CA, // B slot, B amount
+ GPMSG_TRADE_ADD_ITEM = 0x02CB, // W item id, B amount
+ PGMSG_TRADE_SET_MONEY = 0x02CC, // D amount
+ GPMSG_TRADE_SET_MONEY = 0x02CD, // D amount
+ GPMSG_TRADE_BOTH_CONFIRM = 0x02CE, // -
+ PGMSG_USE_ITEM = 0x0300, // B slot
+ GPMSG_USE_RESPONSE = 0x0301, // B error
+ GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
+ GPMSG_CREATE_EFFECT_POS = 0x0320, // W effect id, W*2 position
+ GPMSG_CREATE_EFFECT_BEING = 0x0321, // W effect id, W BeingID
+
+ // Guild
+ PCMSG_GUILD_CREATE = 0x0350, // S name
+ CPMSG_GUILD_CREATE_RESPONSE = 0x0351, // B error, W guild, B rights, W channel
+ PCMSG_GUILD_INVITE = 0x0352, // W id, S name
+ CPMSG_GUILD_INVITE_RESPONSE = 0x0353, // B error
+ PCMSG_GUILD_ACCEPT = 0x0354, // W id
+ CPMSG_GUILD_ACCEPT_RESPONSE = 0x0355, // B error, W guild, B rights, W channel
+ PCMSG_GUILD_GET_MEMBERS = 0x0356, // W id
+ CPMSG_GUILD_GET_MEMBERS_RESPONSE = 0x0357, // S names, B online
+ CPMSG_GUILD_UPDATE_LIST = 0x0358, // W id, S name, B event
+ PCMSG_GUILD_QUIT = 0x0360, // W id
+ CPMSG_GUILD_QUIT_RESPONSE = 0x0361, // B error
+ PCMSG_GUILD_PROMOTE_MEMBER = 0x0365, // W guild, S name, B rights
+ CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE = 0x0366, // B error
+ PCMSG_GUILD_KICK_MEMBER = 0x0370, // W guild, S name
+ CPMSG_GUILD_KICK_MEMBER_RESPONSE = 0x0371, // B error
+
+ CPMSG_GUILD_INVITED = 0x0388, // S char name, S guild name, W id
+ CPMSG_GUILD_REJOIN = 0x0389, // S name, W guild, W rights, W channel, S announce
+
+ // Party
+ PCMSG_PARTY_INVITE = 0x03A0, // S name
+ CPMSG_PARTY_INVITE_RESPONSE = 0x03A1, // B error, S name
+ CPMSG_PARTY_INVITED = 0x03A2, // S name
+ PCMSG_PARTY_ACCEPT_INVITE = 0x03A5, // S name
+ CPMSG_PARTY_ACCEPT_INVITE_RESPONSE = 0x03A6, // B error, { S name }
+ PCMSG_PARTY_REJECT_INVITE = 0x03A7, // S name
+ CPMSG_PARTY_REJECTED = 0x03A8, // S name
+ PCMSG_PARTY_QUIT = 0x03AA, // -
+ CPMSG_PARTY_QUIT_RESPONSE = 0x03AB, // B error
+ CPMSG_PARTY_NEW_MEMBER = 0x03B0, // W being id, S name
+ CPMSG_PARTY_MEMBER_LEFT = 0x03B1, // W being id
+
+ // Chat
+ CPMSG_ERROR = 0x0401, // B error
+ CPMSG_ANNOUNCEMENT = 0x0402, // S text
+ CPMSG_PRIVMSG = 0x0403, // S user, S text
+ CPMSG_PUBMSG = 0x0404, // W channel, S user, S text
+ PCMSG_CHAT = 0x0410, // S text, W channel
+ PCMSG_ANNOUNCE = 0x0411, // S text
+ PCMSG_PRIVMSG = 0x0412, // S user, S text
+ PCMSG_WHO = 0x0415, // -
+ CPMSG_WHO_RESPONSE = 0x0416, // { S user }
+
+ // -- Channeling
+ CPMSG_CHANNEL_EVENT = 0x0430, // W channel, B event, S info
+ PCMSG_ENTER_CHANNEL = 0x0440, // S channel, S password
+ CPMSG_ENTER_CHANNEL_RESPONSE = 0x0441, // B error, W id, S name, S topic, S userlist
+ PCMSG_QUIT_CHANNEL = 0x0443, // W channel id
+ CPMSG_QUIT_CHANNEL_RESPONSE = 0x0444, // B error, W channel id
+ PCMSG_LIST_CHANNELS = 0x0445, // -
+ CPMSG_LIST_CHANNELS_RESPONSE = 0x0446, // S names, W number of users
+ PCMSG_LIST_CHANNELUSERS = 0x0460, // S channel
+ CPMSG_LIST_CHANNELUSERS_RESPONSE = 0x0461, // S channel, { S user, B mode }
+ PCMSG_TOPIC_CHANGE = 0x0462, // W channel id, S topic
+ // -- User modes
+ PCMSG_USER_MODE = 0x0465, // W channel id, S name, B mode
+ PCMSG_KICK_USER = 0x0466, // W channel id, S name
+
+ // Inter-server
+ GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision, { W map id }*
+ AGMSG_REGISTER_RESPONSE = 0x0501, // C item version, C password response
+ AGMSG_ACTIVE_MAP = 0x0502, // W map id
+ AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, D id, S name, serialised character data
+ GAMSG_PLAYER_DATA = 0x0520, // D id, serialised character data
+ GAMSG_REDIRECT = 0x0530, // D id
+ AGMSG_REDIRECT_RESPONSE = 0x0531, // D id, B*32 token, S game address, W game port
+ GAMSG_PLAYER_RECONNECT = 0x0532, // D id, B*32 token
+ GAMSG_PLAYER_SYNC = 0x0533, // serialised sync data
+ GAMSG_SET_QUEST = 0x0540, // D id, S name, S value
+ GAMSG_GET_QUEST = 0x0541, // D id, S name
+ AGMSG_GET_QUEST_RESPONSE = 0x0542, // D id, S name, S value
+ GAMSG_BAN_PLAYER = 0x0550, // D id, W duration
+ GAMSG_CHANGE_PLAYER_LEVEL = 0x0555, // D id, W level
+ GAMSG_CHANGE_ACCOUNT_LEVEL = 0x0556, // D id, W level
+ GAMSG_STATISTICS = 0x0560, // { W map id, W thing nb, W monster nb, W player nb, { D character id }* }*
+ CGMSG_CHANGED_PARTY = 0x0590, // D character id, D party id
+ GCMSG_REQUEST_POST = 0x05A0, // D character id
+ CGMSG_POST_RESPONSE = 0x05A1, // D receiver id, { S sender name, S letter, W num attachments { W attachment item id, W quantity } }
+ GCMSG_STORE_POST = 0x05A5, // D sender id, S receiver name, S letter, { W attachment item id, W quantity }
+ CGMSG_STORE_POST_RESPONSE = 0x05A6, // D id, B error
+ GAMSG_TRANSACTION = 0x0600, // D character id, D action, S message
+
+ XXMSG_INVALID = 0x7FFF
+};
+
+// Generic return values
+
+enum {
+ ERRMSG_OK = 0, // everything is fine
+ ERRMSG_FAILURE, // the action failed
+ ERRMSG_NO_LOGIN, // the user is not yet logged
+ ERRMSG_NO_CHARACTER_SELECTED, // the user needs a character
+ ERRMSG_INSUFFICIENT_RIGHTS, // the user is not privileged
+ ERRMSG_INVALID_ARGUMENT, // part of the received message was invalid
+ ERRMSG_EMAIL_ALREADY_EXISTS, // The Email Address already exists
+ ERRMSG_ALREADY_TAKEN, // name used was already taken
+ ERRMSG_SERVER_FULL, // the server is overloaded
+ ERRMSG_TIME_OUT, // data failed to arrive in due time
+ ERRMSG_LIMIT_REACHED // limit reached
+};
+
+// used in AGMSG_REGISTER_RESPONSE to show state of item db
+enum {
+ DATA_VERSION_OK = 0x00,
+ DATA_VERSION_OUTDATED = 0x01
+};
+
+// used in AGMSG_REGISTER_RESPNSE to show if password was accepted
+enum {
+ PASSWORD_OK = 0x00,
+ PASSWORD_BAD = 0x01
+};
+
+// used to identify part of sync message
+enum {
+ SYNC_CHARACTER_POINTS = 0x01, // D charId, D charPoints, D corrPoints
+ SYNC_CHARACTER_ATTRIBUTE = 0x02, // D charId, D attrId, DF base, DF mod
+ SYNC_CHARACTER_SKILL = 0x03, // D charId, B skillId, D skill value
+ SYNC_ONLINE_STATUS = 0x04, // D charId, B 0x00 = offline, 0x01 = online
+ SYNC_END_OF_BUFFER = 0xFF // shows, that the buffer ends here.
+};
+
+// Login specific return values
+enum {
+ LOGIN_INVALID_VERSION = 0x40, // the user is using an incompatible protocol
+ LOGIN_INVALID_TIME = 0x50, // the user tried logging in too fast
+ LOGIN_BANNED // the user is currently banned
+};
+
+// Account register specific return values
+enum {
+ REGISTER_INVALID_VERSION = 0x40, // the user is using an incompatible protocol
+ REGISTER_EXISTS_USERNAME, // there already is an account with this username
+ REGISTER_EXISTS_EMAIL, // there already is an account with this email address
+ REGISTER_CAPTCHA_WRONG // user didn't solve the captcha correctly
+};
+
+// Character creation specific return values
+enum {
+ CREATE_INVALID_HAIRSTYLE = 0x40,
+ CREATE_INVALID_HAIRCOLOR,
+ CREATE_INVALID_GENDER,
+ CREATE_ATTRIBUTES_TOO_HIGH,
+ CREATE_ATTRIBUTES_TOO_LOW,
+ CREATE_ATTRIBUTES_OUT_OF_RANGE,
+ CREATE_EXISTS_NAME,
+ CREATE_TOO_MUCH_CHARACTERS,
+ CREATE_INVALID_SLOT
+};
+
+// Character attribute modification specific return value
+enum AttribmodResponseCode {
+ ATTRIBMOD_OK = ERRMSG_OK,
+ ATTRIBMOD_INVALID_ATTRIBUTE = 0x40,
+ ATTRIBMOD_NO_POINTS_LEFT,
+ ATTRIBMOD_DENIED
+};
+
+// Object type enumeration
+enum ThingType
+{
+ // A simple item.
+ OBJECT_ITEM = 0,
+ // An item that toggle map/quest actions (doors, switchs, ...)
+ // and can speak (map panels).
+ OBJECT_ACTOR,
+ // Non-Playable-Character is an actor capable of movement and maybe actions.
+ OBJECT_NPC,
+ // A monster (moving actor with AI. Should be able to toggle map/quest
+ // actions, too).
+ OBJECT_MONSTER,
+ // A normal being.
+ OBJECT_CHARACTER,
+ // A effect to be shown.
+ OBJECT_EFFECT,
+ // Server-only object.
+ OBJECT_OTHER
+};
+
+// Moving object flags
+enum {
+ // Payload contains the current position.
+ MOVING_POSITION = 1,
+ // Payload contains the destination.
+ MOVING_DESTINATION = 2
+};
+
+// Email change specific return values
+enum {
+ EMAILCHG_EXISTS_EMAIL = 0x40
+};
+
+// Chat errors return values
+enum {
+ CHAT_USING_BAD_WORDS = 0x40,
+ CHAT_UNHANDLED_COMMAND
+};
+
+// Chat channels event values
+enum {
+ CHAT_EVENT_NEW_PLAYER = 0,
+ CHAT_EVENT_LEAVING_PLAYER,
+ CHAT_EVENT_TOPIC_CHANGE,
+ CHAT_EVENT_MODE_CHANGE,
+ CHAT_EVENT_KICKED_PLAYER
+};
+
+// Guild member event values
+enum {
+ GUILD_EVENT_NEW_PLAYER = 0,
+ GUILD_EVENT_LEAVING_PLAYER,
+ GUILD_EVENT_ONLINE_PLAYER,
+ GUILD_EVENT_OFFLINE_PLAYER
+};
+
+
+enum
+{
+ SPRITE_BASE = 0,
+ SPRITE_SHOE,
+ SPRITE_BOTTOMCLOTHES,
+ SPRITE_TOPCLOTHES,
+ SPRITE_HAIR,
+ SPRITE_HAT,
+ SPRITE_WEAPON,
+ SPRITE_VECTOREND
+};
+
+#endif // MANASERV_PROTOCOL_H
diff --git a/src/net/manaserv/specialhandler.cpp b/src/net/manaserv/specialhandler.cpp
new file mode 100644
index 000000000..8508c9b56
--- /dev/null
+++ b/src/net/manaserv/specialhandler.cpp
@@ -0,0 +1,70 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/specialhandler.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+extern Net::SpecialHandler *specialHandler;
+
+namespace ManaServ
+{
+
+extern Connection *gameServerConnection;
+
+SpecialHandler::SpecialHandler()
+{
+ specialHandler = this;
+}
+
+void SpecialHandler::handleMessage(Net::MessageIn &msg _UNUSED_)
+{
+ // TODO
+}
+
+void SpecialHandler::use(int id)
+{
+ MessageOut msg(PGMSG_USE_SPECIAL);
+ msg.writeInt8(id);
+ gameServerConnection->send(msg);
+}
+
+void SpecialHandler::use(int id _UNUSED_, int level _UNUSED_,
+ int beingId _UNUSED_)
+{
+ // TODO
+}
+
+void SpecialHandler::use(int id _UNUSED_, int level _UNUSED_, int x _UNUSED_,
+ int y _UNUSED_)
+{
+ // TODO
+}
+
+void SpecialHandler::use(int id _UNUSED_, const std::string &map _UNUSED_)
+{
+ // TODO
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/specialhandler.h b/src/net/manaserv/specialhandler.h
new file mode 100644
index 000000000..1f48688bf
--- /dev/null
+++ b/src/net/manaserv/specialhandler.h
@@ -0,0 +1,56 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_SKILLHANDLER_H
+#define NET_MANASERV_SKILLHANDLER_H
+
+#include "net/specialhandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class SpecialHandler : public MessageHandler, public Net::SpecialHandler
+{
+ public:
+ SpecialHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void use(int id);
+
+ void use(int id, int level, int beingId);
+
+ void use(int id, int level, int x, int y);
+
+ void use(int id, const std::string &map);
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_SKILLHANDLER_H
diff --git a/src/net/manaserv/tradehandler.cpp b/src/net/manaserv/tradehandler.cpp
new file mode 100644
index 000000000..5a9fdfabd
--- /dev/null
+++ b/src/net/manaserv/tradehandler.cpp
@@ -0,0 +1,237 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/manaserv/tradehandler.h"
+
+#include "actorspritemanager.h"
+#include "event.h"
+#include "item.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "playerrelations.h"
+
+#include "gui/confirmdialog.h"
+#include "gui/trade.h"
+
+#include "net/net.h"
+
+#include "net/manaserv/connection.h"
+#include "net/manaserv/messagein.h"
+#include "net/manaserv/messageout.h"
+#include "net/manaserv/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern std::string tradePartnerName;
+int tradePartnerID;
+
+extern Net::TradeHandler *tradeHandler;
+
+namespace ManaServ
+{
+
+extern Connection *gameServerConnection;
+
+/**
+ * Listener for request trade dialogs
+ */
+namespace
+{
+ struct RequestTradeListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event)
+ {
+ if (event.getId() == "yes")
+ {
+ ManaServ::MessageOut msg(PGMSG_TRADE_REQUEST);
+ msg.writeInt16(tradePartnerID);
+ gameServerConnection->send(msg);
+ }
+ else if (event.getId() == "ignore")
+ {
+ player_relations.ignoreTrade(tradePartnerName);
+ Net::getTradeHandler()->cancel();
+ }
+ else
+ {
+ Net::getTradeHandler()->cancel();
+ }
+ }
+ } listener;
+}
+
+TradeHandler::TradeHandler():
+ mAcceptTradeRequests(true)
+{
+ static const Uint16 _messages[] =
+ {
+ GPMSG_TRADE_REQUEST,
+ GPMSG_TRADE_CANCEL,
+ GPMSG_TRADE_START,
+ GPMSG_TRADE_COMPLETE,
+ GPMSG_TRADE_AGREED,
+ GPMSG_TRADE_BOTH_CONFIRM,
+ GPMSG_TRADE_CONFIRM,
+ GPMSG_TRADE_ADD_ITEM,
+ GPMSG_TRADE_SET_MONEY,
+ 0
+ };
+ handledMessages = _messages;
+ tradeHandler = this;
+}
+
+void TradeHandler::setAcceptTradeRequests(bool acceptTradeRequests)
+{
+ mAcceptTradeRequests = acceptTradeRequests;
+ if (mAcceptTradeRequests)
+ SERVER_NOTICE(_("Accepting incoming trade requests."))
+ else
+ SERVER_NOTICE(_("Ignoring incoming trade requests."))
+}
+
+void TradeHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_TRADE_REQUEST:
+ {
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being || !mAcceptTradeRequests)
+ {
+ respond(false);
+ break;
+ }
+ PlayerInfo::setTrading(true);
+ tradePartnerName = being->getName();
+ tradePartnerID = being->getId();
+ ConfirmDialog *dlg = new ConfirmDialog(_("Request for Trade"),
+ strprintf(_("%s wants to trade with you, do you accept?"),
+ tradePartnerName.c_str()), true);
+ dlg->addActionListener(&listener);
+ } break;
+
+ case GPMSG_TRADE_ADD_ITEM:
+ {
+ int type = msg.readInt16();
+ int amount = msg.readInt8();
+ tradeWindow->addItem(type, false, amount, 0);
+ } break;
+
+ case GPMSG_TRADE_SET_MONEY:
+ tradeWindow->setMoney(msg.readInt32());
+ break;
+
+ case GPMSG_TRADE_START:
+ tradeWindow->reset();
+ tradeWindow->setCaption(strprintf(_("Trading with %s"),
+ tradePartnerName.c_str()));
+ tradeWindow->setVisible(true);
+ break;
+
+ case GPMSG_TRADE_BOTH_CONFIRM:
+ tradeWindow->receivedOk(false);
+ break;
+
+ case GPMSG_TRADE_AGREED:
+ tradeWindow->receivedOk(false);
+ break;
+
+ case GPMSG_TRADE_CANCEL:
+ SERVER_NOTICE(_("Trade canceled."))
+ tradeWindow->setVisible(false);
+ tradeWindow->reset();
+ PlayerInfo::setTrading(false);
+ break;
+
+ case GPMSG_TRADE_COMPLETE:
+ SERVER_NOTICE(_("Trade completed."))
+ tradeWindow->setVisible(false);
+ tradeWindow->reset();
+ PlayerInfo::setTrading(false);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void TradeHandler::request(Being *being)
+{
+ tradePartnerName = being->getName();
+ tradePartnerID = being->getId();
+
+ MessageOut msg(PGMSG_TRADE_REQUEST);
+ msg.writeInt16(tradePartnerID);
+ gameServerConnection->send(msg);
+}
+
+void TradeHandler::respond(bool accept)
+{
+ MessageOut msg(accept ? PGMSG_TRADE_REQUEST : PGMSG_TRADE_CANCEL);
+ gameServerConnection->send(msg);
+
+ if (!accept)
+ PlayerInfo::setTrading(false);
+}
+
+void TradeHandler::addItem(Item *item, int amount)
+{
+ MessageOut msg(PGMSG_TRADE_ADD_ITEM);
+ msg.writeInt8(item->getInvIndex());
+ msg.writeInt8(amount);
+ gameServerConnection->send(msg);
+
+ tradeWindow->addItem(item->getId(), true, amount, 0);
+ item->increaseQuantity(-amount);
+}
+
+void TradeHandler::removeItem(int slotNum _UNUSED_, int amount _UNUSED_)
+{
+ // TODO
+}
+
+void TradeHandler::setMoney(int amount)
+{
+ MessageOut msg(PGMSG_TRADE_SET_MONEY);
+ msg.writeInt32(amount);
+ gameServerConnection->send(msg);
+}
+
+void TradeHandler::confirm()
+{
+ MessageOut msg(PGMSG_TRADE_CONFIRM);
+ gameServerConnection->send(msg);
+}
+
+void TradeHandler::finish()
+{
+ MessageOut msg(PGMSG_TRADE_AGREED);
+ gameServerConnection->send(msg);
+}
+
+void TradeHandler::cancel()
+{
+ MessageOut msg(PGMSG_TRADE_CANCEL);
+ gameServerConnection->send(msg);
+}
+
+} // namespace ManaServ
diff --git a/src/net/manaserv/tradehandler.h b/src/net/manaserv/tradehandler.h
new file mode 100644
index 000000000..3bbf15470
--- /dev/null
+++ b/src/net/manaserv/tradehandler.h
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MANASERV_TRADEHANDLER_H
+#define NET_MANASERV_TRADEHANDLER_H
+
+#include "net/tradehandler.h"
+
+#include "net/manaserv/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace ManaServ
+{
+
+class TradeHandler : public MessageHandler, public Net::TradeHandler
+{
+ public:
+ TradeHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ /**
+ * Returns whether trade requests are accepted.
+ *
+ * @see setAcceptTradeRequests
+ */
+ bool acceptTradeRequests() const
+ { return mAcceptTradeRequests; }
+
+ /**
+ * Sets whether trade requests are accepted. When set to false, trade
+ * requests are automatically denied. When true, a popup will ask the
+ * player whether he wants to trade.
+ */
+ void setAcceptTradeRequests(bool acceptTradeRequests);
+
+ void request(Being *being);
+
+ void respond(bool accept);
+
+ void addItem(Item *item, int amount);
+
+ void removeItem(int slotNum, int amount);
+
+ void setMoney(int amount);
+
+ void confirm();
+
+ void finish();
+
+ void cancel();
+
+ private:
+ bool mAcceptTradeRequests;
+};
+
+} // namespace ManaServ
+
+#endif // NET_MANASERV_TRADEHANDLER_H
diff --git a/src/net/messagehandler.h b/src/net/messagehandler.h
new file mode 100644
index 000000000..3a454b1f9
--- /dev/null
+++ b/src/net/messagehandler.h
@@ -0,0 +1,50 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MESSAGEHANDLER_H
+#define NET_MESSAGEHANDLER_H
+
+#include "net/messagein.h"
+
+#include <SDL_types.h>
+
+#include <memory>
+
+namespace Net
+{
+
+/**
+ * \ingroup Network
+ */
+class MessageHandler
+{
+ public:
+ const Uint16 *handledMessages;
+
+ virtual void handleMessage(MessageIn &msg) = 0;
+
+ virtual ~MessageHandler()
+ { }
+};
+
+}
+
+#endif // NET_MESSAGEHANDLER_H
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp
new file mode 100644
index 000000000..0ac391ee2
--- /dev/null
+++ b/src/net/messagein.cpp
@@ -0,0 +1,227 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/messagein.h"
+
+#include "net/packetcounters.h"
+
+#include "log.h"
+
+#include "utils/stringutils.h"
+
+#define MAKEWORD(low, high) \
+ ((unsigned short)(((unsigned char)(low)) | \
+ ((unsigned short)((unsigned char)(high))) << 8))
+
+namespace Net
+{
+
+MessageIn::MessageIn(const char *data, unsigned int length):
+ mData(data),
+ mLength(length),
+ mPos(0)
+{
+ PacketCounters::incInPackets();
+ DEBUGLOG("MessageIn");
+}
+
+unsigned char MessageIn::readInt8()
+{
+ unsigned char value = -1;
+ if (mPos < mLength)
+ value = static_cast<unsigned char>(mData[mPos]);
+
+ mPos += 1;
+ PacketCounters::incInBytes(1);
+ DEBUGLOG("readInt8: " + toString(static_cast<int>(value)));
+ return value;
+}
+
+void MessageIn::readCoordinates(Uint16 &x, Uint16 &y)
+{
+ if (mPos + 3 <= mLength)
+ {
+ unsigned char const *p
+ = reinterpret_cast< unsigned char const * >(mData + mPos);
+ x = static_cast<short unsigned>(p[0] | ((p[1] & 0x07) << 8));
+ y = static_cast<short unsigned>((p[1] >> 3) | ((p[2] & 0x3F) << 5));
+ }
+ mPos += 3;
+ PacketCounters::incInBytes(3);
+ DEBUGLOG("readCoordinates: " + toString(static_cast<int>(x)) + ","
+ + toString(static_cast<int>(y)));
+}
+
+void MessageIn::readCoordinates(Uint16 &x, Uint16 &y, Uint8 &direction)
+{
+ if (mPos + 3 <= mLength)
+ {
+ const char *data = mData + mPos;
+ Sint16 temp;
+
+ temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff);
+ x = static_cast<unsigned short>(temp >> 6);
+ temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f);
+ y = static_cast<unsigned short>(temp >> 4);
+
+ direction = data[2] & 0x000f;
+
+ // Translate from eAthena format
+ switch (direction)
+ {
+ case 0:
+ direction = 1;
+ break;
+ case 1:
+ direction = 3;
+ break;
+ case 2:
+ direction = 2;
+ break;
+ case 3:
+ direction = 6;
+ break;
+ case 4:
+ direction = 4;
+ break;
+ case 5:
+ direction = 12;
+ break;
+ case 6:
+ direction = 8;
+ break;
+ case 7:
+ direction = 9;
+ break;
+ default:
+ // OOPSIE! Impossible or unknown
+ direction = 0;
+ }
+ }
+ mPos += 3;
+ PacketCounters::incInBytes(3);
+ DEBUGLOG("readCoordinates: " + toString((int)x) + "," + toString((int)y));
+}
+
+void MessageIn::readCoordinatePair(Uint16 &srcX, Uint16 &srcY,
+ Uint16 &dstX, Uint16 &dstY)
+{
+ if (mPos + 5 <= mLength)
+ {
+ const char *data = mData + mPos;
+ Sint16 temp;
+
+ temp = MAKEWORD(data[3], data[2] & 0x000f);
+ dstX = static_cast<unsigned short>(temp >> 2);
+
+ dstY = MAKEWORD(data[4], data[3] & 0x0003);
+
+ temp = MAKEWORD(data[1], data[0]);
+ srcX = static_cast<unsigned short>(temp >> 6);
+
+ temp = MAKEWORD(data[2], data[1] & 0x003f);
+ srcY = static_cast<unsigned short>(temp >> 4);
+ }
+ mPos += 5;
+ DEBUGLOG("readCoordinatePair: " + toString((int)srcX) + ","
+ + toString((int)srcY) + " " + toString((int)dstX) + ","
+ + toString((int)dstY));
+ PacketCounters::incInBytes(5);
+}
+
+void MessageIn::skip(unsigned int length)
+{
+ mPos += length;
+ PacketCounters::incInBytes(length);
+ DEBUGLOG("skip: " + toString((int)length));
+}
+
+std::string MessageIn::readString(int length)
+{
+ // Get string length
+ if (length < 0)
+ length = readInt16();
+
+ // Make sure the string isn't erroneous
+ if (length < 0 || mPos + length > mLength)
+ {
+ mPos = mLength + 1;
+ DEBUGLOG("readString error");
+ return "";
+ }
+
+ // Read the string
+ char const *stringBeg = mData + mPos;
+ char const *stringEnd
+ = static_cast<char const *>(memchr(stringBeg, '\0', length));
+
+ std::string readString(stringBeg,
+ stringEnd ? stringEnd - stringBeg : length);
+ mPos += length;
+ PacketCounters::incInBytes(length);
+ DEBUGLOG("readString: " + readString);
+ return readString;
+}
+
+std::string MessageIn::readRawString(int length)
+{
+ // Get string length
+ if (length < 0)
+ length = readInt16();
+
+ // Make sure the string isn't erroneous
+ if (length < 0 || mPos + length > mLength)
+ {
+ mPos = mLength + 1;
+ return "";
+ }
+
+ // Read the string
+ char const *stringBeg = mData + mPos;
+ char const *stringEnd
+ = static_cast<char const *>(memchr(stringBeg, '\0', length));
+ std::string readString(stringBeg,
+ stringEnd ? stringEnd - stringBeg : length);
+
+ mPos += length;
+ PacketCounters::incInBytes(length);
+ DEBUGLOG("readString: " + readString);
+
+ if (stringEnd)
+ {
+ long len2 = length - (stringEnd - stringBeg) - 1;
+ char const *stringBeg2 = stringEnd + 1;
+ char const *stringEnd2
+ = static_cast<char const *>(memchr(stringBeg2, '\0', len2));
+ std::string hiddenPart = std::string(stringBeg2,
+ stringEnd2 ? stringEnd2 - stringBeg2 : len2);
+ if (hiddenPart.length() > 0)
+ {
+ DEBUGLOG("readString2: " + hiddenPart);
+
+ return readString + "|" + hiddenPart;
+ }
+ }
+
+ return readString;
+}
+
+}
diff --git a/src/net/messagein.h b/src/net/messagein.h
new file mode 100644
index 000000000..8781b3050
--- /dev/null
+++ b/src/net/messagein.h
@@ -0,0 +1,118 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MESSAGEIN_H
+#define NET_MESSAGEIN_H
+
+#include <SDL_types.h>
+
+#include <string>
+
+namespace Net
+{
+
+/**
+ * Used for parsing an incoming message.
+ *
+ * \ingroup Network
+ */
+class MessageIn
+{
+ public:
+ /**
+ * Returns the message ID.
+ */
+ int getId() const
+ { return mId; }
+
+ /**
+ * Returns the message length.
+ */
+ unsigned int getLength() const
+ { return mLength; }
+
+ /**
+ * Returns the length of unread data.
+ */
+ unsigned int getUnreadLength() const
+ { return mLength - mPos; }
+
+ virtual unsigned char readInt8(); /**< Reads a byte. */
+ virtual Sint16 readInt16() = 0; /**< Reads a short. */
+ virtual int readInt32() = 0; /**< Reads a long. */
+
+ /**
+ * Reads a 3-byte block containing tile-based coordinates. Used by
+ * manaserv.
+ */
+ virtual void readCoordinates(Uint16 &x, Uint16 &y);
+
+ /**
+ * Reads a special 3 byte block used by eAthena, containing x and y
+ * coordinates and direction.
+ */
+ virtual void readCoordinates(Uint16 &x, Uint16 &y, Uint8 &direction);
+
+ /**
+ * Reads a special 5 byte block used by eAthena, containing a source
+ * and destination coordinate pair.
+ */
+ virtual void readCoordinatePair(Uint16 &srcX, Uint16 &srcY,
+ Uint16 &dstX, Uint16 &dstY);
+
+ /**
+ * Skips a given number of bytes.
+ */
+ virtual void skip(unsigned int length);
+
+ /**
+ * Reads a string. If a length is not given (-1), it is assumed
+ * that the length of the string is stored in a short at the
+ * start of the string.
+ */
+ virtual std::string readString(int length = -1);
+
+ virtual std::string readRawString(int length);
+
+ virtual ~MessageIn()
+ { }
+
+ protected:
+ /**
+ * Constructor.
+ */
+ MessageIn(const char *data, unsigned int length);
+
+ const char *mData; /**< The message data. */
+ unsigned int mLength; /**< The length of the data. */
+ unsigned short mId; /**< The message ID. */
+
+ /**
+ * Actual position in the packet. From 0 to packet->length.
+ * A value bigger than packet->length means EOP was reached when
+ * reading it.
+ */
+ unsigned int mPos;
+};
+
+}
+
+#endif // NET_MESSAGEIN_H
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
new file mode 100644
index 000000000..5152b73e2
--- /dev/null
+++ b/src/net/messageout.cpp
@@ -0,0 +1,92 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/messageout.h"
+
+#include "net/packetcounters.h"
+
+#include "log.h"
+
+#include "utils/stringutils.h"
+
+#include <cstring>
+#include <string>
+
+namespace Net
+{
+
+MessageOut::MessageOut(short id _UNUSED_):
+ mData(0),
+ mDataSize(0),
+ mPos(0)
+{
+ PacketCounters::incOutPackets();
+ DEBUGLOG("MessageOut");
+}
+
+void MessageOut::writeInt8(Sint8 value)
+{
+ DEBUGLOG("writeInt8: " + toString((int)value));
+ expand(1);
+ mData[mPos] = value;
+ mPos += 1;
+ PacketCounters::incOutBytes(1);
+}
+
+void MessageOut::writeString(const std::string &string, int length)
+{
+ DEBUGLOG("writeString: " + string);
+ int stringLength = static_cast<int>(string.length());
+ if (length < 0)
+ {
+ // Write the length at the start if not fixed
+ writeInt16(static_cast<short>(stringLength));
+ length = stringLength;
+ }
+ else if (length < stringLength)
+ {
+ // Make sure the length of the string is no longer than specified
+ stringLength = length;
+ }
+ expand(length);
+
+ // Write the actual string
+ memcpy(mData + mPos, string.c_str(), stringLength);
+
+ // Pad remaining space with zeros
+ if (length > stringLength)
+ memset(mData + mPos + stringLength, '\0', length - stringLength);
+
+ mPos += length;
+ PacketCounters::incOutBytes(length);
+}
+
+char *MessageOut::getData() const
+{
+ return mData;
+}
+
+unsigned int MessageOut::getDataSize() const
+{
+ return mDataSize;
+}
+
+}
diff --git a/src/net/messageout.h b/src/net/messageout.h
new file mode 100644
index 000000000..11a9ff552
--- /dev/null
+++ b/src/net/messageout.h
@@ -0,0 +1,91 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_MESSAGEOUT_H
+#define NET_MESSAGEOUT_H
+
+#include <SDL_types.h>
+
+#include <iosfwd>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace Net
+{
+
+/**
+ * Used for building an outgoing message.
+ *
+ * \ingroup Network
+ */
+class MessageOut
+{
+ public:
+ virtual void writeInt8(Sint8 value); /**< Writes a byte. */
+ virtual void writeInt16(Sint16 value) = 0; /**< Writes a short. */
+ virtual void writeInt32(Sint32 value) = 0; /**< Writes a long. */
+
+ /**
+ * Writes a string. If a fixed length is not given (-1), it is stored
+ * as a short at the start of the string.
+ */
+ virtual void writeString(const std::string &string, int length = -1);
+
+ /**
+ * Returns the content of the message.
+ */
+ virtual char *getData() const;
+
+ /**
+ * Returns the length of the data.
+ */
+ virtual unsigned int getDataSize() const;
+
+ virtual ~MessageOut()
+ { }
+
+ protected:
+ /**
+ * Constructor.
+ */
+ MessageOut(short id);
+
+ /**
+ * Expand the packet data to be able to hold more data.
+ *
+ * NOTE: For performance enhancements this method could allocate extra
+ * memory in advance instead of expanding size every time more data is
+ * added.
+ */
+ virtual void expand(size_t size) = 0;
+
+ char *mData; /**< Data building up. */
+ unsigned int mDataSize; /**< Size of data. */
+ unsigned int mPos; /**< Position in the data. */
+};
+
+}
+
+#endif // NET_MESSAGEOUT_H
diff --git a/src/net/net.cpp b/src/net/net.cpp
new file mode 100644
index 000000000..36e414643
--- /dev/null
+++ b/src/net/net.cpp
@@ -0,0 +1,198 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/net.h"
+
+#include "main.h"
+
+#include "net/adminhandler.h"
+#include "net/beinghandler.h"
+#include "net/buysellhandler.h"
+#include "net/charhandler.h"
+#include "net/chathandler.h"
+#include "net/generalhandler.h"
+#include "net/guildhandler.h"
+#include "net/inventoryhandler.h"
+#include "net/loginhandler.h"
+#include "net/gamehandler.h"
+#include "net/npchandler.h"
+#include "net/partyhandler.h"
+#include "net/playerhandler.h"
+#include "net/specialhandler.h"
+#include "net/tradehandler.h"
+
+#include "net/tmwa/generalhandler.h"
+
+#include "net/manaserv/generalhandler.h"
+
+Net::AdminHandler *adminHandler = NULL;
+Net::CharHandler *charHandler = NULL;
+Net::ChatHandler *chatHandler = NULL;
+Net::GeneralHandler *generalHandler = NULL;
+Net::InventoryHandler *inventoryHandler = NULL;
+Net::LoginHandler *loginHandler = NULL;
+Net::GameHandler *gameHandler = NULL;
+Net::GuildHandler *guildHandler = NULL;
+Net::NpcHandler *npcHandler = NULL;
+Net::PartyHandler *partyHandler = NULL;
+Net::PlayerHandler *playerHandler = NULL;
+Net::SpecialHandler *specialHandler = NULL;
+Net::TradeHandler *tradeHandler = NULL;
+Net::BeingHandler *beingHandler = NULL;
+Net::BuySellHandler *buySellHandler = NULL;
+
+Net::AdminHandler *Net::getAdminHandler()
+{
+ return adminHandler;
+}
+
+Net::CharHandler *Net::getCharHandler()
+{
+ return charHandler;
+}
+
+Net::ChatHandler *Net::getChatHandler()
+{
+ return chatHandler;
+}
+
+Net::GameHandler *Net::getGameHandler()
+{
+ return gameHandler;
+}
+
+Net::GeneralHandler *Net::getGeneralHandler()
+{
+ return generalHandler;
+}
+
+Net::GuildHandler *Net::getGuildHandler()
+{
+ return guildHandler;
+}
+
+Net::InventoryHandler *Net::getInventoryHandler()
+{
+ return inventoryHandler;
+}
+
+Net::LoginHandler *Net::getLoginHandler()
+{
+ return loginHandler;
+}
+
+Net::NpcHandler *Net::getNpcHandler()
+{
+ return npcHandler;
+}
+
+Net::PartyHandler *Net::getPartyHandler()
+{
+ return partyHandler;
+}
+
+Net::PlayerHandler *Net::getPlayerHandler()
+{
+ return playerHandler;
+}
+
+Net::SpecialHandler *Net::getSpecialHandler()
+{
+ return specialHandler;
+}
+
+Net::TradeHandler *Net::getTradeHandler()
+{
+ return tradeHandler;
+}
+
+Net::BeingHandler *Net::getBeingHandler()
+{
+ return beingHandler;
+}
+
+Net::BuySellHandler *Net::getBuySellHandler()
+{
+ return buySellHandler;
+}
+
+namespace Net
+{
+ServerInfo::Type networkType = ServerInfo::UNKNOWN;
+
+void connectToServer(const ServerInfo &server)
+{
+ if (server.type == ServerInfo::UNKNOWN)
+ {
+ // TODO: Query the server about itself and choose the netcode based on
+ // that
+ }
+
+ if (networkType == server.type && getGeneralHandler() != NULL)
+ {
+ getGeneralHandler()->reload();
+ }
+ else
+ {
+ if (networkType != ServerInfo::UNKNOWN && getGeneralHandler() != NULL)
+ getGeneralHandler()->unload();
+
+ switch (server.type)
+ {
+ case ServerInfo::MANASERV:
+ new ManaServ::GeneralHandler;
+ break;
+
+ case ServerInfo::TMWATHENA:
+ new TmwAthena::GeneralHandler;
+ break;
+
+ default:
+ // Shouldn't happen...
+ break;
+ }
+
+ getGeneralHandler()->load();
+
+ networkType = server.type;
+ }
+
+ if (getLoginHandler())
+ {
+ getLoginHandler()->setServer(server);
+ getLoginHandler()->connect();
+ }
+}
+
+void unload()
+{
+ GeneralHandler *handler = getGeneralHandler();
+ if (handler)
+ handler->unload();
+}
+
+ServerInfo::Type getNetworkType()
+{
+ return networkType;
+}
+
+} // namespace Net
+
diff --git a/src/net/net.h b/src/net/net.h
new file mode 100644
index 000000000..95fe04f36
--- /dev/null
+++ b/src/net/net.h
@@ -0,0 +1,81 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_H
+#define NET_H
+
+/**
+ * \namespace Net
+ *
+ * The network communication layer. It is composed of a host of interfaces that
+ * interact with different aspects of the game. They have different
+ * implementations depending on the type of server the client is connecting to.
+ */
+
+#include "net/serverinfo.h"
+
+namespace Net
+{
+
+class AdminHandler;
+class BeingHandler;
+class CharHandler;
+class ChatHandler;
+class GameHandler;
+class GeneralHandler;
+class GuildHandler;
+class InventoryHandler;
+class LoginHandler;
+class NpcHandler;
+class PartyHandler;
+class PlayerHandler;
+class SpecialHandler;
+class TradeHandler;
+class BuySellHandler;
+
+AdminHandler *getAdminHandler();
+BeingHandler *getBeingHandler();
+CharHandler *getCharHandler();
+ChatHandler *getChatHandler();
+GameHandler *getGameHandler();
+GeneralHandler *getGeneralHandler();
+GuildHandler *getGuildHandler();
+InventoryHandler *getInventoryHandler();
+LoginHandler *getLoginHandler();
+NpcHandler *getNpcHandler();
+PartyHandler *getPartyHandler();
+PlayerHandler *getPlayerHandler();
+SpecialHandler *getSpecialHandler();
+TradeHandler *getTradeHandler();
+BuySellHandler *getBuySellHandler();
+
+ServerInfo::Type getNetworkType();
+
+/**
+ * Handles server detection and connection
+ */
+void connectToServer(const ServerInfo &server);
+
+void unload();
+
+} // namespace Net
+
+#endif // NET_H
diff --git a/src/net/npchandler.h b/src/net/npchandler.h
new file mode 100644
index 000000000..1b08a83ec
--- /dev/null
+++ b/src/net/npchandler.h
@@ -0,0 +1,66 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NPCHANDLER_H
+#define NPCHANDLER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+
+class NpcHandler
+{
+ public:
+ virtual ~NpcHandler()
+ { }
+
+ virtual void talk(int npcId) = 0;
+
+ virtual void nextDialog(int npcId) = 0;
+
+ virtual void closeDialog(int npcId) = 0;
+
+ virtual void listInput(int npcId, unsigned char value) = 0;
+
+ virtual void integerInput(int npcId, int value) = 0;
+
+ virtual void stringInput(int npcId, const std::string &value) = 0;
+
+ virtual void sendLetter(int npcId, const std::string &recipient,
+ const std::string &text) = 0;
+
+ virtual void startShopping(int beingId) = 0;
+
+ virtual void buy(int beingId) = 0;
+
+ virtual void sell(int beingId) = 0;
+
+ virtual void buyItem(int beingId, int itemId, int amount) = 0;
+
+ virtual void sellItem(int beingId, int itemId, int amount) = 0;
+
+ virtual void endShopping(int beingId) = 0;
+};
+
+} // namespace Net
+
+#endif // NPCHANDLER_H
diff --git a/src/net/packetcounters.cpp b/src/net/packetcounters.cpp
new file mode 100644
index 000000000..40ab72024
--- /dev/null
+++ b/src/net/packetcounters.cpp
@@ -0,0 +1,128 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/packetcounters.h"
+
+extern volatile int cur_time;
+extern volatile bool runCounters;
+
+int PacketCounters::mInCurrentSec = 0;
+int PacketCounters::mInBytes = 0;
+int PacketCounters::mInBytesCalc = 0;
+int PacketCounters::mInPackets = 0;
+int PacketCounters::mInPacketsCalc = 0;
+int PacketCounters::mOutCurrentSec = 0;
+int PacketCounters::mOutBytes = 0;
+int PacketCounters::mOutBytesCalc = 0;
+int PacketCounters::mOutPackets = 0;
+int PacketCounters::mOutPacketsCalc = 0;
+
+void PacketCounters::incInBytes(int cnt)
+{
+ if (!runCounters)
+ return;
+
+ updateCounter(PacketCounters::mInCurrentSec, PacketCounters::mInBytesCalc,
+ PacketCounters::mInBytes);
+
+ PacketCounters::mInBytes += cnt;
+}
+
+void PacketCounters::incInPackets()
+{
+ if (!runCounters)
+ return;
+
+ updateCounter(PacketCounters::mInCurrentSec,
+ PacketCounters::mInPacketsCalc, PacketCounters::mInPackets);
+
+ PacketCounters::mInPackets ++;
+}
+
+int PacketCounters::getInBytes()
+{
+ return PacketCounters::mInBytesCalc;
+}
+
+int PacketCounters::getInPackets()
+{
+ return PacketCounters::mInPacketsCalc;
+}
+
+void PacketCounters::incOutBytes(int cnt)
+{
+ if (!runCounters)
+ return;
+
+ updateCounter(PacketCounters::mOutCurrentSec,
+ PacketCounters::mOutBytesCalc, PacketCounters::mOutBytes);
+
+ PacketCounters::mOutBytes += cnt;
+}
+
+void PacketCounters::incOutPackets()
+{
+ if (!runCounters)
+ return;
+
+ updateCounter(PacketCounters::mOutCurrentSec,
+ PacketCounters::mOutPacketsCalc,
+ PacketCounters::mOutPackets);
+
+ PacketCounters::mOutPackets ++;
+}
+
+int PacketCounters::getOutBytes()
+{
+ return PacketCounters::mOutBytesCalc;
+}
+
+int PacketCounters::getOutPackets()
+{
+ return PacketCounters::mOutPacketsCalc;
+}
+
+
+void PacketCounters::updateCounter(int &currentSec, int &calc, int &counter)
+{
+ int idx = cur_time % 60;
+ if (currentSec != idx)
+ {
+ currentSec = idx;
+ calc = counter;
+ counter = 0;
+ }
+}
+
+void PacketCounters::update()
+{
+ if (!runCounters)
+ return;
+
+ updateCounter(PacketCounters::mInCurrentSec, PacketCounters::mInBytesCalc,
+ PacketCounters::mInBytes);
+ updateCounter(PacketCounters::mInCurrentSec,
+ PacketCounters::mInPacketsCalc, PacketCounters::mInPackets);
+ updateCounter(PacketCounters::mOutCurrentSec,
+ PacketCounters::mOutBytesCalc, PacketCounters::mOutBytes);
+ updateCounter(PacketCounters::mOutCurrentSec,
+ PacketCounters::mOutPacketsCalc, PacketCounters::mOutPackets);
+}
diff --git a/src/net/packetcounters.h b/src/net/packetcounters.h
new file mode 100644
index 000000000..1e1aa7d83
--- /dev/null
+++ b/src/net/packetcounters.h
@@ -0,0 +1,55 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PACKETCOUNTERS_H
+#define PACKETCOUNTERS_H
+
+class PacketCounters
+{
+public:
+// PacketCounters();
+ static void incInBytes(int cnt);
+ static void incInPackets();
+ static int getInBytes();
+ static int getInPackets();
+ static void incOutBytes(int cnt);
+ static void incOutPackets();
+ static int getOutBytes();
+ static int getOutPackets();
+ static void update();
+
+ static int mInCurrentSec;
+ static int mInBytes;
+ static int mInBytesCalc;
+ static int mInPackets;
+ static int mInPacketsCalc;
+ static int mOutCurrentSec;
+ static int mOutBytes;
+ static int mOutBytesCalc;
+ static int mOutPackets;
+ static int mOutPacketsCalc;
+
+private:
+ static void updateCounter(int &currentSec, int &calc, int &counter);
+
+};
+
+#endif
diff --git a/src/net/partyhandler.h b/src/net/partyhandler.h
new file mode 100644
index 000000000..461334ece
--- /dev/null
+++ b/src/net/partyhandler.h
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PARTYHANDLER_H
+#define PARTYHANDLER_H
+
+#include <string>
+
+class Being;
+
+enum PartyShare
+{
+ PARTY_SHARE_UNKNOWN = -1,
+ PARTY_SHARE_NO,
+ PARTY_SHARE,
+ PARTY_SHARE_NOT_POSSIBLE = 2
+};
+
+namespace Net
+{
+
+class PartyHandler
+{
+ public:
+ virtual ~PartyHandler()
+ { }
+
+ virtual void create(const std::string &name = "") = 0;
+
+ virtual void join(int partyId) = 0;
+
+ virtual void invite(Being *player) = 0;
+
+ virtual void invite(const std::string &name) = 0;
+
+ virtual void inviteResponse(const std::string &inviter,
+ bool accept) = 0;
+
+ virtual void leave() = 0;
+
+ virtual void kick(Being *player) = 0;
+
+ virtual void kick(const std::string &name) = 0;
+
+ virtual void chat(const std::string &text) = 0;
+
+ virtual void requestPartyMembers() = 0;
+
+ virtual PartyShare getShareExperience() = 0;
+
+ virtual void setShareExperience(PartyShare share) = 0;
+
+ virtual PartyShare getShareItems() = 0;
+
+ virtual void setShareItems(PartyShare share) = 0;
+
+ // virtual void options() = 0;
+
+ // virtual void message() = 0;
+};
+
+} // namespace Net
+
+#endif // PARTYHANDLER_H
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
new file mode 100644
index 000000000..8fa84b38f
--- /dev/null
+++ b/src/net/playerhandler.h
@@ -0,0 +1,75 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PLAYERHANDLER_H
+#define PLAYERHANDLER_H
+
+#include "being.h"
+#include "flooritem.h"
+#include "localplayer.h"
+
+namespace Net
+{
+
+class PlayerHandler
+{
+ public:
+ virtual ~PlayerHandler()
+ { }
+
+ virtual void attack(int id, bool keep = false) = 0;
+
+ virtual void stopAttack() = 0;
+
+ virtual void emote(int emoteId) = 0;
+
+ virtual void increaseAttribute(int attr) = 0;
+
+ virtual void decreaseAttribute(int attr) = 0;
+
+ virtual void increaseSkill(int skillId) = 0;
+
+ virtual void pickUp(FloorItem *floorItem) = 0;
+
+ virtual void setDirection(char direction) = 0;
+
+ virtual void setDestination(int x, int y, int direction = -1) = 0;
+
+ virtual void changeAction(Being::Action action) = 0;
+
+ virtual void respawn() = 0;
+
+ virtual void ignorePlayer(const std::string &player, bool ignore) = 0;
+
+ virtual void ignoreAll(bool ignore) = 0;
+
+ virtual bool canUseMagic() = 0;
+
+ virtual bool canCorrectAttributes() = 0;
+
+ virtual int getJobLocation() = 0;
+
+ virtual Vector getDefaultWalkSpeed() = 0;
+};
+
+} // namespace Net
+
+#endif // PLAYERHANDLER_H
diff --git a/src/net/serverinfo.h b/src/net/serverinfo.h
new file mode 100644
index 000000000..113d8a9b2
--- /dev/null
+++ b/src/net/serverinfo.h
@@ -0,0 +1,117 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SERVERINFO_H
+#define SERVERINFO_H
+
+#include "utils/stringutils.h"
+
+#include <string>
+#include <vector>
+
+class ServerInfo
+{
+public:
+ enum Type
+ {
+ UNKNOWN = 0,
+ MANASERV,
+ TMWATHENA
+ };
+
+ typedef std::pair<int, std::string> VersionString;
+
+ Type type;
+ std::string name;
+ std::string hostname;
+ unsigned short port;
+
+ std::string description;
+ VersionString version;
+
+ bool save;
+
+ ServerInfo()
+ {
+ type = TMWATHENA;
+ port = 0;
+ save = false;
+ version.first = 0;
+ }
+
+ ServerInfo(const ServerInfo &info)
+ {
+ type = info.type;
+ name = info.name;
+ hostname = info.hostname;
+ port = info.port;
+ description = info.description;
+ version.first = info.version.first;
+ version.second = info.version.second;
+ save = info.save;
+ }
+
+ bool isValid() const
+ {
+ return !(hostname.empty() || port == 0 || type == UNKNOWN);
+ }
+
+ void clear()
+ {
+ type = UNKNOWN;
+ name.clear();
+ hostname.clear();
+ port = 0;
+ description.clear();
+ version.first = 0;
+ version.second.clear();
+ save = false;
+ }
+
+ bool operator==(const ServerInfo &other) const
+ {
+ return (type == other.type && hostname == other.hostname &&
+ port == other.port);
+ }
+
+ bool operator!=(const ServerInfo &other) const
+ {
+ return (type != other.type || hostname != other.hostname ||
+ port != other.port);
+ }
+
+ static Type parseType(const std::string &type)
+ {
+ if (compareStrI(type, "tmwathena") == 0)
+ return TMWATHENA;
+ // Used for backward compatibility
+ else if (compareStrI(type, "eathena") == 0)
+ return TMWATHENA;
+ else if (compareStrI(type, "manaserv") == 0)
+ return MANASERV;
+
+ return UNKNOWN;
+ }
+};
+
+typedef std::vector<ServerInfo> ServerInfos;
+
+#endif // SERVERINFO_H
diff --git a/src/net/specialhandler.h b/src/net/specialhandler.h
new file mode 100644
index 000000000..cc3a09356
--- /dev/null
+++ b/src/net/specialhandler.h
@@ -0,0 +1,45 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SPECIALHANDLER_H
+#define SPECIALHANDLER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+class SpecialHandler
+{
+ public:
+ virtual ~SpecialHandler ()
+ { }
+
+ virtual void use(int id) = 0;
+
+ virtual void use(int id, int level, int beingId) = 0;
+
+ virtual void use(int id, int level, int x, int y) = 0;
+
+ virtual void use(int id, const std::string &map) = 0;
+};
+}
+
+#endif // SPECIALHANDLER_H
diff --git a/src/net/tmwa/adminhandler.cpp b/src/net/tmwa/adminhandler.cpp
new file mode 100644
index 000000000..114c9a897
--- /dev/null
+++ b/src/net/tmwa/adminhandler.cpp
@@ -0,0 +1,135 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/adminhandler.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "event.h"
+#include "game.h"
+#include "playerrelations.h"
+
+#include "net/chathandler.h"
+#include "net/net.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
+
+extern Net::AdminHandler *adminHandler;
+
+namespace TmwAthena
+{
+
+AdminHandler::AdminHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_ADMIN_KICK_ACK,
+ 0
+ };
+ handledMessages = _messages;
+ adminHandler = this;
+}
+
+void AdminHandler::handleMessage(Net::MessageIn &msg)
+{
+ int id;
+ switch (msg.getId())
+ {
+ case SMSG_ADMIN_KICK_ACK:
+ id = msg.readInt32();
+ if (id == 0)
+ SERVER_NOTICE(_("Kick failed!"))
+ else
+ SERVER_NOTICE(_("Kick succeeded!"))
+ default:
+ break;
+ }
+}
+
+void AdminHandler::announce(const std::string &text)
+{
+ MessageOut outMsg(CMSG_ADMIN_ANNOUNCE);
+ outMsg.writeInt16(static_cast<Sint16>(text.length() + 4));
+ outMsg.writeString(text, static_cast<int>(text.length()));
+}
+
+void AdminHandler::localAnnounce(const std::string &text)
+{
+ MessageOut outMsg(CMSG_ADMIN_LOCAL_ANNOUNCE);
+ outMsg.writeInt16(static_cast<Sint16>(text.length() + 4));
+ outMsg.writeString(text, static_cast<int>(text.length()));
+}
+
+void AdminHandler::hide(bool hide _UNUSED_)
+{
+ MessageOut outMsg(CMSG_ADMIN_HIDE);
+ outMsg.writeInt32(0); //unused
+}
+
+void AdminHandler::kick(int playerId)
+{
+ MessageOut outMsg(CMSG_ADMIN_KICK);
+ outMsg.writeInt32(playerId);
+}
+
+void AdminHandler::kick(const std::string &name)
+{
+ Net::getChatHandler()->talk("@kick " + name);
+}
+
+void AdminHandler::ban(int playerId _UNUSED_)
+{
+ // Not supported
+}
+
+void AdminHandler::ban(const std::string &name)
+{
+ Net::getChatHandler()->talk("@ban " + name);
+}
+
+void AdminHandler::unban(int playerId _UNUSED_)
+{
+ // Not supported
+}
+
+void AdminHandler::unban(const std::string &name)
+{
+ Net::getChatHandler()->talk("@unban " + name);
+}
+
+void AdminHandler::mute(int playerId _UNUSED_, int type _UNUSED_,
+ int limit _UNUSED_)
+{
+ return; // Still looking into this
+/*
+ MessageOut outMsg(CMSG_ADMIN_MUTE);
+ outMsg.writeInt32(playerId);
+ outMsg.writeInt8(type);
+ outMsg.writeInt16(limit);
+*/
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/adminhandler.h b/src/net/tmwa/adminhandler.h
new file mode 100644
index 000000000..a7febf441
--- /dev/null
+++ b/src/net/tmwa/adminhandler.h
@@ -0,0 +1,69 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_ADMINHANDLER_H
+#define NET_TA_ADMINHANDLER_H
+
+#include "net/adminhandler.h"
+#include "net/net.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class AdminHandler : public MessageHandler, public Net::AdminHandler
+{
+ public:
+ AdminHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void announce(const std::string &text);
+
+ void localAnnounce(const std::string &text);
+
+ void hide(bool hide);
+
+ void kick(int playerId);
+
+ void kick(const std::string &name);
+
+ void ban(int playerId);
+
+ void ban(const std::string &name);
+
+ void unban(int playerId);
+
+ void unban(const std::string &name);
+
+ void mute(int playerId, int type, int limit);
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_ADMINHANDLER_H
diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp
new file mode 100644
index 000000000..ea4978a20
--- /dev/null
+++ b/src/net/tmwa/beinghandler.cpp
@@ -0,0 +1,1075 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/beinghandler.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "client.h"
+#include "effectmanager.h"
+#include "guild.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
+#include "log.h"
+#include "party.h"
+#include "playerrelations.h"
+#include "configuration.h"
+
+#include "gui/botcheckerwindow.h"
+#include "gui/outfitwindow.h"
+#include "gui/socialwindow.h"
+#include "gui/killstats.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "net/playerhandler.h"
+#include "net/net.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "resources/colordb.h"
+
+#include <iostream>
+
+extern Net::BeingHandler *beingHandler;
+
+namespace TmwAthena
+{
+
+const int EMOTION_TIME = 500; /**< Duration of emotion icon */
+
+Being *createBeing(int id, short job);
+
+BeingHandler::BeingHandler(bool enableSync):
+ mSync(enableSync)
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_BEING_VISIBLE,
+ SMSG_BEING_MOVE,
+ SMSG_BEING_MOVE2,
+ SMSG_BEING_REMOVE,
+ SMSG_SKILL_DAMAGE,
+ SMSG_BEING_ACTION,
+ SMSG_BEING_SELFEFFECT,
+ SMSG_BEING_EMOTION,
+ SMSG_BEING_CHANGE_LOOKS,
+ SMSG_BEING_CHANGE_LOOKS2,
+ SMSG_BEING_NAME_RESPONSE,
+ SMSG_PLAYER_GUILD_PARTY_INFO,
+ SMSG_BEING_CHANGE_DIRECTION,
+ SMSG_PLAYER_UPDATE_1,
+ SMSG_PLAYER_UPDATE_2,
+ SMSG_PLAYER_MOVE,
+ SMSG_PLAYER_STOP,
+ SMSG_PLAYER_MOVE_TO_ATTACK,
+ SMSG_PLAYER_STATUS_CHANGE,
+ SMSG_BEING_STATUS_CHANGE,
+ SMSG_BEING_RESURRECT,
+ SMSG_SOLVE_CHAR_NAME,
+ SMSG_BEING_SPAWN,
+ SMSG_SKILL_CASTING,
+ SMSG_SKILL_CAST_CANCEL,
+ SMSG_SKILL_NO_DAMAGE,
+ SMSG_BEING_IP_RESPONSE,
+ SMSG_PVP_MAP_MODE,
+ SMSG_PVP_SET,
+ 0
+ };
+ handledMessages = _messages;
+ beingHandler = this;
+}
+
+Being *createBeing(int id, short job)
+{
+ if (!actorSpriteManager)
+ return 0;
+
+ ActorSprite::Type type = ActorSprite::UNKNOWN;
+ if (job <= 25 || (job >= 4001 && job <= 4049))
+ type = ActorSprite::PLAYER;
+ else if (job >= 46 && job <= 1000)
+ type = ActorSprite::NPC;
+ else if (job > 1000 && job <= 2000)
+ type = ActorSprite::MONSTER;
+ else if (job == 45)
+ type = ActorSprite::PORTAL;
+
+ Being *being = actorSpriteManager->createBeing(id, type, job);
+
+ if (type == ActorSprite::PLAYER || type == ActorSprite::NPC)
+ {
+ if (!being->updateFromCache())
+ {
+ MessageOut outMsg(0x0094);
+ outMsg.writeInt32(id); //readLong(2));
+ }
+ else
+ {
+ if (player_node)
+ player_node->checkNewName(being);
+ }
+ }
+ if (type == Being::PLAYER)
+ {
+ if (botCheckerWindow)
+ botCheckerWindow->updateList();
+ if (socialWindow)
+ socialWindow->updateActiveList();
+ }
+ return being;
+}
+
+void BeingHandler::requestNameById(int id)
+{
+ MessageOut outMsg(0x0094);
+ outMsg.writeInt32(id); //readLong(2));
+}
+
+void BeingHandler::handleMessage(Net::MessageIn &msg)
+{
+ if (!actorSpriteManager)
+ return;
+
+ int id;
+ short job, speed, gender;
+ Uint16 headTop, headMid, headBottom;
+ Uint16 shoes, gloves;
+ Uint16 weapon, shield;
+ Uint16 gmstatus;
+ int param1;
+ Uint16 stunMode;
+ int level;
+ Uint32 statusEffects;
+ int type, guild;
+ Uint16 status;
+ Being *srcBeing, *dstBeing;
+ int hairStyle, hairColor, flag;
+ int hp, maxHP, oldHP;
+
+ switch (msg.getId())
+ {
+ case SMSG_BEING_VISIBLE:
+ case SMSG_BEING_MOVE:
+ // Information about a being in range
+ id = msg.readInt32();
+ speed = msg.readInt16();
+ stunMode = msg.readInt16(); // opt1
+ statusEffects = msg.readInt16(); // opt2
+ statusEffects |= ((Uint32)msg.readInt16()) << 16; // option
+ job = msg.readInt16(); // class
+
+ dstBeing = actorSpriteManager->findBeing(id);
+
+ if (dstBeing && dstBeing->getType() == Being::MONSTER
+ && !dstBeing->isAlive())
+ {
+ actorSpriteManager->destroy(dstBeing);
+ actorSpriteManager->erase(dstBeing);
+ dstBeing = 0;
+ }
+
+ if (!dstBeing)
+ {
+ // Being with id >= 110000000 and job 0 are better
+ // known as ghosts, so don't create those.
+ if (job == 0 && id >= 110000000)
+ break;
+
+ if (actorSpriteManager->isBlocked(id) == true)
+ break;
+
+ dstBeing = createBeing(id, job);
+
+ if (!dstBeing)
+ break;
+
+ if (job == 1022 && killStats)
+ killStats->jackoAlive(dstBeing->getId());
+ }
+ else
+ {
+ // undeleting marked for deletion being
+ if (dstBeing->getType() == Being::NPC)
+ {
+ actorSpriteManager->undelete(dstBeing);
+ }
+ }
+
+ if (dstBeing->getType() == Being::PLAYER)
+ dstBeing->setMoveTime();
+
+ if (msg.getId() == SMSG_BEING_VISIBLE)
+ {
+ dstBeing->clearPath();
+ dstBeing->setActionTime(tick_time);
+ dstBeing->setAction(Being::STAND);
+ }
+
+
+ // Prevent division by 0 when calculating frame
+ if (speed == 0)
+ speed = 150;
+
+ dstBeing->setWalkSpeed(Vector(speed, speed, 0));
+ dstBeing->setSubtype(job);
+ if (dstBeing->getType() == ActorSprite::MONSTER && player_node)
+ player_node->checkNewName(dstBeing);
+
+ hairStyle = msg.readInt16();
+ weapon = msg.readInt16();
+ headBottom = msg.readInt16();
+
+ if (msg.getId() == SMSG_BEING_MOVE)
+ msg.readInt32(); // server tick
+
+ shield = msg.readInt16();
+ headTop = msg.readInt16();
+ headMid = msg.readInt16();
+ hairColor = msg.readInt16();
+ shoes = msg.readInt16(); // clothes color - "abused" as shoes
+
+ if (dstBeing->getType() == ActorSprite::MONSTER)
+ {
+ hp = msg.readInt32();
+ maxHP = msg.readInt32();
+ if (hp && maxHP)
+ {
+ oldHP = dstBeing->getHP();
+ if (!oldHP || oldHP > hp)
+ dstBeing->setHP(hp);
+ dstBeing->setMaxHP(maxHP);
+ }
+ gloves = 0;
+ guild = 0;
+ }
+ else
+ {
+ gloves = msg.readInt16(); // head dir - "abused" as gloves
+ guild = msg.readInt32(); // guild
+ msg.readInt16(); // guild emblem
+ }
+// logger->log("being guild: " + toString(guild));
+/*
+ if (guild == 0)
+ dstBeing->clearGuilds();
+ else
+ dstBeing->setGuild(Guild::getGuild(static_cast<short>(guild)));
+*/
+
+ msg.readInt16(); // manner
+ dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
+ msg.readInt8(); // karma
+ gender = msg.readInt8();
+
+ if (dstBeing->getType() == ActorSprite::PLAYER)
+ {
+ dstBeing->setGender((gender == 0)
+ ? GENDER_FEMALE : GENDER_MALE);
+ // Set these after the gender, as the sprites may be gender-specific
+ dstBeing->setSprite(SPRITE_HAIR, hairStyle * -1,
+ ColorDB::get(hairColor));
+ dstBeing->setSprite(SPRITE_BOTTOMCLOTHES, headBottom);
+ dstBeing->setSprite(SPRITE_TOPCLOTHES, headMid);
+ dstBeing->setSprite(SPRITE_HAT, headTop);
+ dstBeing->setSprite(SPRITE_SHOE, shoes);
+ dstBeing->setSprite(SPRITE_GLOVES, gloves);
+ dstBeing->setSprite(SPRITE_WEAPON, weapon, "", true);
+ if (!config.getBoolValue("hideShield"))
+ dstBeing->setSprite(SPRITE_SHIELD, shield);
+ }
+
+ if (msg.getId() == SMSG_BEING_MOVE)
+ {
+ Uint16 srcX, srcY, dstX, dstY;
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
+ dstBeing->setAction(Being::STAND);
+ dstBeing->setTileCoords(srcX, srcY);
+ dstBeing->setDestination(dstX, dstY);
+
+// if (player_node && player_node->getTarget() == dstBeing)
+// player_node->targetMoved();
+ }
+ else
+ {
+ Uint8 dir;
+ Uint16 x, y;
+ msg.readCoordinates(x, y, dir);
+ dstBeing->setTileCoords(x, y);
+
+ if (job == 45 && socialWindow && outfitWindow)
+ {
+ int num = socialWindow->getPortalIndex(x, y);
+ if (num >= 0)
+ {
+ dstBeing->setName(keyboard.getKeyShortString(
+ outfitWindow->keyName(num)));
+ }
+ else
+ {
+ dstBeing->setName("");
+ }
+ }
+
+ dstBeing->setDirection(getDirection(dir));
+ }
+
+ msg.readInt8(); // unknown
+ msg.readInt8(); // unknown
+// msg.readInt8(); // unknown / sit
+ msg.readInt16();
+
+ dstBeing->setStunMode(stunMode);
+ dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
+ dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
+ break;
+
+ case SMSG_BEING_MOVE2:
+ /*
+ * A simplified movement packet, used by the
+ * later versions of eAthena for both mobs and
+ * players
+ */
+ dstBeing = actorSpriteManager->findBeing(msg.readInt32());
+
+ /*
+ * This packet doesn't have enough info to actually
+ * create a new being, so if the being isn't found,
+ * we'll just pretend the packet didn't happen
+ */
+
+ if (!dstBeing)
+ break;
+
+ Uint16 srcX, srcY, dstX, dstY;
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
+ msg.readInt32(); // Server tick
+
+ dstBeing->setAction(Being::STAND);
+ dstBeing->setTileCoords(srcX, srcY);
+ dstBeing->setDestination(dstX, dstY);
+ if (dstBeing->getType() == Being::PLAYER)
+ dstBeing->setMoveTime();
+
+// if (player_node && player_node->getTarget() == dstBeing)
+// {
+// logger->log("SMSG_BEING_MOVE2");
+// player_node->targetMoved();
+// }
+
+ break;
+
+ case SMSG_BEING_SPAWN:
+ // skipping this packet
+ msg.readInt32(); // id
+ msg.readInt16(); // speed
+ msg.readInt16(); // opt1
+ msg.readInt16(); // opt2
+ msg.readInt16(); // option
+ msg.readInt16(); // disguise
+ break;
+
+ case SMSG_BEING_REMOVE:
+ // A being should be removed or has died
+
+ id = msg.readInt32();
+ dstBeing = actorSpriteManager->findBeing(id);
+ if (!dstBeing)
+ break;
+
+ player_node->followMoveTo(dstBeing, player_node->getNextDestX(),
+ player_node->getNextDestY());
+
+ // If this is player's current target, clear it.
+ if (dstBeing == player_node->getTarget())
+ player_node->stopAttack();
+
+ if (msg.readInt8() == 1)
+ {
+ dstBeing->setAction(Being::DEAD);
+ if (dstBeing->getName() == "Jack O" && killStats)
+ killStats->jackoDead(id);
+ }
+ else
+ {
+ if (dstBeing->getType() == Being::PLAYER)
+ {
+ if (botCheckerWindow)
+ botCheckerWindow->updateList();
+ if (socialWindow)
+ socialWindow->updateActiveList();
+ }
+ actorSpriteManager->destroy(dstBeing);
+ }
+ break;
+
+ case SMSG_BEING_RESURRECT:
+ // A being changed mortality status
+
+ id = msg.readInt32();
+ dstBeing = actorSpriteManager->findBeing(id);
+ if (!dstBeing)
+ break;
+
+ // If this is player's current target, clear it.
+ if (dstBeing == player_node->getTarget())
+ player_node->stopAttack();
+
+ if (msg.readInt8() == 1)
+ dstBeing->setAction(Being::STAND);
+
+ break;
+
+ case SMSG_SKILL_DAMAGE:
+ msg.readInt16(); // Skill Id
+ srcBeing = actorSpriteManager->findBeing(msg.readInt32());
+ dstBeing = actorSpriteManager->findBeing(msg.readInt32());
+ msg.readInt32(); // Server tick
+ msg.readInt32(); // src speed
+ msg.readInt32(); // dst speed
+ param1 = msg.readInt32(); // Damage
+ msg.readInt16(); // Skill level
+ msg.readInt16(); // Div
+ msg.readInt8(); // Skill hit/type (?)
+ if (dstBeing)
+ {
+ // Perhaps a new skill attack type should be created and used?
+ dstBeing->takeDamage(srcBeing, param1, Being::HIT);
+ }
+ if (srcBeing)
+ srcBeing->handleAttack(dstBeing, param1, Being::HIT);
+ break;
+
+ case SMSG_BEING_ACTION:
+ srcBeing = actorSpriteManager->findBeing(msg.readInt32());
+ dstBeing = actorSpriteManager->findBeing(msg.readInt32());
+
+ msg.readInt32(); // server tick
+ msg.readInt32(); // src speed
+ msg.readInt32(); // dst speed
+ param1 = msg.readInt16();
+ msg.readInt16(); // param 2
+ type = msg.readInt8();
+ msg.readInt16(); // param 3
+
+ switch (type)
+ {
+ case Being::HIT: // Damage
+ case Being::CRITICAL: // Critical Damage
+ case Being::MULTI: // Critical Damage
+ case Being::REFLECT: // Reflected Damage
+ case Being::FLEE: // Lucky Dodge
+ if (dstBeing)
+ {
+ dstBeing->takeDamage(srcBeing, param1,
+ (Being::AttackType)type);
+ }
+ if (srcBeing)
+ {
+ srcBeing->handleAttack(dstBeing, param1,
+ (Being::AttackType)type);
+ if (srcBeing->getType() == Being::PLAYER)
+ srcBeing->setAttackTime();
+ }
+ break;
+
+ case 0x02: // Sit
+ if (srcBeing)
+ {
+ srcBeing->setAction(Being::SIT);
+ if (srcBeing->getType() == Being::PLAYER)
+ {
+ srcBeing->setMoveTime();
+ if (player_node)
+ {
+ player_node->imitateAction(
+ srcBeing, Being::SIT);
+ }
+ }
+ }
+ break;
+
+ case 0x03: // Stand up
+ if (srcBeing)
+ {
+ srcBeing->setAction(Being::STAND);
+ if (srcBeing->getType() == Being::PLAYER)
+ {
+ srcBeing->setMoveTime();
+ if (player_node)
+ {
+ player_node->imitateAction(
+ srcBeing, Being::STAND);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+/*
+ logger->log("QQQ1 SMSG_BEING_ACTION:");
+ if (srcBeing)
+ logger->log("srcBeing:" + toString(srcBeing->getId()));
+ if (dstBeing)
+ logger->log("dstBeing:" + toString(dstBeing->getId()));
+ logger->log("type: " + toString(type));
+*/
+ }
+ break;
+
+ case SMSG_BEING_SELFEFFECT:
+ {
+ if (!effectManager)
+ return;
+
+ id = (Uint32)msg.readInt32();
+ Being* being = actorSpriteManager->findBeing(id);
+ if (!being)
+ break;
+
+ int effectType = msg.readInt32();
+
+ effectManager->trigger(effectType, being);
+
+ if (being && effectType == 3
+ && being->getType() == Being::PLAYER
+ && socialWindow)
+ { //reset received damage
+ socialWindow->resetDamage(being->getName());
+ }
+
+ break;
+ }
+
+ case SMSG_BEING_EMOTION:
+ if (!player_node)
+ break;
+
+ if (!(dstBeing = actorSpriteManager->findBeing(msg.readInt32())))
+ break;
+
+ if (player_relations.hasPermission(dstBeing,
+ PlayerRelation::EMOTE))
+ {
+ unsigned char emote = msg.readInt8();
+ if (emote)
+ {
+ dstBeing->setEmote(emote, EMOTION_TIME);
+ player_node->imitateEmote(dstBeing, emote);
+ }
+ }
+ if (dstBeing->getType() == Being::PLAYER)
+ dstBeing->setOtherTime();
+
+ break;
+
+ case SMSG_BEING_CHANGE_LOOKS:
+ case SMSG_BEING_CHANGE_LOOKS2:
+ {
+ /*
+ * SMSG_BEING_CHANGE_LOOKS (0x00c3) and
+ * SMSG_BEING_CHANGE_LOOKS2 (0x01d7) do basically the same
+ * thing. The difference is that ...LOOKS carries a single
+ * 8 bit value, where ...LOOKS2 carries two 16 bit values.
+ *
+ * If type = 2, then the first 16 bit value is the weapon ID,
+ * and the second 16 bit value is the shield ID. If no
+ * shield is equipped, or type is not 2, then the second
+ * 16 bit value will be 0.
+ */
+
+ if (!(dstBeing = actorSpriteManager->findBeing(msg.readInt32())))
+ break;
+
+ int type = msg.readInt8();
+ int id = 0;
+ int id2 = 0;
+
+ if (msg.getId() == SMSG_BEING_CHANGE_LOOKS)
+ {
+ id = msg.readInt8();
+ }
+ else
+ { // SMSG_BEING_CHANGE_LOOKS2
+ id = msg.readInt16();
+ id2 = msg.readInt16();
+ }
+
+ if (dstBeing->getType() == Being::PLAYER)
+ dstBeing->setOtherTime();
+
+ if (!player_node)
+ break;
+
+ switch (type)
+ {
+ case 0: // change race
+ dstBeing->setSubtype(id);
+ break;
+ case 1: // eAthena LOOK_HAIR
+ dstBeing->setSpriteID(SPRITE_HAIR, id *-1);
+ break;
+ case 2: // Weapon ID in id, Shield ID in id2
+ dstBeing->setSprite(SPRITE_WEAPON, id, "", true);
+ if (!config.getBoolValue("hideShield"))
+ dstBeing->setSprite(SPRITE_SHIELD, id2);
+ player_node->imitateOutfit(dstBeing, SPRITE_SHIELD);
+ break;
+ case 3: // Change lower headgear for eAthena, pants for us
+ dstBeing->setSprite(SPRITE_BOTTOMCLOTHES, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_BOTTOMCLOTHES);
+ break;
+ case 4: // Change upper headgear for eAthena, hat for us
+ dstBeing->setSprite(SPRITE_HAT, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_HAT);
+ break;
+ case 5: // Change middle headgear for eathena, armor for us
+ dstBeing->setSprite(SPRITE_TOPCLOTHES, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_TOPCLOTHES);
+ break;
+ case 6: // eAthena LOOK_HAIR_COLOR
+ dstBeing->setSpriteColor(SPRITE_HAIR, ColorDB::get(id));
+ break;
+ case 8: // eAthena LOOK_SHIELD
+ if (!config.getBoolValue("hideShield"))
+ dstBeing->setSprite(SPRITE_SHIELD, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_SHIELD);
+ break;
+ case 9: // eAthena LOOK_SHOES
+ dstBeing->setSprite(SPRITE_SHOE, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_SHOE);
+ break;
+ case 10: // LOOK_GLOVES
+ dstBeing->setSprite(SPRITE_GLOVES, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_GLOVES);
+ break;
+ case 11: // LOOK_CAPE
+ dstBeing->setSprite(SPRITE_CAPE, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_CAPE);
+ break;
+ case 12:
+ dstBeing->setSprite(SPRITE_MISC1, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_MISC1);
+ break;
+ case 13:
+ dstBeing->setSprite(SPRITE_MISC2, id);
+ player_node->imitateOutfit(dstBeing, SPRITE_MISC2);
+ break;
+ default:
+ logger->log("QQQ3 CHANGE_LOOKS: unsupported type: "
+ "%d, id: %d", type, id);
+ if (dstBeing)
+ {
+ logger->log("ID: " + toString(dstBeing->getId()));
+ logger->log("name: " + toString(dstBeing->getName()));
+ }
+ break;
+ }
+ }
+ break;
+
+ case SMSG_BEING_NAME_RESPONSE:
+ {
+ int beingId = msg.readInt32();
+ if ((dstBeing = actorSpriteManager->findBeing(beingId)))
+ {
+ if (beingId == player_node->getId())
+ {
+ player_node->pingResponse();
+ }
+ else
+ {
+ dstBeing->setName(msg.readString(24));
+ dstBeing->updateGuild();
+ dstBeing->addToCache();
+
+ if (dstBeing->getType() == Being::PLAYER)
+ dstBeing->updateColors();
+
+ if (player_node)
+ {
+ Party *party = player_node->getParty();
+ if (party && party->isMember(dstBeing->getId()))
+ {
+ PartyMember *member = party->getMember(
+ dstBeing->getId());
+
+ if (member)
+ member->setName(dstBeing->getName());
+ }
+ player_node->checkNewName(dstBeing);
+ }
+ }
+ }
+ }
+ break;
+ case SMSG_BEING_IP_RESPONSE:
+ {
+ if ((dstBeing = actorSpriteManager->findBeing(
+ msg.readInt32())))
+ {
+ dstBeing->setIp(ipToString(msg.readInt32()));
+ }
+ }
+ break;
+ case SMSG_SOLVE_CHAR_NAME:
+ {
+ logger->log1("SMSG_SOLVE_CHAR_NAME");
+ logger->log(toString(msg.readInt32()));
+ logger->log(msg.readString(24));
+ }
+ break;
+ case SMSG_PLAYER_GUILD_PARTY_INFO:
+ if ((dstBeing = actorSpriteManager->findBeing(msg.readInt32())))
+ {
+ dstBeing->setPartyName(msg.readString(24));
+ dstBeing->setGuildName(msg.readString(24));
+ dstBeing->setGuildPos(msg.readString(24));
+ dstBeing->addToCache();
+ msg.readString(24); // Discard this
+ }
+ break;
+ case SMSG_BEING_CHANGE_DIRECTION:
+ {
+ if (!(dstBeing = actorSpriteManager->findBeing(msg.readInt32())))
+ break;
+
+ msg.readInt16(); // unused
+
+ unsigned char dir = getDirection(msg.readInt8());
+ dstBeing->setDirection(dir);
+ if (player_node)
+ player_node->imitateDirection(dstBeing, dir);
+ break;
+ }
+ case SMSG_PLAYER_UPDATE_1:
+ case SMSG_PLAYER_UPDATE_2:
+ case SMSG_PLAYER_MOVE:
+ if (!actorSpriteManager || !player_node)
+ break;
+
+ // An update about a player, potentially including movement.
+ id = msg.readInt32();
+ speed = msg.readInt16();
+ stunMode = msg.readInt16(); // opt1; Aethyra use this as cape
+ statusEffects = msg.readInt16(); // opt2; Aethyra use this as misc1
+ statusEffects |= ((Uint32) msg.readInt16())
+ << 16; // status.options; Aethyra uses this as misc2
+ job = msg.readInt16();
+
+ dstBeing = actorSpriteManager->findBeing(id);
+
+ if (!dstBeing)
+ {
+ if (actorSpriteManager->isBlocked(id) == true)
+ break;
+
+ dstBeing = createBeing(id, job);
+
+ if (!dstBeing)
+ break;
+ }
+
+ if (Party *party = player_node->getParty())
+ {
+ if (party->isMember(id))
+ dstBeing->setParty(party);
+ }
+
+ dstBeing->setWalkSpeed(Vector(speed, speed, 0));
+ dstBeing->setSubtype(job);
+ hairStyle = msg.readInt16();
+ weapon = msg.readInt16();
+ shield = msg.readInt16();
+ headBottom = msg.readInt16();
+
+ if (msg.getId() == SMSG_PLAYER_MOVE)
+ msg.readInt32(); // server tick
+
+ headTop = msg.readInt16();
+ headMid = msg.readInt16();
+ hairColor = msg.readInt16();
+ shoes = msg.readInt16();
+ gloves = msg.readInt16(); //sd->head_dir
+ guild = msg.readInt32(); // guild
+
+ if (guild == 0)
+ dstBeing->clearGuilds();
+ else
+ dstBeing->setGuild(Guild::getGuild(static_cast<short>(guild)));
+
+ msg.readInt16(); // emblem
+ msg.readInt16(); // manner
+ dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
+ msg.readInt8(); // karma
+ dstBeing->setGender((msg.readInt8() == 0)
+ ? GENDER_FEMALE : GENDER_MALE);
+
+ // Set these after the gender, as the sprites may be gender-specific
+ dstBeing->setSprite(SPRITE_WEAPON, weapon, "", true);
+ if (!config.getBoolValue("hideShield"))
+ dstBeing->setSprite(SPRITE_SHIELD, shield);
+ //dstBeing->setSprite(SPRITE_SHOE, shoes);
+ dstBeing->setSprite(SPRITE_BOTTOMCLOTHES, headBottom);
+ dstBeing->setSprite(SPRITE_TOPCLOTHES, headMid);
+ dstBeing->setSprite(SPRITE_HAT, headTop);
+ //dstBeing->setSprite(SPRITE_GLOVES, gloves);
+ //dstBeing->setSprite(SPRITE_CAPE, cape);
+ //dstBeing->setSprite(SPRITE_MISC1, misc1);
+ //dstBeing->setSprite(SPRITE_MISC2, misc2);
+ dstBeing->setSprite(SPRITE_HAIR, hairStyle * -1,
+ ColorDB::get(hairColor));
+
+ player_node->imitateOutfit(dstBeing);
+
+ if (msg.getId() == SMSG_PLAYER_MOVE)
+ {
+ Uint16 srcX, srcY, dstX, dstY;
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
+
+ player_node->followMoveTo(dstBeing, srcX, srcY, dstX, dstY);
+
+ dstBeing->setTileCoords(srcX, srcY);
+ dstBeing->setDestination(dstX, dstY);
+
+ if (player_node->getCurrentAction() != Being::STAND)
+ player_node->imitateAction(dstBeing, Being::STAND);
+ if (player_node->getDirection() != dstBeing->getDirection())
+ {
+ player_node->imitateDirection(dstBeing,
+ dstBeing->getDirection());
+ }
+ }
+ else
+ {
+ Uint8 dir;
+ Uint16 x, y;
+ msg.readCoordinates(x, y, dir);
+ dstBeing->setTileCoords(x, y);
+ dir = getDirection(dir);
+ dstBeing->setDirection(dir);
+
+ player_node->imitateDirection(dstBeing, dir);
+ }
+
+ gmstatus = msg.readInt16();
+
+ if (gmstatus & 0x80)
+ dstBeing->setGM(true);
+
+ if (msg.getId() == SMSG_PLAYER_UPDATE_1)
+ {
+ int type = msg.readInt8();
+ switch (type)
+ {
+ case 0:
+ dstBeing->setAction(Being::STAND);
+ player_node->imitateAction(dstBeing, Being::STAND);
+ break;
+
+ case 1:
+ dstBeing->setAction(Being::DEAD);
+ break;
+
+ case 2:
+ dstBeing->setAction(Being::SIT);
+ player_node->imitateAction(dstBeing, Being::SIT);
+ break;
+
+ default:
+ //need set stay state?
+ logger->log("QQQ2 SMSG_PLAYER_UPDATE_1:"
+ + toString(id) + " " + toString(type));
+ if (dstBeing)
+ {
+ logger->log("dstBeing id:"
+ + toString(dstBeing->getId()));
+ logger->log("dstBeing name:"
+ + dstBeing->getName());
+ }
+ break;
+
+ }
+ }
+ else if (msg.getId() == SMSG_PLAYER_MOVE)
+ {
+ msg.readInt8(); // unknown
+ }
+
+ level = msg.readInt8(); // Lv
+ if (level)
+ dstBeing->setLevel(level);
+
+ msg.readInt8(); // unknown
+
+ dstBeing->setActionTime(tick_time);
+ dstBeing->reset();
+
+ dstBeing->setStunMode(stunMode);
+ dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
+ dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
+
+ if (msg.getId() == SMSG_PLAYER_MOVE
+ && dstBeing->getType() == Being::PLAYER)
+ {
+ dstBeing->setMoveTime();
+ }
+
+ break;
+ case SMSG_PLAYER_STOP:
+ /*
+ * Instruction from server to stop walking at x, y.
+ *
+ * Some people like having this enabled. Others absolutely
+ * despise it. So I'm setting to so that it only affects the
+ * local player if the person has set a key "EnableSync" to "1"
+ * in their config.xml file.
+ *
+ * This packet will be honored for all other beings, regardless
+ * of the config setting.
+ */
+
+ id = msg.readInt32();
+
+ if (mSync || id != player_node->getId())
+ {
+ dstBeing = actorSpriteManager->findBeing(id);
+ if (dstBeing)
+ {
+ Uint16 x, y;
+ x = msg.readInt16();
+ y = msg.readInt16();
+ dstBeing->setTileCoords(x, y);
+ if (dstBeing->getCurrentAction() == Being::MOVE)
+ dstBeing->setAction(Being::STAND);
+ }
+ }
+ break;
+
+ case SMSG_PLAYER_MOVE_TO_ATTACK:
+ /*
+ * This is an *advisory* message, telling the client that
+ * it needs to move the character before attacking
+ * a target (out of range, obstruction in line of fire).
+ * We can safely ignore this...
+ */
+ if (player_node)
+ player_node->fixAttackTarget();
+ break;
+
+ case SMSG_PLAYER_STATUS_CHANGE:
+ // Change in players' flags
+
+ id = msg.readInt32();
+ dstBeing = actorSpriteManager->findBeing(id);
+ if (!dstBeing)
+ break;
+
+ stunMode = msg.readInt16();
+ statusEffects = msg.readInt16();
+ statusEffects |= ((Uint32) msg.readInt16()) << 16;
+ msg.readInt8(); // Unused?
+
+ dstBeing->setStunMode(stunMode);
+ dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
+ dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
+ break;
+
+ case SMSG_BEING_STATUS_CHANGE:
+ // Status change
+ status = msg.readInt16();
+ id = msg.readInt32();
+ flag = msg.readInt8(); // 0: stop, 1: start
+
+ dstBeing = actorSpriteManager->findBeing(id);
+ if (dstBeing)
+ dstBeing->setStatusEffect(status, flag);
+ break;
+
+ case SMSG_SKILL_CASTING:
+ msg.readInt32(); // src id
+ msg.readInt32(); // dst id
+ msg.readInt16(); // dst x
+ msg.readInt16(); // dst y
+ msg.readInt16(); // skill num
+ msg.readInt32(); // skill get pl
+ msg.readInt32(); // cast time
+ break;
+
+ case SMSG_SKILL_CAST_CANCEL:
+ msg.readInt32(); // id
+ break;
+
+ case SMSG_SKILL_NO_DAMAGE:
+ msg.readInt16(); // skill id
+ msg.readInt16(); // heal
+ msg.readInt32(); // dst id
+ msg.readInt32(); // src id
+ msg.readInt8(); // fail
+ break;
+
+ case SMSG_PVP_MAP_MODE:
+ {
+ Game *game = Game::instance();
+ if (!game)
+ break;
+
+ Map *map = game->getCurrentMap();
+ if (map)
+ map->setPvpMode(msg.readInt16());
+ break;
+ }
+
+ case SMSG_PVP_SET:
+ {
+ int id = msg.readInt32(); // id
+ int rank = msg.readInt32(); // rank
+ msg.readInt32(); // num
+ dstBeing = actorSpriteManager->findBeing(id);
+ if (dstBeing)
+ dstBeing->setPvpRank(rank);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+Uint8 BeingHandler::getDirection(Uint8 dir)
+{
+ if (dir == 0)
+ dir = 8;
+ return dir;
+}
+
+void BeingHandler::undress(Being *being)
+{
+ being->setSprite(SPRITE_BOTTOMCLOTHES, 0);
+ being->setSprite(SPRITE_TOPCLOTHES, 0);
+ being->setSprite(SPRITE_HAT, 0);
+ being->setSprite(SPRITE_SHOE, 0);
+ being->setSprite(SPRITE_GLOVES, 0);
+// being->setSprite(SPRITE_WEAPON, 0, "", true);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/beinghandler.h b/src/net/tmwa/beinghandler.h
new file mode 100644
index 000000000..f16b35178
--- /dev/null
+++ b/src/net/tmwa/beinghandler.h
@@ -0,0 +1,53 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_BEINGHANDLER_H
+#define NET_TA_BEINGHANDLER_H
+
+#include "net/beinghandler.h"
+#include "net/net.h"
+
+#include "net/tmwa/messagehandler.h"
+
+namespace TmwAthena
+{
+
+class BeingHandler : public MessageHandler, public Net::BeingHandler
+{
+ public:
+ BeingHandler(bool enableSync);
+
+ virtual void handleMessage(Net::MessageIn &msg);
+
+ virtual void requestNameById(int id);
+
+ virtual void undress(Being *being);
+
+ Uint8 getDirection(Uint8 dir);
+
+ private:
+ // Should we honor server "Stop Walking" packets
+ bool mSync;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_BEINGHANDLER_H
diff --git a/src/net/tmwa/buysellhandler.cpp b/src/net/tmwa/buysellhandler.cpp
new file mode 100644
index 000000000..bdc372238
--- /dev/null
+++ b/src/net/tmwa/buysellhandler.cpp
@@ -0,0 +1,231 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/buysellhandler.h"
+
+#include "actorspritemanager.h"
+#include "configuration.h"
+#include "event.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+#include "shopitem.h"
+
+#include "gui/buy.h"
+#include "gui/buysell.h"
+#include "gui/sell.h"
+#include "gui/shopwindow.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "net/chathandler.h"
+#include "net/messagein.h"
+#include "net/net.h"
+
+#include "net/tmwa/chathandler.h"
+#include "net/tmwa/protocol.h"
+
+#include "utils/gettext.h"
+
+extern Net::BuySellHandler *buySellHandler;
+
+namespace TmwAthena
+{
+
+BuySellHandler::BuySellHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_NPC_BUY_SELL_CHOICE,
+ SMSG_NPC_BUY,
+ SMSG_NPC_SELL,
+ SMSG_NPC_BUY_RESPONSE,
+ SMSG_NPC_SELL_RESPONSE,
+ 0
+ };
+ mNpcId = 0;
+ handledMessages = _messages;
+ buySellHandler = this;
+}
+
+void BuySellHandler::handleMessage(Net::MessageIn &msg)
+{
+ int n_items;
+
+ switch (msg.getId())
+ {
+ case SMSG_NPC_BUY_SELL_CHOICE:
+ if (!BuySellDialog::isActive())
+ {
+ mNpcId = msg.readInt32();
+ new BuySellDialog(mNpcId);
+ }
+ break;
+
+ case SMSG_NPC_BUY:
+ msg.readInt16(); // length
+ n_items = (msg.getLength() - 4) / 11;
+ mBuyDialog = new BuyDialog(mNpcId);
+ mBuyDialog->setMoney(PlayerInfo::getAttribute(MONEY));
+
+ for (int k = 0; k < n_items; k++)
+ {
+ int value = msg.readInt32();
+ msg.readInt32(); // DCvalue
+ msg.readInt8(); // type
+ int itemId = msg.readInt16();
+ mBuyDialog->addItem(itemId, 0, value);
+ }
+ break;
+
+ case SMSG_NPC_SELL:
+ msg.readInt16(); // length
+ n_items = (msg.getLength() - 4) / 10;
+ if (n_items > 0)
+ {
+ SellDialog *dialog = new SellDialog(mNpcId);
+ dialog->setMoney(PlayerInfo::getAttribute(MONEY));
+
+ for (int k = 0; k < n_items; k++)
+ {
+ int index = msg.readInt16() - INVENTORY_OFFSET;
+ int value = msg.readInt32();
+ msg.readInt32(); // OCvalue
+
+ Item *item = PlayerInfo::getInventory()->getItem(index);
+
+ if (item && !(item->isEquipped()))
+ dialog->addItem(item, value);
+ }
+ }
+ else
+ {
+ SERVER_NOTICE(_("Nothing to sell."))
+ }
+ break;
+
+ case SMSG_NPC_BUY_RESPONSE:
+ if (msg.readInt8() == 0)
+ {
+ SERVER_NOTICE(_("Thanks for buying."))
+ }
+ else
+ {
+ // Reset player money since buy dialog already assumed purchase
+ // would go fine
+ if (mBuyDialog)
+ mBuyDialog->setMoney(PlayerInfo::getAttribute(MONEY));
+ SERVER_NOTICE(_("Unable to buy."))
+ }
+ break;
+
+ case SMSG_NPC_SELL_RESPONSE:
+ if (msg.readInt8() == 0)
+ SERVER_NOTICE(_("Thanks for selling."))
+ else
+ SERVER_NOTICE(_("Unable to sell."))
+
+ break;
+ default:
+ break;
+ }
+
+}
+
+void BuySellHandler::requestSellList(std::string nick)
+{
+ if (nick.empty() != 0 || !shopWindow)
+ return;
+
+ std::string data = "!selllist " + toString(tick_time);
+ shopWindow->setAcceptPlayer(nick);
+
+ if (config.getBoolValue("hideShopMessages"))
+ {
+ Net::getChatHandler()->privateMessage(nick, data);
+ }
+ else
+ {
+ if (chatWindow)
+ chatWindow->whisper(nick, data, BY_PLAYER);
+ }
+//was true
+}
+
+void BuySellHandler::requestBuyList(std::string nick)
+{
+ if (nick.empty() || !shopWindow)
+ return;
+
+ std::string data = "!buylist " + toString(tick_time);
+ shopWindow->setAcceptPlayer(nick);
+
+ if (config.getBoolValue("hideShopMessages"))
+ {
+ Net::getChatHandler()->privateMessage(nick, data);
+ }
+ else
+ {
+ if (chatWindow)
+ chatWindow->whisper(nick, data, BY_PLAYER);
+ }
+//was true
+}
+
+void BuySellHandler::sendBuyRequest(std::string nick, ShopItem* item,
+ int amount)
+{
+ if (!chatWindow || nick.empty() || !item ||
+ amount < 1 || amount > item->getQuantity())
+ {
+ return;
+ }
+ std::string data = strprintf("!buyitem %d %d %d",
+ item->getId(), item->getPrice(), amount);
+
+ if (config.getBoolValue("hideShopMessages"))
+ Net::getChatHandler()->privateMessage(nick, data);
+ else
+ chatWindow->whisper(nick, data, BY_PLAYER);
+//was true
+}
+
+void BuySellHandler::sendSellRequest(std::string nick, ShopItem* item,
+ int amount)
+{
+ if (!chatWindow || nick.empty() || !item ||
+ amount < 1 || amount > item->getQuantity())
+ {
+ return;
+ }
+
+ std::string data = strprintf("!sellitem %d %d %d",
+ item->getId(), item->getPrice(), amount);
+
+ if (config.getBoolValue("hideShopMessages"))
+ Net::getChatHandler()->privateMessage(nick, data);
+ else
+ chatWindow->whisper(nick, data, BY_PLAYER);
+//was true
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/buysellhandler.h b/src/net/tmwa/buysellhandler.h
new file mode 100644
index 000000000..e9ae2b9ff
--- /dev/null
+++ b/src/net/tmwa/buysellhandler.h
@@ -0,0 +1,59 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_BUYSELLHANDLER_H
+#define NET_TA_BUYSELLHANDLER_H
+
+#include "net/buysellhandler.h"
+
+#include "being.h"
+
+#include "net/net.h"
+
+#include "net/tmwa/messagehandler.h"
+
+class BuyDialog;
+
+namespace TmwAthena
+{
+
+class BuySellHandler : public MessageHandler, public Net::BuySellHandler
+{
+ public:
+ BuySellHandler();
+
+ virtual void handleMessage(Net::MessageIn &msg);
+
+ virtual void requestSellList(std::string nick);
+ virtual void requestBuyList(std::string nick);
+ virtual void sendBuyRequest(std::string nick, ShopItem* item,
+ int amount);
+ virtual void sendSellRequest(std::string nick, ShopItem* item,
+ int amount);
+
+ private:
+ int mNpcId;
+ BuyDialog *mBuyDialog;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_BUYSELLHANDLER_H
diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp
new file mode 100644
index 000000000..e500f667b
--- /dev/null
+++ b/src/net/tmwa/charserverhandler.cpp
@@ -0,0 +1,386 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/charserverhandler.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "game.h"
+#include "log.h"
+
+#include "gui/charcreatedialog.h"
+#include "gui/okdialog.h"
+
+#include "net/logindata.h"
+#include "net/messagein.h"
+#include "net/messageout.h"
+#include "net/net.h"
+
+#include "net/tmwa/gamehandler.h"
+#include "net/tmwa/loginhandler.h"
+#include "net/tmwa/network.h"
+#include "net/tmwa/protocol.h"
+
+#include "resources/colordb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern Net::CharHandler *charHandler;
+
+namespace TmwAthena
+{
+
+extern ServerInfo charServer;
+extern ServerInfo mapServer;
+
+CharServerHandler::CharServerHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_CHAR_LOGIN,
+ SMSG_CHAR_LOGIN_ERROR,
+ SMSG_CHAR_CREATE_SUCCEEDED,
+ SMSG_CHAR_CREATE_FAILED,
+ SMSG_CHAR_DELETE_SUCCEEDED,
+ SMSG_CHAR_DELETE_FAILED,
+ SMSG_CHAR_MAP_INFO,
+ SMSG_CHANGE_MAP_SERVER,
+ 0
+ };
+ handledMessages = _messages;
+ charHandler = this;
+}
+
+void CharServerHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case SMSG_CHAR_LOGIN:
+ {
+ msg.skip(2); // Length word
+ msg.skip(20); // Unused
+
+ delete_all(mCharacters);
+ mCharacters.clear();
+
+ // Derive number of characters from message length
+ const int count = (msg.getLength() - 24) / 106;
+
+ for (int i = 0; i < count; ++i)
+ {
+ Net::Character *character = new Net::Character;
+ readPlayerData(msg, character);
+ mCharacters.push_back(character);
+ logger->log("CharServer: Player: %s (%d)",
+ character->dummy->getName().c_str(), character->slot);
+ }
+
+ Client::setState(STATE_CHAR_SELECT);
+ }
+ break;
+
+ case SMSG_CHAR_LOGIN_ERROR:
+ switch (msg.readInt8())
+ {
+ case 0:
+ errorMessage = _("Access denied. Most likely, there are "
+ "too many players on this server.");
+ break;
+ case 1:
+ errorMessage = _("Cannot use this ID.");
+ break;
+ default:
+ errorMessage = _("Unknown char-server failure.");
+ break;
+ }
+ Client::setState(STATE_ERROR);
+ break;
+
+ case SMSG_CHAR_CREATE_SUCCEEDED:
+ {
+ Net::Character *character = new Net::Character;
+ readPlayerData(msg, character);
+ mCharacters.push_back(character);
+
+ updateCharSelectDialog();
+
+ // Close the character create dialog
+ if (mCharCreateDialog)
+ {
+ mCharCreateDialog->scheduleDelete();
+ mCharCreateDialog = 0;
+ }
+ }
+ break;
+
+ case SMSG_CHAR_CREATE_FAILED:
+ new OkDialog(_("Error"), _("Failed to create character. Most "
+ "likely the name is already taken."));
+ if (mCharCreateDialog)
+ mCharCreateDialog->unlock();
+ break;
+
+ case SMSG_CHAR_DELETE_SUCCEEDED:
+ delete mSelectedCharacter;
+ mCharacters.remove(mSelectedCharacter);
+ mSelectedCharacter = 0;
+ updateCharSelectDialog();
+ unlockCharSelectDialog();
+ new OkDialog(_("Info"), _("Character deleted."));
+ break;
+
+ case SMSG_CHAR_DELETE_FAILED:
+ unlockCharSelectDialog();
+ new OkDialog(_("Error"), _("Failed to delete character."));
+ break;
+
+ case SMSG_CHAR_MAP_INFO:
+ {
+// msg.skip(4); // CharID, must be the same as player_node->charID
+ PlayerInfo::setCharId(msg.readInt32());
+ GameHandler *gh = static_cast<GameHandler*>(Net::getGameHandler());
+ gh->setMap(msg.readString(16));
+ mapServer.hostname = ipToString(msg.readInt32());
+ mapServer.port = msg.readInt16();
+
+ // Prevent the selected local player from being deleted
+ player_node = mSelectedCharacter->dummy;
+ PlayerInfo::setBackend(mSelectedCharacter->data);
+
+ mSelectedCharacter->dummy = 0;
+
+ delete_all(mCharacters);
+ mCharacters.clear();
+ updateCharSelectDialog();
+
+ if (mNetwork)
+ mNetwork->disconnect();
+ Client::setState(STATE_CONNECT_GAME);
+ }
+ break;
+
+ case SMSG_CHANGE_MAP_SERVER:
+ {
+ GameHandler *gh = static_cast<GameHandler*>(Net::getGameHandler());
+ if (!gh || !mNetwork)
+ return;
+ gh->setMap(msg.readString(16));
+ int x = msg.readInt16();
+ int y = msg.readInt16();
+ mapServer.hostname = ipToString(msg.readInt32());
+ mapServer.port = msg.readInt16();
+
+ mNetwork->disconnect();
+ Client::setState(STATE_CHANGE_MAP);
+ if (player_node)
+ {
+ player_node->setTileCoords(x, y);
+ player_node->setMap(0);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void CharServerHandler::readPlayerData(Net::MessageIn &msg,
+ Net::Character *character)
+{
+ const Token &token =
+ static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();
+
+ LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0);
+ tempPlayer->setGender(token.sex);
+
+ character->data.mAttributes[EXP] = msg.readInt32();
+ character->data.mAttributes[MONEY] = msg.readInt32();
+ character->data.mStats[JOB].exp = msg.readInt32();
+
+ int temp = msg.readInt32();
+ character->data.mStats[JOB].base = temp;
+ character->data.mStats[JOB].mod = temp;
+
+ tempPlayer->setSprite(SPRITE_SHOE, msg.readInt16());
+ tempPlayer->setSprite(SPRITE_GLOVES, msg.readInt16());
+ tempPlayer->setSprite(SPRITE_CAPE, msg.readInt16());
+ tempPlayer->setSprite(SPRITE_MISC1, msg.readInt16());
+
+ msg.readInt32(); // option
+ msg.readInt32(); // karma
+ msg.readInt32(); // manner
+ msg.skip(2); // unknown
+
+ character->data.mAttributes[HP] = msg.readInt16();
+ character->data.mAttributes[MAX_HP] = msg.readInt16();
+ character->data.mAttributes[MP] = msg.readInt16();
+ character->data.mAttributes[MAX_MP] = msg.readInt16();
+
+ msg.readInt16(); // speed
+ tempPlayer->setSubtype(msg.readInt16()); // class (used for race)
+ int hairStyle = msg.readInt16();
+ Uint16 weapon = msg.readInt16();
+ tempPlayer->setSprite(SPRITE_WEAPON, weapon, "", true);
+
+ character->data.mAttributes[LEVEL] = msg.readInt16();
+
+ msg.readInt16(); // skill point
+ tempPlayer->setSprite(SPRITE_BOTTOMCLOTHES, msg.readInt16());
+ //to avoid show error (error.xml) need remove this sprite
+ if (!config.getBoolValue("hideShield"))
+ tempPlayer->setSprite(SPRITE_SHIELD, msg.readInt16());
+ else
+ msg.readInt16();
+
+ tempPlayer->setSprite(SPRITE_HAT, msg.readInt16()); // head option top
+ tempPlayer->setSprite(SPRITE_TOPCLOTHES, msg.readInt16());
+ tempPlayer->setSprite(SPRITE_HAIR, hairStyle * -1,
+ ColorDB::get(msg.readInt16()));
+ tempPlayer->setSprite(SPRITE_MISC2, msg.readInt16());
+ tempPlayer->setName(msg.readString(24));
+
+ character->dummy = tempPlayer;
+
+ for (int i = 0; i < 6; i++)
+ character->data.mStats[i + STR].base = msg.readInt8();
+
+ character->slot = msg.readInt8(); // character slot
+ msg.readInt8(); // unknown
+}
+
+void CharServerHandler::setCharSelectDialog(CharSelectDialog *window)
+{
+ mCharSelectDialog = window;
+ updateCharSelectDialog();
+}
+
+void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
+{
+ mCharCreateDialog = window;
+
+ if (!mCharCreateDialog)
+ return;
+
+ std::vector<std::string> attributes;
+ attributes.push_back(_("Strength:"));
+ attributes.push_back(_("Agility:"));
+ attributes.push_back(_("Vitality:"));
+ attributes.push_back(_("Intelligence:"));
+ attributes.push_back(_("Dexterity:"));
+ attributes.push_back(_("Luck:"));
+
+ const Token &token =
+ static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();
+
+ mCharCreateDialog->setAttributes(attributes, 30, 1, 9);
+ mCharCreateDialog->setFixedGender(true, token.sex);
+}
+
+void CharServerHandler::requestCharacters()
+{
+ connect();
+}
+
+void CharServerHandler::chooseCharacter(Net::Character *character)
+{
+ mSelectedCharacter = character;
+ mCharSelectDialog = 0;
+
+ MessageOut outMsg(CMSG_CHAR_SELECT);
+ outMsg.writeInt8(static_cast<unsigned char>(mSelectedCharacter->slot));
+}
+
+void CharServerHandler::newCharacter(const std::string &name, int slot,
+ bool gender _UNUSED_, int hairstyle,
+ int hairColor,
+ const std::vector<int> &stats)
+{
+ MessageOut outMsg(CMSG_CHAR_CREATE);
+ outMsg.writeString(name, 24);
+ for (int i = 0; i < 6; i++)
+ outMsg.writeInt8(static_cast<unsigned char>(stats[i]));
+
+ outMsg.writeInt8(static_cast<unsigned char>(slot));
+ outMsg.writeInt16(static_cast<short>(hairColor));
+ outMsg.writeInt16(static_cast<short>(hairstyle));
+}
+
+void CharServerHandler::deleteCharacter(Net::Character *character)
+{
+ if (!character)
+ return;
+
+ mSelectedCharacter = character;
+
+ MessageOut outMsg(CMSG_CHAR_DELETE);
+ outMsg.writeInt32(mSelectedCharacter->dummy->getId());
+ outMsg.writeString("a@a.com", 40);
+}
+
+void CharServerHandler::switchCharacter()
+{
+ // This is really a map-server packet
+ MessageOut outMsg(CMSG_PLAYER_RESTART);
+ outMsg.writeInt8(1);
+}
+
+unsigned int CharServerHandler::baseSprite() const
+{
+ return SPRITE_BASE;
+}
+
+unsigned int CharServerHandler::hairSprite() const
+{
+ return SPRITE_HAIR;
+}
+
+unsigned int CharServerHandler::maxSprite() const
+{
+ return SPRITE_VECTOREND;
+}
+
+void CharServerHandler::connect()
+{
+ const Token &token =
+ static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();
+
+ if (!mNetwork)
+ return;
+
+ mNetwork->disconnect();
+ mNetwork->connect(charServer);
+ MessageOut outMsg(CMSG_CHAR_SERVER_CONNECT);
+ outMsg.writeInt32(token.account_ID);
+ outMsg.writeInt32(token.session_ID1);
+ outMsg.writeInt32(token.session_ID2);
+ // [Fate] The next word is unused by the old char server, so we squeeze in
+ // mana client version information
+ outMsg.writeInt16(CLIENT_PROTOCOL_VERSION);
+ outMsg.writeInt8((token.sex == GENDER_MALE) ? 1 : 0);
+
+ // We get 4 useless bytes before the real answer comes in (what are these?)
+ mNetwork->skip(4);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h
new file mode 100644
index 000000000..d6ce0a2dc
--- /dev/null
+++ b/src/net/tmwa/charserverhandler.h
@@ -0,0 +1,87 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_CHARSERVERHANDLER_H
+#define NET_TA_CHARSERVERHANDLER_H
+
+#include "net/charhandler.h"
+#include "net/serverinfo.h"
+
+#include "net/tmwa/messagehandler.h"
+#include "net/tmwa/token.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class LoginData;
+
+namespace TmwAthena
+{
+
+/**
+ * Deals with incoming messages from the character server.
+ */
+class CharServerHandler : public MessageHandler, public Net::CharHandler
+{
+ public:
+ CharServerHandler();
+
+ virtual void handleMessage(Net::MessageIn &msg);
+
+ void setCharSelectDialog(CharSelectDialog *window);
+
+ /**
+ * Sets the character create dialog. The handler will clean up this
+ * dialog when a new character is succesfully created, and will unlock
+ * the dialog when a new character failed to be created.
+ */
+ void setCharCreateDialog(CharCreateDialog *window);
+
+ void requestCharacters();
+
+ void chooseCharacter(Net::Character *character);
+
+ void newCharacter(const std::string &name, int slot,
+ bool gender, int hairstyle, int hairColor,
+ const std::vector<int> &stats);
+
+ void deleteCharacter(Net::Character *character);
+
+ void switchCharacter();
+
+ unsigned int baseSprite() const;
+
+ unsigned int hairSprite() const;
+
+ unsigned int maxSprite() const;
+
+ void connect();
+
+ private:
+ void readPlayerData(Net::MessageIn &msg, Net::Character *character);
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_CHARSERVERHANDLER_H
diff --git a/src/net/tmwa/chathandler.cpp b/src/net/tmwa/chathandler.cpp
new file mode 100644
index 000000000..4dcfb2b34
--- /dev/null
+++ b/src/net/tmwa/chathandler.cpp
@@ -0,0 +1,552 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/chathandler.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "configuration.h"
+#include "event.h"
+#include "game.h"
+#include "localplayer.h"
+#include "playerrelations.h"
+#include "log.h"
+
+#include "gui/chat.h"
+#include "gui/shopwindow.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
+
+extern Net::ChatHandler *chatHandler;
+
+namespace TmwAthena
+{
+
+ChatHandler::ChatHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_BEING_CHAT,
+ SMSG_PLAYER_CHAT,
+ SMSG_WHISPER,
+ SMSG_WHISPER_RESPONSE,
+ SMSG_GM_CHAT,
+ SMSG_MVP, // MVP
+ 0
+ };
+ handledMessages = _messages;
+ chatHandler = this;
+}
+
+void ChatHandler::handleMessage(Net::MessageIn &msg)
+{
+ if (!localChatTab)
+ return;
+
+ Being *being;
+ std::string chatMsg;
+ std::string nick;
+ int chatMsgLength;
+
+ switch (msg.getId())
+ {
+ case SMSG_WHISPER_RESPONSE:
+ {
+ if (mSentWhispers.empty())
+ {
+ nick = "user";
+ }
+ else
+ {
+ nick = mSentWhispers.front();
+ mSentWhispers.pop();
+ }
+
+ int type = msg.readInt8();
+ switch (type)
+ {
+ case 0x00:
+ // Success (don't need to report)
+ break;
+ case 0x01:
+ if (chatWindow)
+ {
+ chatWindow->whisper(nick,
+ strprintf(_("Whisper could not be "
+ "sent, %s is offline."), nick.c_str()), BY_SERVER);
+ }
+ break;
+ case 0x02:
+ if (chatWindow)
+ {
+ chatWindow->whisper(nick,
+ strprintf(_("Whisper could not "
+ "be sent, ignored by %s."), nick.c_str()),
+ BY_SERVER);
+ }
+ break;
+ default:
+ if (logger)
+ {
+ logger->log("QQQ SMSG_WHISPER_RESPONSE:"
+ + toString(type));
+ }
+ }
+ break;
+ }
+
+ // Received whisper
+ case SMSG_WHISPER:
+ {
+ chatMsgLength = msg.readInt16() - 28;
+ nick = msg.readString(24);
+
+ if (chatMsgLength <= 0)
+ break;
+
+ chatMsg = msg.readString(chatMsgLength);
+
+ if (nick != "Server")
+ {
+ if (player_relations.hasPermission(
+ nick, PlayerRelation::WHISPER))
+ {
+ bool tradeBot = config.getBoolValue("tradebot");
+ bool showMsg = !config.getBoolValue("hideShopMessages");
+ if (player_relations.hasPermission(
+ nick, PlayerRelation::TRADE))
+ {
+ if (shopWindow)
+ { //commands to shop from player
+ if (chatMsg.find("!selllist ") == 0)
+ {
+ if (tradeBot)
+ {
+ if (showMsg && chatWindow)
+ chatWindow->whisper(nick, chatMsg);
+ shopWindow->giveList(nick,
+ ShopWindow::SELL);
+ }
+ }
+ else if (chatMsg.find("!buylist ") == 0)
+ {
+ if (tradeBot)
+ {
+ if (showMsg && chatWindow)
+ chatWindow->whisper(nick, chatMsg);
+ shopWindow->giveList(nick,
+ ShopWindow::BUY);
+ }
+ }
+ else if (chatMsg.find("!buyitem ") == 0)
+ {
+ if (showMsg && chatWindow)
+ chatWindow->whisper(nick, chatMsg);
+ if (tradeBot)
+ {
+ shopWindow->processRequest(nick, chatMsg,
+ ShopWindow::BUY);
+ }
+ }
+ else if (chatMsg.find("!sellitem ") == 0)
+ {
+ if (showMsg && chatWindow)
+ chatWindow->whisper(nick, chatMsg);
+ if (tradeBot)
+ {
+ shopWindow->processRequest(nick, chatMsg,
+ ShopWindow::SELL);
+ }
+ }
+ else if (chatMsg.length() > 3
+ && chatMsg.find("\302\202") == 0)
+ {
+ chatMsg = chatMsg.erase(0, 2);
+ if (showMsg && chatWindow)
+ chatWindow->whisper(nick, chatMsg);
+ if (chatMsg.find("B1") == 0
+ || chatMsg.find("S1") == 0)
+ {
+ shopWindow->showList(nick, chatMsg);
+ }
+ }
+ else if (chatWindow)
+ {
+ chatWindow->whisper(nick, chatMsg);
+ }
+ }
+ else if (chatWindow)
+ {
+ chatWindow->whisper(nick, chatMsg);
+ }
+ }
+ else
+ {
+ if (chatWindow && (showMsg
+ || (chatMsg.find("!selllist")
+ != 0 && chatMsg.find("!buylist") != 0)))
+ {
+ chatWindow->whisper(nick, chatMsg);
+ }
+ }
+ }
+ }
+ else if (localChatTab)
+ {
+ localChatTab->chatLog(chatMsg, BY_SERVER);
+ }
+
+ break;
+ }
+
+ // Received speech from being
+ case SMSG_BEING_CHAT:
+ {
+ if (!actorSpriteManager)
+ return;
+
+ chatMsgLength = msg.readInt16() - 8;
+ being = actorSpriteManager->findBeing(msg.readInt32());
+
+ if (!being || chatMsgLength <= 0)
+ break;
+
+ std::string str2;
+ chatMsg = msg.readRawString(chatMsgLength);
+
+ if (being->getType() == Being::PLAYER)
+ being->setTalkTime();
+
+ std::string::size_type pos = chatMsg.find(" : ", 0);
+ std::string sender_name = ((pos == std::string::npos)
+ ? "" : chatMsg.substr(0, pos));
+
+ if (sender_name != being->getName()
+ && being->getType() == Being::PLAYER)
+ {
+ if (!being->getName().empty())
+ sender_name = being->getName();
+ }
+ else
+ {
+ chatMsg.erase(0, pos + 3);
+ }
+
+ trim(chatMsg);
+
+ // We use getIgnorePlayer instead of ignoringPlayer here
+ // because ignorePlayer' side effects are triggered
+ // right below for Being::IGNORE_SPEECH_FLOAT.
+ if (player_relations.checkPermissionSilently(sender_name,
+ PlayerRelation::SPEECH_LOG) && chatWindow)
+ {
+ chatWindow->resortChatLog(removeColors(sender_name) + " : "
+ + chatMsg, BY_OTHER);
+ }
+
+ if (player_relations.hasPermission(sender_name,
+ PlayerRelation::SPEECH_FLOAT))
+ {
+ being->setSpeech(chatMsg, SPEECH_TIME);
+ }
+ break;
+ }
+
+ case SMSG_PLAYER_CHAT:
+ case SMSG_GM_CHAT:
+ {
+ chatMsgLength = msg.readInt16() - 4;
+
+ if (chatMsgLength <= 0)
+ break;
+
+ std::string str2;
+ chatMsg = msg.readRawString(chatMsgLength);
+ std::string::size_type pos = chatMsg.find(" : ", 0);
+
+ if (msg.getId() == SMSG_PLAYER_CHAT)
+ {
+ if (chatWindow)
+ chatWindow->resortChatLog(chatMsg, BY_PLAYER);
+// if (localChatTab)
+// localChatTab->chatLog(chatMsg, BY_PLAYER);
+
+ const std::string senseStr = "You sense the following: ";
+ if (actorSpriteManager && !chatMsg.find(senseStr))
+ {
+ actorSpriteManager->parseLevels(
+ chatMsg.substr(senseStr.size()));
+ }
+
+ if (pos != std::string::npos)
+ chatMsg.erase(0, pos + 3);
+
+ trim(chatMsg);
+
+ if (player_node)
+ player_node->setSpeech(chatMsg, SPEECH_TIME);
+ }
+ else if (localChatTab)
+ {
+ localChatTab->chatLog(chatMsg, BY_GM);
+ }
+ break;
+ }
+
+ case SMSG_MVP:
+ {
+ // Display MVP player
+ int id = msg.readInt32(); // id
+ if (localChatTab && actorSpriteManager)
+ {
+ being = actorSpriteManager->findBeing(id);
+ if (!being)
+ {
+ localChatTab->chatLog(_("MVP player."), BY_SERVER);
+ }
+ else
+ {
+ localChatTab->chatLog(_("MVP player: ")
+ + being->getName(), BY_SERVER);
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void ChatHandler::talk(const std::string &text)
+{
+ if (!player_node)
+ return;
+
+ std::string mes = player_node->getName() + " : " + text;
+// std::string mes = player_node->getName() + "zzzz : " + text;
+
+ MessageOut outMsg(CMSG_CHAT_MESSAGE);
+ // Added + 1 in order to let eAthena parse admin commands correctly
+ outMsg.writeInt16(static_cast<short>(mes.length() + 4 + 1));
+ outMsg.writeString(mes, static_cast<int>(mes.length() + 1));
+}
+
+void ChatHandler::talkRaw(const std::string &mes)
+{
+ MessageOut outMsg(CMSG_CHAT_MESSAGE);
+ // Added + 1 in order to let eAthena parse admin commands correctly
+ outMsg.writeInt16(static_cast<short>(mes.length() + 4 + 1));
+ outMsg.writeString(mes, static_cast<int>(mes.length() + 1));
+}
+
+void ChatHandler::me(const std::string &text)
+{
+ std::string action = strprintf("*%s*", text.c_str());
+
+ talk(action);
+}
+
+void ChatHandler::privateMessage(const std::string &recipient,
+ const std::string &text)
+{
+ MessageOut outMsg(CMSG_CHAT_WHISPER);
+ outMsg.writeInt16(static_cast<short>(text.length() + 28));
+ outMsg.writeString(recipient, 24);
+ outMsg.writeString(text, static_cast<int>(text.length()));
+ mSentWhispers.push(recipient);
+}
+
+void ChatHandler::channelList()
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::enterChannel(const std::string &channel _UNUSED_,
+ const std::string &password _UNUSED_)
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::quitChannel(int channelId _UNUSED_)
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::sendToChannel(int channelId _UNUSED_,
+ const std::string &text _UNUSED_)
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::userList(const std::string &channel _UNUSED_)
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::setChannelTopic(int channelId _UNUSED_,
+ const std::string &text _UNUSED_)
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::setUserMode(int channelId _UNUSED_,
+ const std::string &name _UNUSED_,
+ int mode _UNUSED_)
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::kickUser(int channelId _UNUSED_,
+ const std::string &name _UNUSED_)
+{
+ SERVER_NOTICE(_("Channels are not supported!"))
+}
+
+void ChatHandler::who()
+{
+ MessageOut outMsg(CMSG_WHO_REQUEST);
+}
+
+void ChatHandler::sendRaw(const std::string &args)
+{
+ std::string line = args;
+ std::string str;
+ MessageOut *outMsg = 0;
+
+ if (line == "")
+ return;
+
+ std::string::size_type pos = line.find(" ");
+ if (pos != std::string::npos)
+ {
+ str = line.substr(0, pos);
+ outMsg = new MessageOut(static_cast<short>(atoi(str.c_str())));
+ line = line.substr(pos + 1);
+ pos = line.find(" ");
+ }
+ else
+ {
+ outMsg = new MessageOut(static_cast<short>(atoi(line.c_str())));
+ delete outMsg;
+ return;
+ }
+
+ while (pos != std::string::npos)
+ {
+ str = line.substr(0, pos);
+ processRaw(*outMsg, str);
+ line = line.substr(pos + 1);
+ pos = line.find(" ");
+ }
+ if (outMsg)
+ {
+ if (line != "")
+ processRaw(*outMsg, line);
+ delete outMsg;
+ }
+}
+
+void ChatHandler::processRaw(MessageOut &outMsg, std::string &line)
+{
+ std::string::size_type pos = line.find(":");
+ if (pos == std::string::npos)
+ {
+ int i = atoi(line.c_str());
+ if (line.length() <= 3)
+ outMsg.writeInt8(static_cast<char>(i));
+ else if (line.length() <= 5)
+ outMsg.writeInt16(static_cast<short>(i));
+ else
+ outMsg.writeInt32(i);
+ }
+ else
+ {
+ std::string header = line.substr(0, pos);
+ std::string data = line.substr(pos + 1);
+ if (header.length() != 1)
+ return;
+
+ int i = 0;
+
+ switch (header[0])
+ {
+ case '1':
+ case '2':
+ case '4':
+ i = atoi(data.c_str());
+ break;
+ default:
+ break;
+ }
+
+ switch (header[0])
+ {
+ case '1':
+ outMsg.writeInt8(static_cast<char>(i));
+ break;
+ case '2':
+ outMsg.writeInt16(static_cast<short>(i));
+ break;
+ case '4':
+ outMsg.writeInt32(i);
+ break;
+ case 'c':
+ {
+ pos = line.find(",");
+ if (pos != std::string::npos)
+ {
+ unsigned short x = static_cast<unsigned short>(
+ atoi(data.substr(0, pos).c_str()));
+ data = data.substr(pos + 1);
+ pos = line.find(",");
+ if (pos == std::string::npos)
+ break;
+
+ unsigned short y = static_cast<unsigned short>(
+ atoi(data.substr(0, pos).c_str()));
+ int dir = atoi(data.substr(pos + 1).c_str());
+ outMsg.writeCoordinates(x, y,
+ static_cast<unsigned char>(dir));
+ }
+ break;
+ }
+ case 't':
+ outMsg.writeString(data, static_cast<int>(data.length()));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+} // namespace TmwAthena
+
diff --git a/src/net/tmwa/chathandler.h b/src/net/tmwa/chathandler.h
new file mode 100644
index 000000000..1432da3a2
--- /dev/null
+++ b/src/net/tmwa/chathandler.h
@@ -0,0 +1,87 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_CHATHANDLER_H
+#define NET_TA_CHATHANDLER_H
+
+#include "net/chathandler.h"
+#include "net/net.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#include <queue>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class ChatHandler : public MessageHandler, public Net::ChatHandler
+{
+ public:
+ ChatHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void talk(const std::string &text);
+
+ void talkRaw(const std::string &text);
+
+ void me(const std::string &text);
+
+ void privateMessage(const std::string &recipient,
+ const std::string &text);
+
+ void channelList();
+
+ void enterChannel(const std::string &channel,
+ const std::string &password);
+
+ void quitChannel(int channelId);
+
+ void sendToChannel(int channelId, const std::string &text);
+
+ void userList(const std::string &channel);
+
+ void setChannelTopic(int channelId, const std::string &text);
+
+ void setUserMode(int channelId, const std::string &name, int mode);
+
+ void kickUser(int channelId, const std::string &name);
+
+ void who();
+
+ void sendRaw(const std::string &args);
+
+ void processRaw(MessageOut &outMsg, std::string &line);
+
+ private:
+ typedef std::queue<std::string> WhisperQueue;
+ WhisperQueue mSentWhispers;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_CHATHANDLER_H
diff --git a/src/net/tmwa/gamehandler.cpp b/src/net/tmwa/gamehandler.cpp
new file mode 100644
index 000000000..5f949ce6e
--- /dev/null
+++ b/src/net/tmwa/gamehandler.cpp
@@ -0,0 +1,196 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/gamehandler.h"
+
+#include "client.h"
+#include "event.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/okdialog.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/loginhandler.h"
+#include "net/tmwa/network.h"
+#include "net/tmwa/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern Net::GameHandler *gameHandler;
+
+namespace TmwAthena
+{
+
+extern ServerInfo mapServer;
+
+GameHandler::GameHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_MAP_LOGIN_SUCCESS,
+ SMSG_SERVER_PING,
+ SMSG_WHO_ANSWER,
+ SMSG_CHAR_SWITCH_RESPONSE,
+ SMSG_MAP_QUIT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+ gameHandler = this;
+
+ listen(CHANNEL_GAME);
+}
+
+void GameHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case SMSG_MAP_LOGIN_SUCCESS:
+ {
+ unsigned char direction;
+ Uint16 x, y;
+ msg.readInt32(); // server tick
+ msg.readCoordinates(x, y, direction);
+ msg.skip(2); // unknown
+ logger->log("Protocol: Player start position: (%d, %d),"
+ " Direction: %d", x, y, direction);
+ // Switch now or we'll have problems
+ Client::setState(STATE_GAME);
+ if (player_node)
+ player_node->setTileCoords(x, y);
+ break;
+ }
+
+ case SMSG_SERVER_PING:
+ // We ignore this for now
+ // int tick = msg.readInt32()
+ break;
+
+ case SMSG_WHO_ANSWER:
+ SERVER_NOTICE(strprintf(_("Online users: %d"), msg.readInt32()))
+ break;
+
+ case SMSG_CHAR_SWITCH_RESPONSE:
+ if (msg.readInt8())
+ Client::setState(STATE_SWITCH_CHARACTER);
+ break;
+
+ case SMSG_MAP_QUIT_RESPONSE:
+ if (msg.readInt8())
+ new OkDialog(_("Game"), _("Request to quit denied!"), NULL);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void GameHandler::event(Channels channel, const Mana::Event &event)
+{
+ if (channel == CHANNEL_GAME)
+ {
+ if (event.getName() == EVENT_ENGINESINITALIZED)
+ Game::instance()->changeMap(mMap);
+ else if (event.getName() == EVENT_MAPLOADED)
+ MessageOut outMsg(CMSG_MAP_LOADED);
+ }
+}
+
+void GameHandler::connect()
+{
+ if (!mNetwork)
+ return;
+
+ mNetwork->connect(mapServer);
+
+ const Token &token =
+ static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();
+
+
+ if (Client::getState() == STATE_CONNECT_GAME)
+ {
+ mCharID = player_node->getId();
+ // Change the player's ID to the account ID to match what eAthena uses
+ player_node->setId(token.account_ID);
+ }
+
+ // Send login infos
+ MessageOut outMsg(CMSG_MAP_SERVER_CONNECT);
+ outMsg.writeInt32(token.account_ID);
+ outMsg.writeInt32(mCharID);
+ outMsg.writeInt32(token.session_ID1);
+ outMsg.writeInt32(token.session_ID2);
+ outMsg.writeInt8((token.sex == GENDER_MALE) ? 1 : 0);
+
+/*
+ if (player_node)
+ {
+ // Change the player's ID to the account ID to match what eAthena uses
+ player_node->setId(token.account_ID);
+ }
+*/
+ // We get 4 useless bytes before the real answer comes in (what are these?)
+ mNetwork->skip(4);
+}
+
+bool GameHandler::isConnected()
+{
+ if (!mNetwork)
+ return false;
+ return mNetwork->isConnected();
+}
+
+void GameHandler::disconnect()
+{
+ if (mNetwork)
+ mNetwork->disconnect();
+}
+
+void GameHandler::who()
+{
+}
+
+void GameHandler::quit()
+{
+ MessageOut outMsg(CMSG_CLIENT_QUIT);
+}
+
+void GameHandler::ping(int tick)
+{
+ MessageOut msg(CMSG_CLIENT_PING);
+ msg.writeInt32(tick);
+}
+
+void GameHandler::setMap(const std::string map)
+{
+ mMap = map.substr(0, map.rfind("."));
+}
+
+void GameHandler::disconnect2()
+{
+ MessageOut outMsg(CMSG_CLIENT_DISCONNECT);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/gamehandler.h b/src/net/tmwa/gamehandler.h
new file mode 100644
index 000000000..d59320bfa
--- /dev/null
+++ b/src/net/tmwa/gamehandler.h
@@ -0,0 +1,85 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_MAPHANDLER_H
+#define NET_TA_MAPHANDLER_H
+
+#include "listener.h"
+
+#include "net/gamehandler.h"
+#include "net/net.h"
+#include "net/serverinfo.h"
+
+#include "net/tmwa/messagehandler.h"
+#include "net/tmwa/token.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class GameHandler : public MessageHandler, public Net::GameHandler,
+ public Mana::Listener
+{
+ public:
+ GameHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void event(Channels channel, const Mana::Event &event);
+
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
+ void who();
+
+ void quit();
+
+ void ping(int tick);
+
+ bool removeDeadBeings() const
+ { return true; }
+
+ void clear();
+
+ void setMap(const std::string map);
+
+ /** The tmwAthena protocol is making use of the MP status bar. */
+ bool canUseMagicBar() const
+ { return true; }
+
+ void disconnect2();
+
+ private:
+ std::string mMap;
+ int mCharID; /// < Saved for map-server switching
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_MAPHANDLER_H
diff --git a/src/net/tmwa/generalhandler.cpp b/src/net/tmwa/generalhandler.cpp
new file mode 100644
index 000000000..83d8ceb8d
--- /dev/null
+++ b/src/net/tmwa/generalhandler.cpp
@@ -0,0 +1,285 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/generalhandler.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "log.h"
+
+#include "gui/charselectdialog.h"
+#include "gui/inventorywindow.h"
+#include "gui/register.h"
+#include "gui/skilldialog.h"
+#include "gui/socialwindow.h"
+#include "gui/statuswindow.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+#include "net/serverinfo.h"
+
+#include "net/tmwa/adminhandler.h"
+#include "net/tmwa/beinghandler.h"
+#include "net/tmwa/buysellhandler.h"
+#include "net/tmwa/chathandler.h"
+#include "net/tmwa/charserverhandler.h"
+#include "net/tmwa/gamehandler.h"
+#include "net/tmwa/guildhandler.h"
+#include "net/tmwa/inventoryhandler.h"
+#include "net/tmwa/itemhandler.h"
+#include "net/tmwa/loginhandler.h"
+#include "net/tmwa/network.h"
+#include "net/tmwa/npchandler.h"
+#include "net/tmwa/partyhandler.h"
+#include "net/tmwa/playerhandler.h"
+#include "net/tmwa/protocol.h"
+#include "net/tmwa/tradehandler.h"
+#include "net/tmwa/specialhandler.h"
+
+#include "net/tmwa/gui/guildtab.h"
+#include "net/tmwa/gui/partytab.h"
+
+#include "resources/itemdb.h"
+
+#include "utils/gettext.h"
+
+#include <assert.h>
+#include <list>
+
+extern Net::GeneralHandler *generalHandler;
+
+namespace TmwAthena
+{
+
+ServerInfo charServer;
+ServerInfo mapServer;
+
+extern Guild *taGuild;
+extern Party *taParty;
+
+GeneralHandler::GeneralHandler():
+ mAdminHandler(new AdminHandler),
+ mBeingHandler(new BeingHandler(config.getBoolValue("EnableSync"))),
+ mBuySellHandler(new BuySellHandler),
+ mCharHandler(new CharServerHandler),
+ mChatHandler(new ChatHandler),
+ mGameHandler(new GameHandler),
+ mGuildHandler(new GuildHandler),
+ mInventoryHandler(new InventoryHandler),
+ mItemHandler(new ItemHandler),
+ mLoginHandler(new LoginHandler),
+ mNpcHandler(new NpcHandler),
+ mPartyHandler(new PartyHandler),
+ mPlayerHandler(new PlayerHandler),
+ mSpecialHandler(new SpecialHandler),
+ mTradeHandler(new TradeHandler)
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_CONNECTION_PROBLEM,
+ 0
+ };
+ handledMessages = _messages;
+ generalHandler = this;
+
+ std::list<ItemDB::Stat> stats;
+ stats.push_back(ItemDB::Stat("str", _("Strength %+d")));
+ stats.push_back(ItemDB::Stat("agi", _("Agility %+d")));
+ stats.push_back(ItemDB::Stat("vit", _("Vitality %+d")));
+ stats.push_back(ItemDB::Stat("int", _("Intelligence %+d")));
+ stats.push_back(ItemDB::Stat("dex", _("Dexterity %+d")));
+ stats.push_back(ItemDB::Stat("luck", _("Luck %+d")));
+
+ ItemDB::setStatsList(stats);
+
+ listen(CHANNEL_GAME);
+}
+
+GeneralHandler::~GeneralHandler()
+{
+ delete mNetwork;
+ mNetwork = 0;
+}
+
+void GeneralHandler::handleMessage(Net::MessageIn &msg)
+{
+ int code;
+
+ switch (msg.getId())
+ {
+ case SMSG_CONNECTION_PROBLEM:
+ code = msg.readInt8();
+ logger->log("Connection problem: %i", code);
+
+ switch (code)
+ {
+ case 0:
+ errorMessage = _("Authentication failed.");
+ break;
+ case 1:
+ errorMessage = _("No servers available.");
+ break;
+ case 2:
+ if (Client::getState() == STATE_GAME)
+ errorMessage = _("Someone else is trying to use this "
+ "account.");
+ else
+ errorMessage = _("This account is already logged in.");
+ break;
+ case 3:
+ errorMessage = _("Speed hack detected.");
+ break;
+ case 8:
+ errorMessage = _("Duplicated login.");
+ break;
+ default:
+ errorMessage = _("Unknown connection error.");
+ break;
+ }
+ Client::setState(STATE_ERROR);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void GeneralHandler::load()
+{
+ (new Network)->registerHandler(this);
+
+ if (!mNetwork)
+ return;
+
+ mNetwork->registerHandler(mAdminHandler.get());
+ mNetwork->registerHandler(mBeingHandler.get());
+ mNetwork->registerHandler(mBuySellHandler.get());
+ mNetwork->registerHandler(mChatHandler.get());
+ mNetwork->registerHandler(mCharHandler.get());
+ mNetwork->registerHandler(mGameHandler.get());
+ mNetwork->registerHandler(mGuildHandler.get());
+ mNetwork->registerHandler(mInventoryHandler.get());
+ mNetwork->registerHandler(mItemHandler.get());
+ mNetwork->registerHandler(mLoginHandler.get());
+ mNetwork->registerHandler(mNpcHandler.get());
+ mNetwork->registerHandler(mPlayerHandler.get());
+ mNetwork->registerHandler(mSpecialHandler.get());
+ mNetwork->registerHandler(mTradeHandler.get());
+ mNetwork->registerHandler(mPartyHandler.get());
+}
+
+void GeneralHandler::reload()
+{
+ if (mNetwork)
+ mNetwork->disconnect();
+
+ static_cast<LoginHandler*>(mLoginHandler.get())->clearWorlds();
+ static_cast<CharServerHandler*>(
+ mCharHandler.get())->setCharCreateDialog(0);
+ static_cast<CharServerHandler*>(
+ mCharHandler.get())->setCharSelectDialog(0);
+}
+
+void GeneralHandler::unload()
+{
+ if (mNetwork)
+ mNetwork->clearHandlers();
+}
+
+void GeneralHandler::flushNetwork()
+{
+ if (!mNetwork)
+ return;
+
+ mNetwork->flush();
+ mNetwork->dispatchMessages();
+
+ if (mNetwork->getState() == Network::NET_ERROR)
+ {
+ if (!mNetwork->getError().empty())
+ errorMessage = mNetwork->getError();
+ else
+ errorMessage = _("Got disconnected from server!");
+
+ Client::setState(STATE_ERROR);
+ }
+}
+
+void GeneralHandler::clearHandlers()
+{
+ if (mNetwork)
+ mNetwork->clearHandlers();
+}
+
+void GeneralHandler::event(Channels channel,
+ const Mana::Event &event)
+{
+ if (channel == CHANNEL_GAME)
+ {
+ if (event.getName() == EVENT_GUIWINDOWSLOADED)
+ {
+ if (inventoryWindow)
+ inventoryWindow->setSplitAllowed(false);
+ if (skillDialog)
+ skillDialog->loadSkills("ea-skills.xml");
+
+ if (!statusWindow)
+ return;
+
+ statusWindow->addAttribute(STR, _("Strength"), true, "");
+ statusWindow->addAttribute(AGI, _("Agility"), true, "");
+ statusWindow->addAttribute(VIT, _("Vitality"), true, "");
+ statusWindow->addAttribute(INT, _("Intelligence"), true, "");
+ statusWindow->addAttribute(DEX, _("Dexterity"), true, "");
+ statusWindow->addAttribute(LUK, _("Luck"), true, "");
+
+ statusWindow->addAttribute(ATK, _("Attack"), false, "");
+ statusWindow->addAttribute(DEF, _("Defense"), false, "");
+ statusWindow->addAttribute(MATK, _("M.Attack"), false, "");
+ statusWindow->addAttribute(MDEF, _("M.Defense"), false, "");
+ statusWindow->addAttribute(HIT, _("% Accuracy"), false, "");
+ statusWindow->addAttribute(FLEE, _("% Evade"), false, "");
+ statusWindow->addAttribute(CRIT, _("% Critical"), false, "");
+ statusWindow->addAttribute(ATTACK_SPEED, _("Attack Delay"),
+ false, "");
+ statusWindow->addAttribute(WALK_SPEED, _("Walk Delay"),
+ false, "");
+ statusWindow->addAttribute(ATTACK_RANGE, _("Attack Range"),
+ false, "");
+ }
+ else if (event.getName() == EVENT_GUIWINDOWSUNLOADING)
+ {
+ if (socialWindow)
+ {
+ socialWindow->removeTab(taGuild);
+ socialWindow->removeTab(taParty);
+ }
+
+ delete guildTab;
+ guildTab = 0;
+
+ delete partyTab;
+ partyTab = 0;
+ }
+ }
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/generalhandler.h b/src/net/tmwa/generalhandler.h
new file mode 100644
index 000000000..eded556d0
--- /dev/null
+++ b/src/net/tmwa/generalhandler.h
@@ -0,0 +1,83 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TMWA_GENERALHANDLER_H
+#define NET_TMWA_GENERALHANDLER_H
+
+#include "listener.h"
+
+#include "net/generalhandler.h"
+#include "net/net.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class GeneralHandler : public MessageHandler, public Net::GeneralHandler,
+ public Mana::Listener
+{
+ public:
+ GeneralHandler();
+
+ ~GeneralHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void load();
+
+ void reload();
+
+ void unload();
+
+ void flushNetwork();
+
+ void clearHandlers();
+
+ void event(Channels channel, const Mana::Event &event);
+
+ protected:
+ MessageHandlerPtr mAdminHandler;
+ MessageHandlerPtr mBeingHandler;
+ MessageHandlerPtr mBuySellHandler;
+ MessageHandlerPtr mCharHandler;
+ MessageHandlerPtr mChatHandler;
+ MessageHandlerPtr mGameHandler;
+ MessageHandlerPtr mGuildHandler;
+ MessageHandlerPtr mInventoryHandler;
+ MessageHandlerPtr mItemHandler;
+ MessageHandlerPtr mLoginHandler;
+ MessageHandlerPtr mNpcHandler;
+ MessageHandlerPtr mPartyHandler;
+ MessageHandlerPtr mPlayerHandler;
+ MessageHandlerPtr mSpecialHandler;
+ MessageHandlerPtr mTradeHandler;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_GENERALHANDLER_H
diff --git a/src/net/tmwa/gui/guildtab.cpp b/src/net/tmwa/gui/guildtab.cpp
new file mode 100644
index 000000000..4b080277c
--- /dev/null
+++ b/src/net/tmwa/gui/guildtab.cpp
@@ -0,0 +1,150 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/gui/guildtab.h"
+
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "guild.h"
+#include "localplayer.h"
+
+#include "gui/theme.h"
+
+#include "net/net.h"
+#include "net/guildhandler.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+namespace TmwAthena
+{
+
+extern Guild *taGuild;
+
+GuildTab::GuildTab() :
+ ChatTab(_("Guild"))
+{
+ setTabColor(&Theme::getThemeColor(Theme::GUILD_CHAT_TAB));
+}
+
+GuildTab::~GuildTab()
+{
+}
+
+void GuildTab::handleInput(const std::string &msg)
+{
+ if (!taGuild)
+ return;
+
+ if (chatWindow)
+ {
+ Net::getGuildHandler()->chat(taGuild->getId(),
+ chatWindow->doReplace(msg));
+ }
+ else
+ {
+ Net::getGuildHandler()->chat(taGuild->getId(), msg);
+ }
+}
+
+void GuildTab::showHelp()
+{
+ chatLog(_("/help > Display this help."));
+ chatLog(_("/invite > Invite a player to your guild"));
+ chatLog(_("/leave > Leave the guild you are in"));
+ chatLog(_("/kick > Kick some one from the guild you are in"));
+}
+
+bool GuildTab::handleCommand(const std::string &type, const std::string &args)
+{
+ if (type == "help")
+ {
+ if (args == "invite")
+ {
+ chatLog(_("Command: /invite <nick>"));
+ chatLog(_("This command invites <nick> to the guild you're in."));
+ chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ }
+ else if (args == "leave")
+ {
+ chatLog(_("Command: /leave"));
+ chatLog(_("This command causes the player to leave the guild."));
+ }
+ else
+ return false;
+ }
+/*
+ else if (type == "create" || type == "new")
+ {
+ if (args.empty())
+ chatLog(_("Guild name is missing."), BY_SERVER);
+ else
+ Net::getGuildHandler()->create(args);
+ }
+*/
+ else if (type == "invite" && taGuild)
+ {
+ Net::getGuildHandler()->invite(taGuild->getId(), args);
+ }
+ else if (type == "leave" && taGuild)
+ {
+ Net::getGuildHandler()->leave(taGuild->getId());
+ }
+ else if (type == "kick" && taGuild)
+ {
+ Net::getGuildHandler()->kick(taGuild->getMember(args));
+ }
+ else if (type == "notice" && taGuild)
+ {
+ std::string str1 = args.substr(0, 60);
+ std::string str2 = "";
+ if (args.size() > 60)
+ str2 = args.substr(60);
+ Net::getGuildHandler()->changeNotice(taGuild->getId(), str1, str2);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void GuildTab::getAutoCompleteList(std::vector<std::string> &names) const
+{
+ if (taGuild)
+ taGuild->getNames(names);
+ names.push_back("/notice ");
+}
+
+void GuildTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log("#Guild", msg);
+}
+
+} // namespace TmwAthena
+
diff --git a/src/net/tmwa/gui/guildtab.h b/src/net/tmwa/gui/guildtab.h
new file mode 100644
index 000000000..cce9eb596
--- /dev/null
+++ b/src/net/tmwa/gui/guildtab.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TA_GUILDTAB_H
+#define TA_GUILDTAB_H
+
+#include "gui/widgets/chattab.h"
+
+namespace TmwAthena
+{
+
+/**
+ * A tab for a guild chat channel.
+ */
+class GuildTab : public ChatTab
+{
+ public:
+ GuildTab();
+ ~GuildTab();
+
+ void showHelp();
+
+ bool handleCommand(const std::string &type, const std::string &args);
+
+ void saveToLogFile(std::string &msg);
+
+ int getType() const { return ChatTab::TAB_GUILD; }
+
+ protected:
+ void handleInput(const std::string &msg);
+
+ void getAutoCompleteList(std::vector<std::string> &names) const;
+};
+
+extern GuildTab *guildTab;
+
+} // namespace TmwAthena
+
+#endif // TA_GUILDTAB_H
diff --git a/src/net/tmwa/gui/partytab.cpp b/src/net/tmwa/gui/partytab.cpp
new file mode 100644
index 000000000..9cfb4670f
--- /dev/null
+++ b/src/net/tmwa/gui/partytab.cpp
@@ -0,0 +1,242 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/gui/partytab.h"
+
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "localplayer.h"
+#include "party.h"
+
+#include "gui/theme.h"
+
+#include "net/net.h"
+#include "net/partyhandler.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "net/chathandler.h"
+
+namespace TmwAthena
+{
+
+PartyTab::PartyTab() :
+ ChatTab(_("Party"))
+{
+ setTabColor(&Theme::getThemeColor(Theme::PARTY_CHAT_TAB));
+}
+
+PartyTab::~PartyTab()
+{
+}
+
+void PartyTab::handleInput(const std::string &msg)
+{
+ if (chatWindow)
+ Net::getPartyHandler()->chat(chatWindow->doReplace(msg));
+ else
+ Net::getPartyHandler()->chat(msg);
+}
+
+void PartyTab::showHelp()
+{
+ chatLog(_("/help > Display this help."));
+ chatLog(_("/invite > Invite a player to your party"));
+ chatLog(_("/leave > Leave the party you are in"));
+ chatLog(_("/kick > Kick some one from the party you are in"));
+ chatLog(_("/item > Show/change party item sharing options"));
+ chatLog(_("/exp > Show/change party experience sharing options"));
+}
+
+bool PartyTab::handleCommand(const std::string &type, const std::string &args)
+{
+ if (type == "help")
+ {
+ if (args == "invite")
+ {
+ chatLog(_("Command: /invite <nick>"));
+ chatLog(_("This command invites <nick> to party with you."));
+ chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ }
+ else if (args == "leave")
+ {
+ chatLog(_("Command: /leave"));
+ chatLog(_("This command causes the player to leave the party."));
+ }
+ else if (args == "item")
+ {
+ chatLog(_("Command: /item <policy>"));
+ chatLog(
+ _("This command changes the party's item sharing policy."));
+ chatLog(_("<policy> can be one of \"1\", \"yes\", \"true\" to "
+ "enable item sharing, or \"0\", \"no\", \"false\" to "
+ "disable item sharing."));
+ chatLog(_("Command: /item"));
+ chatLog(_("This command displays the party's"
+ " current item sharing policy."));
+ }
+ else if (args == "exp")
+ {
+ chatLog(_("Command: /exp <policy>"));
+ chatLog(_("This command changes the party's "
+ "experience sharing policy."));
+ chatLog(_("<policy> can be one of \"1\", \"yes\", \"true\" to "
+ "enable experience sharing, or \"0\","
+ " \"no\", \"false\" to disable experience sharing."));
+ chatLog(_("Command: /exp"));
+ chatLog(_("This command displays the party's current "
+ "experience sharing policy."));
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (type == "create" || type == "new")
+ {
+ if (args.empty())
+ chatLog(_("Party name is missing."), BY_SERVER);
+ else
+ Net::getPartyHandler()->create(args);
+ }
+ else if (type == "invite")
+ {
+ Net::getPartyHandler()->invite(args);
+ }
+ else if (type == "leave")
+ {
+ Net::getPartyHandler()->leave();
+ }
+ else if (type == "kick")
+ {
+ Net::getPartyHandler()->kick(args);
+ }
+ else if (type == "item")
+ {
+ if (args.empty())
+ {
+ switch (Net::getPartyHandler()->getShareItems())
+ {
+ case PARTY_SHARE:
+ chatLog(_("Item sharing enabled."), BY_SERVER);
+ return true;
+ case PARTY_SHARE_NO:
+ chatLog(_("Item sharing disabled."), BY_SERVER);
+ return true;
+ case PARTY_SHARE_NOT_POSSIBLE:
+ chatLog(_("Item sharing not possible."), BY_SERVER);
+ return true;
+ case PARTY_SHARE_UNKNOWN:
+ chatLog(_("Item sharing unknown."), BY_SERVER);
+ return true;
+ default:
+ break;
+ }
+ }
+
+ char opt = CommandHandler::parseBoolean(args);
+
+ switch (opt)
+ {
+ case 1:
+ Net::getPartyHandler()->setShareItems(PARTY_SHARE);
+ break;
+ case 0:
+ Net::getPartyHandler()->setShareItems(PARTY_SHARE_NO);
+ break;
+ case -1:
+ chatLog(strprintf(BOOLEAN_OPTIONS, "item"));
+ default:
+ break;
+ }
+ }
+ else if (type == "exp")
+ {
+ if (args.empty())
+ {
+ switch (Net::getPartyHandler()->getShareExperience())
+ {
+ case PARTY_SHARE:
+ chatLog(_("Experience sharing enabled."), BY_SERVER);
+ return true;
+ case PARTY_SHARE_NO:
+ chatLog(_("Experience sharing disabled."), BY_SERVER);
+ return true;
+ case PARTY_SHARE_NOT_POSSIBLE:
+ chatLog(_("Experience sharing not possible."), BY_SERVER);
+ return true;
+ case PARTY_SHARE_UNKNOWN:
+ chatLog(_("Experience sharing unknown."), BY_SERVER);
+ return true;
+ default:
+ break;
+ }
+ }
+
+ char opt = CommandHandler::parseBoolean(args);
+
+ switch (opt)
+ {
+ case 1:
+ Net::getPartyHandler()->setShareExperience(PARTY_SHARE);
+ break;
+ case 0:
+ Net::getPartyHandler()->setShareExperience(PARTY_SHARE_NO);
+ break;
+ case -1:
+ chatLog(strprintf(BOOLEAN_OPTIONS, "exp"));
+ default:
+ break;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void PartyTab::getAutoCompleteList(std::vector<std::string> &names) const
+{
+ if (!player_node)
+ return;
+
+ Party *p = player_node->getParty();
+
+ if (p)
+ p->getNames(names);
+}
+
+void PartyTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log("#Party", msg);
+}
+
+} // namespace TmwAthena
+
diff --git a/src/net/tmwa/gui/partytab.h b/src/net/tmwa/gui/partytab.h
new file mode 100644
index 000000000..d5f4436db
--- /dev/null
+++ b/src/net/tmwa/gui/partytab.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TA_PARTYTAB_H
+#define TA_PARTYTAB_H
+
+#include "gui/widgets/chattab.h"
+
+namespace TmwAthena
+{
+
+/**
+ * A tab for a party chat channel.
+ */
+class PartyTab : public ChatTab
+{
+ public:
+ PartyTab();
+ ~PartyTab();
+
+ void showHelp();
+
+ bool handleCommand(const std::string &type, const std::string &args);
+
+ int getType() const { return ChatTab::TAB_PARTY; }
+
+ void saveToLogFile(std::string &msg);
+
+ protected:
+ void handleInput(const std::string &msg);
+
+ virtual void getAutoCompleteList(std::vector<std::string>&) const;
+};
+
+extern PartyTab *partyTab;
+
+} // namespace TmwAthena
+
+#endif // TA_PARTYTAB_H
diff --git a/src/net/tmwa/guildhandler.cpp b/src/net/tmwa/guildhandler.cpp
new file mode 100644
index 000000000..88cd88009
--- /dev/null
+++ b/src/net/tmwa/guildhandler.cpp
@@ -0,0 +1,780 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/guildhandler.h"
+
+#include "actorspritemanager.h"
+#include "guild.h"
+#include "event.h"
+#include "localplayer.h"
+#include "log.h"
+#include "playerinfo.h"
+
+#include "gui/socialwindow.h"
+
+#include "net/tmwa/messagein.h"
+#include "net/tmwa/protocol.h"
+
+#include "net/tmwa/gui/guildtab.h"
+
+#include "utils/gettext.h"
+
+extern Net::GuildHandler *guildHandler;
+
+namespace TmwAthena
+{
+
+GuildTab *guildTab = 0;
+Guild *taGuild;
+bool showBasicInfo(false);
+
+GuildHandler::GuildHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_GUILD_CREATE_RESPONSE,
+ SMSG_GUILD_POSITION_INFO,
+ SMSG_GUILD_MEMBER_LOGIN,
+ SMSG_GUILD_MASTER_OR_MEMBER,
+ SMSG_GUILD_BASIC_INFO,
+ SMSG_GUILD_ALIANCE_INFO,
+ SMSG_GUILD_MEMBER_LIST,
+ SMSG_GUILD_POS_NAME_LIST,
+ SMSG_GUILD_POS_INFO_LIST,
+ SMSG_GUILD_POSITION_CHANGED,
+ SMSG_GUILD_MEMBER_POS_CHANGE,
+ SMSG_GUILD_EMBLEM,
+ SMSG_GUILD_SKILL_INFO,
+ SMSG_GUILD_NOTICE,
+ SMSG_GUILD_INVITE,
+ SMSG_GUILD_INVITE_ACK,
+ SMSG_GUILD_LEAVE,
+ SMSG_GUILD_EXPULSION,
+ SMSG_GUILD_EXPULSION_LIST,
+ SMSG_GUILD_MESSAGE,
+ SMSG_GUILD_SKILL_UP,
+ SMSG_GUILD_REQ_ALLIANCE,
+ SMSG_GUILD_REQ_ALLIANCE_ACK,
+ SMSG_GUILD_DEL_ALLIANCE,
+ SMSG_GUILD_OPPOSITION_ACK,
+ SMSG_GUILD_BROKEN,
+ 0
+ };
+ handledMessages = _messages;
+
+ guildHandler = this;
+}
+
+GuildHandler::~GuildHandler()
+{
+ delete guildTab;
+ guildTab = 0;
+}
+
+void GuildHandler::handleMessage(Net::MessageIn &msg)
+{
+ DEBUGLOG("guild message");
+
+ switch (msg.getId())
+ {
+ case SMSG_GUILD_CREATE_RESPONSE:
+ {
+ int flag = msg.readInt8();
+
+ if (flag == 0)
+ {
+ // Success
+ SERVER_NOTICE(_("Guild created."))
+ }
+ else if (flag == 1)
+ {
+ // Already in a guild
+ SERVER_NOTICE(_("You already in guild."))
+ }
+ else if (flag == 2)
+ {
+ // Unable to make (likely name already in use)
+ SERVER_NOTICE(_("You already in guild."))
+ }
+ else if (flag == 3)
+ {
+ // Emperium check failed
+ SERVER_NOTICE(_("Emperium check failed."))
+ }
+ else
+ {
+ // Unknown response
+ SERVER_NOTICE(_("Unknown server response."))
+ }
+ }
+ break;
+
+ case SMSG_GUILD_POSITION_INFO:
+ {
+ int guildId = msg.readInt32();
+ int emblem = msg.readInt32();
+ int posMode = msg.readInt32();
+ msg.readInt32(); // Unused
+ msg.readInt8(); // Unused
+ std::string guildName = msg.readString(24);
+
+ Guild *g = Guild::getGuild(guildId);
+ if (!g)
+ break;
+
+ g->setName(guildName);
+ g->setEmblemId(emblem);
+ if (!taGuild)
+ taGuild = g;
+ if (!guildTab && chatWindow)
+ {
+ guildTab = new GuildTab();
+ if (player_node)
+ player_node->addGuild(taGuild);
+ memberList(guildId);
+ }
+
+ if (player_node)
+ {
+ player_node->setGuild(g);
+ player_node->setGuildName(g->getName());
+ }
+
+ logger->log("Guild position info: %d %d %d %s\n", guildId,
+ emblem, posMode, guildName.c_str());
+ }
+ break;
+
+ case SMSG_GUILD_MEMBER_LOGIN:
+ {
+ int accountId = msg.readInt32(); // Account ID
+ int charId = msg.readInt32(); // Char ID
+ int online = msg.readInt32(); // Flag
+ if (taGuild)
+ {
+ GuildMember *m = taGuild->getMember(accountId, charId);
+ if (m)
+ m->setOnline(online);
+ }
+ break;
+ }
+
+ case SMSG_GUILD_MASTER_OR_MEMBER:
+ msg.readInt32(); // Type (0x57 for member, 0xd7 for master)
+ break;
+
+ case SMSG_GUILD_BASIC_INFO:
+ {
+ int guildId = msg.readInt32(); // Guild ID
+ int level = msg.readInt32(); // Guild level
+ int members = msg.readInt32(); // 'Connect member'
+ int maxMembers = msg.readInt32(); // 'Max member'
+ int avgLevel = msg.readInt32(); // Average level
+ int exp = msg.readInt32(); // Exp
+ int nextExp = msg.readInt32(); // Next exp
+ msg.skip(16); // unused
+ std::string name = msg.readString(24); // Name
+ std::string master = msg.readString(24); // Master's name
+ std::string castle = msg.readString(20); // Castles
+ // (ie: "Six Castles" or "None Taken")
+
+ if (guildTab && showBasicInfo)
+ {
+ showBasicInfo = false;
+ guildTab->chatLog(strprintf(
+ _("Guild name: %s"), name.c_str()), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Guild master: %s"), master.c_str()), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Guild level: %d"), level), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Online members: %d"), members), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Max members: %d"), maxMembers), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Average level: %d"), avgLevel), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Guild exp: %d"), exp), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Guild next exp: %d"), nextExp), BY_SERVER);
+ guildTab->chatLog(strprintf(
+ _("Guild castle: %s"), castle.c_str()), BY_SERVER);
+ }
+
+ Guild *g = Guild::getGuild(guildId);
+ if (!g)
+ break;
+ g->setName(name);
+ }
+ break;
+
+ case SMSG_GUILD_ALIANCE_INFO:
+ {
+ int length = msg.readInt16();
+ int count = (length - 4) / 32;
+
+ for (int i = 0; i < count; i++)
+ {
+ msg.readInt32(); // 'Opposition'
+ msg.readInt32(); // Other guild ID
+ msg.readString(24); // Other guild name
+ }
+ }
+ break;
+
+ case SMSG_GUILD_MEMBER_LIST:
+ {
+ int length = msg.readInt16();
+ int count = (length - 4) / 104;
+ if (!taGuild)
+ {
+ logger->log1("!taGuild");
+ break;
+ }
+
+ taGuild->clearMembers();
+
+ for (int i = 0; i < count; i++)
+ {
+ int id = msg.readInt32(); // Account ID
+ int charId = msg.readInt32(); // Char ID
+ msg.readInt16(); // Hair
+ msg.readInt16(); // Hair color
+ int gender = msg.readInt16(); // Gender
+ int race = msg.readInt16(); // Class
+ int level = msg.readInt16(); // Level
+ int exp = msg.readInt32(); // Exp
+ int online = msg.readInt32(); // Online
+ int pos = msg.readInt32(); // Position
+ msg.skip(50); // unused
+ std::string name = msg.readString(24); // Name
+
+ GuildMember *m = taGuild->addMember(id, charId, name);
+ if (m)
+ {
+ m->setOnline(online);
+ m->setID(id);
+ m->setCharId(charId);
+ if (!gender)
+ m->setGender(GENDER_FEMALE);
+ else if (gender == 1)
+ m->setGender(GENDER_MALE);
+ else
+ m->setGender(GENDER_UNSPECIFIED);
+
+ m->setLevel(level);
+ m->setExp(exp);
+ m->setPos(pos);
+ m->setRace(race);
+// m->setDisplayBold(!pos);
+ if (actorSpriteManager)
+ {
+ Being *being = actorSpriteManager->findBeingByName(
+ name, Being::PLAYER);
+ if (being)
+ {
+ being->setGuildName(taGuild->getName());
+ if (being->getLevel() != level)
+ {
+ being->setLevel(level);
+ being->updateName();
+ }
+ }
+ }
+ }
+ }
+ taGuild->sort();
+ if (actorSpriteManager)
+ {
+ actorSpriteManager->updatePlayerGuild();
+ actorSpriteManager->updatePlayerColors();
+ }
+ }
+ break;
+
+ case SMSG_GUILD_POS_NAME_LIST:
+ {
+ if (!taGuild)
+ {
+ logger->log1("!taGuild");
+ break;
+ }
+
+ int length = msg.readInt16();
+ int count = (length - 4) / 28;
+
+ for (int i = 0; i < count; i++)
+ {
+ int id = msg.readInt32(); // ID
+ std::string name = msg.readString(24); // Position name
+ taGuild->addPos(id, name);
+ }
+ }
+ break;
+
+ case SMSG_GUILD_POS_INFO_LIST:
+ {
+ int length = msg.readInt16();
+ int count = (length - 4) / 16;
+
+ for (int i = 0; i < count; i++)
+ {
+ msg.readInt32(); // ID
+ msg.readInt32(); // Mode
+ msg.readInt32(); // Same ID
+ msg.readInt32(); // Exp mode
+ }
+ }
+ break;
+
+ case SMSG_GUILD_POSITION_CHANGED:
+ msg.readInt16(); // Always 44
+ msg.readInt32(); // ID
+ msg.readInt32(); // Mode
+ msg.readInt32(); // Same ID
+ msg.readInt32(); // Exp mode
+ msg.readString(24); // Name
+ break;
+
+ case SMSG_GUILD_MEMBER_POS_CHANGE:
+ {
+ msg.readInt16(); // Always 16
+ int accountId = msg.readInt32(); // Account ID
+ int charId = msg.readInt32(); // Char ID
+ int pos = msg.readInt32(); // Position
+ if (taGuild)
+ {
+ GuildMember *m = taGuild->getMember(accountId, charId);
+ if (m)
+ m->setPos(pos);
+ }
+ break;
+ }
+
+ case SMSG_GUILD_EMBLEM:
+ {
+ int length = msg.readInt16();
+
+ msg.readInt32(); // Guild ID
+ msg.readInt32(); // Emblem ID
+ msg.skip(length - 12); // Emblem data (unknown format)
+ }
+ break;
+
+ case SMSG_GUILD_SKILL_INFO:
+ {
+ int length = msg.readInt16();
+ int count = (length - 6) / 37;
+
+ msg.readInt16(); // 'Skill point'
+
+ for (int i = 0; i < count; i++)
+ {
+ msg.readInt16(); // ID
+ msg.readInt16(); // 'Info' (unknown atm)
+ msg.readInt16(); // unused
+ msg.readInt16(); // Level
+ msg.readInt16(); // SP
+ msg.readInt16(); // 'Range'
+ msg.skip(24); // unused
+ msg.readInt8(); // Can be increased
+ }
+ }
+ break;
+
+ case SMSG_GUILD_NOTICE:
+ {
+ std::string msg1 = msg.readString(60); // Mes1
+ std::string msg2 = msg.readString(120); // Mes2
+ if (guildTab)
+ {
+ guildTab->chatLog(msg1, BY_SERVER);
+ guildTab->chatLog(msg2, BY_SERVER);
+ }
+ break;
+ }
+
+ case SMSG_GUILD_INVITE:
+ {
+ int guildId = msg.readInt32();
+ std::string guildName = msg.readString(24);
+
+ if (socialWindow)
+ socialWindow->showGuildInvite(guildName, guildId, "");
+ break;
+ }
+
+ case SMSG_GUILD_INVITE_ACK:
+ {
+ int flag = msg.readInt8();
+ if (!guildTab)
+ break;
+
+ switch (flag)
+ {
+ case 0:
+ guildTab->chatLog(_("Could not inivte user to guild."),
+ BY_SERVER);
+ break;
+
+ case 1:
+ guildTab->chatLog(_("User rejected guild invite."),
+ BY_SERVER);
+ break;
+
+ case 2:
+ guildTab->chatLog(_("User is now part of your guild."),
+ BY_SERVER);
+ break;
+
+ case 3:
+ guildTab->chatLog(_("Your guild is full."),
+ BY_SERVER);
+ break;
+
+ default:
+ guildTab->chatLog(_("Unknown guild invite response."),
+ BY_SERVER);
+ break;
+ }
+ }
+ break;
+
+ case SMSG_GUILD_LEAVE:
+ {
+ std::string nick = msg.readString(24); // Name
+ std::string message = msg.readString(40); // Message
+
+ if (taGuild)
+ taGuild->removeMember(nick);
+
+ if (player_node && nick == player_node->getName())
+ {
+ if (taGuild)
+ {
+ taGuild->removeFromMembers();
+ taGuild->clearMembers();
+ }
+ SERVER_NOTICE(_("You have left the guild."))
+ delete guildTab;
+ guildTab = 0;
+
+ if (socialWindow && taGuild)
+ socialWindow->removeTab(taGuild);
+ if (actorSpriteManager)
+ actorSpriteManager->updatePlayerColors();
+ }
+ else
+ {
+ if (guildTab)
+ {
+ guildTab->chatLog(strprintf(
+ _("%s has left your guild."),
+ nick.c_str()), BY_SERVER);
+ }
+ if (actorSpriteManager)
+ {
+ Being *b = actorSpriteManager->findBeingByName(
+ nick, Being::PLAYER);
+
+ if (b)
+ b->clearGuilds();
+ if (taGuild)
+ taGuild->removeMember(nick);
+ }
+ }
+ break;
+ }
+
+ case SMSG_GUILD_EXPULSION:
+ {
+ std::string nick = msg.readString(24); // Name (of expulsed?)
+ std::string message = msg.readString(40); // Message
+ msg.skip(24); // unused ("dummy")
+ if (taGuild)
+ taGuild->removeMember(nick);
+
+ if (player_node && nick == player_node->getName())
+ {
+ if (taGuild)
+ {
+ taGuild->removeFromMembers();
+ taGuild->clearMembers();
+ }
+ SERVER_NOTICE(_("You was kicked from guild."));
+ delete guildTab;
+ guildTab = 0;
+
+ if (socialWindow && taGuild)
+ socialWindow->removeTab(taGuild);
+ if (actorSpriteManager)
+ actorSpriteManager->updatePlayerColors();
+ }
+ else
+ {
+ if (guildTab)
+ {
+ guildTab->chatLog(strprintf(
+ _("%s has kicked from your guild."),
+ nick.c_str()), BY_SERVER);
+ }
+
+ if (actorSpriteManager)
+ {
+ Being *b = actorSpriteManager->findBeingByName(
+ nick, Being::PLAYER);
+
+ if (b)
+ b->clearGuilds();
+ if (taGuild)
+ taGuild->removeMember(nick);
+ }
+ }
+ break;
+ }
+
+ case SMSG_GUILD_EXPULSION_LIST:
+ {
+ int length = msg.readInt16();
+ int count = (length - 4) / 88;
+
+ for (int i = 0; i < count; i++)
+ {
+ msg.readString(24); // Name (of expulsed?)
+ msg.readString(24); // 'Acc' (name of expulser?)
+ msg.readString(24); // Message
+ }
+ }
+ break;
+
+ case SMSG_GUILD_MESSAGE:
+ {
+ int msgLength = msg.readInt16() - 4;
+
+ if (msgLength <= 0)
+ return;
+ if (guildTab)
+ {
+ std::string chatMsg = msg.readString(msgLength);
+
+ std::string::size_type pos = chatMsg.find(" : ", 0);
+ if (pos != std::string::npos)
+ {
+ std::string sender_name = ((pos == std::string::npos)
+ ? "" : chatMsg.substr(0, pos));
+
+ chatMsg.erase(0, pos + 3);
+
+ trim(chatMsg);
+ guildTab->chatLog(sender_name, chatMsg);
+ }
+ else
+ {
+ guildTab->chatLog(chatMsg);
+ }
+ }
+ }
+ break;
+
+ case SMSG_GUILD_SKILL_UP:
+ msg.readInt16(); // Skill ID
+ msg.readInt16(); // Level
+ msg.readInt16(); // SP
+ msg.readInt16(); // 'Range'
+ msg.readInt8(); // unused? (always 1)
+ break;
+
+ case SMSG_GUILD_REQ_ALLIANCE:
+ msg.readInt32(); // Account ID
+ msg.readString(24); // Name
+ break;
+
+ case SMSG_GUILD_REQ_ALLIANCE_ACK:
+ msg.readInt32(); // Flag
+ break;
+
+ case SMSG_GUILD_DEL_ALLIANCE:
+ msg.readInt32(); // Guild ID
+ msg.readInt32(); // Flag
+ break;
+
+ case SMSG_GUILD_OPPOSITION_ACK:
+ msg.readInt8(); // Flag
+ break;
+
+ case SMSG_GUILD_BROKEN:
+ msg.readInt32(); // Flag
+ break;
+
+ default:
+ break;
+ }
+}
+
+void GuildHandler::create(const std::string &name)
+{
+ MessageOut msg(CMSG_GUILD_CREATE);
+ msg.writeInt32(0); // Unused
+ msg.writeString(name, 24);
+}
+
+void GuildHandler::invite(int guildId _UNUSED_,
+ const std::string &name _UNUSED_)
+{
+ if (!actorSpriteManager)
+ return;
+
+ Being* being = actorSpriteManager->findBeingByName(name, Being::PLAYER);
+ if (being)
+ {
+ MessageOut msg(CMSG_GUILD_INVITE);
+ msg.writeInt32(being->getId());
+ msg.writeInt32(0); // Unused
+ msg.writeInt32(0); // Unused
+ }
+}
+
+void GuildHandler::invite(int guildId _UNUSED_, Being *being)
+{
+ if (!being)
+ return;
+
+ MessageOut msg(CMSG_GUILD_INVITE);
+ msg.writeInt32(being->getId());
+ msg.writeInt32(0); // Unused
+ msg.writeInt32(0); // Unused
+}
+
+void GuildHandler::inviteResponse(int guildId, bool response)
+{
+ MessageOut msg(CMSG_GUILD_INVITE_REPLY);
+ msg.writeInt32(guildId);
+ msg.writeInt8(response);
+ msg.writeInt8(0); // Unused
+ msg.writeInt16(0); // Unused
+}
+
+void GuildHandler::leave(int guildId)
+{
+ if (!player_node)
+ return;
+
+ MessageOut msg(CMSG_GUILD_LEAVE);
+ msg.writeInt32(guildId);
+ msg.writeInt32(player_node->getId()); // Account ID
+ msg.writeInt32(PlayerInfo::getCharId()); // Char ID
+ msg.writeString("", 40); // Message
+}
+
+void GuildHandler::kick(GuildMember *member, std::string reason)
+{
+ if (!member || !member->getGuild())
+ return;
+
+ MessageOut msg(CMSG_GUILD_EXPULSION);
+ msg.writeInt32(member->getGuild()->getId());
+ msg.writeInt32(member->getID()); // Account ID
+ msg.writeInt32(member->getCharId()); // Char ID
+ msg.writeString(reason, 40); // Message
+}
+
+void GuildHandler::chat(int guildId _UNUSED_, const std::string &text)
+{
+ if (!player_node)
+ return;
+
+ std::string str = player_node->getName() + " : " + text;
+ MessageOut msg(CMSG_GUILD_MESSAGE);
+ msg.writeInt16(str.size() + 4);
+ msg.writeString(str, str.length());
+}
+
+void GuildHandler::memberList(int guildId _UNUSED_)
+{
+ // TODO four types of info requests:
+ // 0 = basic info + alliance info
+ // 1 = position name list + member list
+ // 2 = position name list + position info list
+ // 3 = skill info
+ // 4 = expulsion list
+
+ MessageOut msg(CMSG_GUILD_REQUEST_INFO);
+ msg.writeInt32(1); // Request member list
+}
+
+void GuildHandler::info(int guildId _UNUSED_)
+{
+ // TODO four types of info requests:
+ // 0 = basic info + alliance info
+ // 1 = position name list + member list
+ // 2 = position name list + position info list
+ // 3 = skill info
+ // 4 = expulsion list
+
+ showBasicInfo = true;
+ MessageOut msg(CMSG_GUILD_REQUEST_INFO);
+ msg.writeInt32(0); // Request basic info
+}
+
+void GuildHandler::changeMemberPostion(GuildMember *member, int level)
+{
+ if (!member || !member->getGuild())
+ return;
+
+ MessageOut msg(CMSG_GUILD_CHANGE_MEMBER_POS);
+ msg.writeInt16(16); // size less then 16 <= 4 + 12
+ msg.writeInt32(member->getID()); // Account ID
+ msg.writeInt32(member->getCharId()); // Char ID
+ msg.writeInt32(level); // pos
+}
+
+void GuildHandler::requestAlliance(int guildId _UNUSED_,
+ int otherGuildId _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::requestAllianceResponse(int guildId _UNUSED_,
+ int otherGuildId _UNUSED_,
+ bool response _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::endAlliance(int guildId _UNUSED_, int otherGuildId _UNUSED_)
+{
+ // TODO
+}
+
+void GuildHandler::changeNotice(int guildId, std::string msg1,
+ std::string msg2)
+{
+ MessageOut msg(CMSG_GUILD_CHANGE_NOTICE);
+ msg.writeInt32(guildId);
+ msg.writeString(msg1, 60); // msg1
+ msg.writeString(msg2, 120); // msg2
+}
+
+bool GuildHandler::isSupported()
+{
+ return true;
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/guildhandler.h b/src/net/tmwa/guildhandler.h
new file mode 100644
index 000000000..80b03bd01
--- /dev/null
+++ b/src/net/tmwa/guildhandler.h
@@ -0,0 +1,84 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_GUILDHANDLER_H
+#define NET_TA_GUILDHANDLER_H
+
+#include "net/guildhandler.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class GuildHandler : public Net::GuildHandler, public MessageHandler
+{
+ public:
+ GuildHandler();
+
+ ~GuildHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void create(const std::string &name);
+
+ void invite(int guildId, const std::string &name);
+
+ void invite(int guildId, Being *being);
+
+ void inviteResponse(int guildId, bool response);
+
+ void leave(int guildId);
+
+ void kick(GuildMember *member, std::string reason = "");
+
+ void chat(int guildId, const std::string &text);
+
+ void memberList(int guildId);
+
+ void info(int guildId _UNUSED_);
+
+ void changeMemberPostion(GuildMember *member, int level);
+
+ void requestAlliance(int guildId, int otherGuildId);
+
+ void requestAllianceResponse(int guildId, int otherGuildId,
+ bool response);
+
+ void endAlliance(int guildId, int otherGuildId);
+
+ void changeNotice(int guildId, std::string msg1, std::string msg2);
+
+ bool isSupported();
+
+ private:
+ // TmwAthena (and eAthena) only supports one guild per player
+ Guild *mGuild;
+};
+
+}
+
+#endif // NET_TA_GUILDHANDLER_H
diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp
new file mode 100644
index 000000000..b4b38e623
--- /dev/null
+++ b/src/net/tmwa/inventoryhandler.cpp
@@ -0,0 +1,609 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/inventoryhandler.h"
+
+#include "configuration.h"
+#include "equipment.h"
+#include "event.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <SDL_types.h>
+
+extern Net::InventoryHandler *inventoryHandler;
+
+const Equipment::Slot EQUIP_POINTS[Equipment::EQUIP_VECTOREND] =
+{
+ Equipment::EQUIP_LEGS_SLOT,
+ Equipment::EQUIP_FIGHT1_SLOT,
+ Equipment::EQUIP_GLOVES_SLOT,
+ Equipment::EQUIP_RING2_SLOT,
+ Equipment::EQUIP_RING1_SLOT,
+ Equipment::EQUIP_FIGHT2_SLOT,
+ Equipment::EQUIP_FEET_SLOT,
+ Equipment::EQUIP_NECK_SLOT,
+ Equipment::EQUIP_HEAD_SLOT,
+ Equipment::EQUIP_TORSO_SLOT,
+ Equipment::EQUIP_EVOL_RING1_SLOT,
+ Equipment::EQUIP_EVOL_RING2_SLOT,
+ Equipment::EQUIP_PROJECTILE_SLOT,
+};
+
+const Equipment::Slot EQUIP_CONVERT[] =
+{
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+ Equipment::EQUIP_FEET_SLOT, // SPRITE_SHOE
+ Equipment::EQUIP_LEGS_SLOT, // SPRITE_BOTTOMCLOTHES
+ Equipment::EQUIP_TORSO_SLOT, // SPRITE_TOPCLOTHES
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+ Equipment::EQUIP_HEAD_SLOT, // SPRITE_HAT
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+ Equipment::EQUIP_GLOVES_SLOT, // SPRITE_GLOVES
+ Equipment::EQUIP_FIGHT1_SLOT, // SPRITE_WEAPON
+ Equipment::EQUIP_FIGHT2_SLOT, // SPRITE_SHIELD
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+ Equipment::EQUIP_PROJECTILE_SLOT, // 0
+};
+
+namespace TmwAthena
+{
+
+int getSlot(int eAthenaSlot);
+
+int getSlot(int eAthenaSlot)
+{
+ if (eAthenaSlot == 0)
+ return Equipment::EQUIP_VECTOREND;
+
+ if (eAthenaSlot & 0x8000)
+ return Equipment::EQUIP_PROJECTILE_SLOT;
+
+ int mask = 1;
+ int position = 0;
+ while (!(eAthenaSlot & mask))
+ {
+ mask <<= 1;
+ position++;
+ }
+ return EQUIP_POINTS[position];
+}
+
+enum
+{
+ debugInventory = 1
+};
+
+InventoryHandler::InventoryHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_PLAYER_INVENTORY,
+ SMSG_PLAYER_INVENTORY_ADD,
+ SMSG_PLAYER_INVENTORY_REMOVE,
+ SMSG_PLAYER_INVENTORY_USE,
+ SMSG_ITEM_USE_RESPONSE,
+ SMSG_PLAYER_STORAGE_ITEMS,
+ SMSG_PLAYER_STORAGE_EQUIP,
+ SMSG_PLAYER_STORAGE_STATUS,
+ SMSG_PLAYER_STORAGE_ADD,
+ SMSG_PLAYER_STORAGE_REMOVE,
+ SMSG_PLAYER_STORAGE_CLOSE,
+ SMSG_PLAYER_EQUIPMENT,
+ SMSG_PLAYER_EQUIP,
+ SMSG_PLAYER_UNEQUIP,
+ SMSG_PLAYER_ARROW_EQUIP,
+ SMSG_PLAYER_ATTACK_RANGE,
+ 0
+ };
+ handledMessages = _messages;
+ inventoryHandler = this;
+
+ mStorage = 0;
+ mStorageWindow = 0;
+}
+
+InventoryHandler::~InventoryHandler()
+{
+ if (mStorageWindow)
+ {
+ mStorageWindow->close();
+ mStorageWindow = 0;
+ }
+
+ delete mStorage;
+ mStorage = 0;
+}
+
+void InventoryHandler::handleMessage(Net::MessageIn &msg)
+{
+ int number, flag;
+ int index, amount, itemId, equipType, arrow, refine;
+ int identified, cards[4], itemType;
+ Inventory *inventory = 0;
+ if (player_node)
+ inventory = PlayerInfo::getInventory();
+
+ switch (msg.getId())
+ {
+ case SMSG_PLAYER_INVENTORY:
+ case SMSG_PLAYER_STORAGE_ITEMS:
+ if (msg.getId() == SMSG_PLAYER_INVENTORY)
+ {
+ // Clear inventory - this will be a complete refresh
+ mEquips.clear();
+ PlayerInfo::getEquipment()->setBackend(&mEquips);
+
+ if (inventory)
+ inventory->clear();
+ }
+ else
+ {
+ mInventoryItems.clear();
+ }
+
+ msg.readInt16(); // length
+ number = (msg.getLength() - 4) / 18;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ index = msg.readInt16();
+ itemId = msg.readInt16();
+ itemType = msg.readInt8();
+ identified = msg.readInt8();
+ amount = msg.readInt16();
+ arrow = msg.readInt16();
+ for (int i = 0; i < 4; i++)
+ cards[i] = msg.readInt16();
+
+ index -= (msg.getId() == SMSG_PLAYER_INVENTORY) ?
+ INVENTORY_OFFSET : STORAGE_OFFSET;
+
+ if (debugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
+ "Qty: %d, Cards: %d, %d, %d, %d",
+ index, itemId, itemType, identified, amount,
+ cards[0], cards[1], cards[2], cards[3]);
+ }
+
+ if (msg.getId() == SMSG_PLAYER_INVENTORY)
+ {
+ // Trick because arrows are not considered equipment
+ bool isEquipment = arrow & 0x8000;
+
+ if (inventory)
+ {
+ inventory->setItem(index, itemId, amount,
+ 0, isEquipment);
+ }
+ }
+ else
+ {
+ mInventoryItems.push_back(InventoryItem(index, itemId,
+ amount, 0, false));
+ }
+ }
+ break;
+
+ case SMSG_PLAYER_STORAGE_EQUIP:
+ msg.readInt16(); // length
+ number = (msg.getLength() - 4) / 20;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ index = msg.readInt16() - STORAGE_OFFSET;
+ itemId = msg.readInt16();
+ itemType = msg.readInt8();
+ identified = msg.readInt8();
+ amount = 1;
+ msg.readInt16(); // Equip Point?
+ msg.readInt16(); // Another Equip Point?
+ msg.readInt8(); // Attribute (broken)
+ refine = msg.readInt8();
+ for (int i = 0; i < 4; i++)
+ cards[i] = msg.readInt16();
+
+ if (debugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
+ "Qty: %d, Cards: %d, %d, %d, %d, Refine: %d",
+ index, itemId, itemType, identified, amount,
+ cards[0], cards[1], cards[2], cards[3],
+ refine);
+ }
+
+ mInventoryItems.push_back(InventoryItem(index, itemId, amount,
+ refine, false));
+ }
+ break;
+
+ case SMSG_PLAYER_INVENTORY_ADD:
+ index = msg.readInt16() - INVENTORY_OFFSET;
+ amount = msg.readInt16();
+ itemId = msg.readInt16();
+ identified = msg.readInt8();
+ msg.readInt8(); // attribute
+ refine = msg.readInt8();
+ for (int i = 0; i < 4; i++)
+ cards[i] = msg.readInt16();
+ equipType = msg.readInt16();
+ itemType = msg.readInt8();
+
+ {
+ const ItemInfo &itemInfo = ItemDB::get(itemId);
+
+ if (msg.readInt8() > 0)
+ {
+ if (player_node)
+ player_node->pickedUp(itemInfo, 0);
+ }
+ else
+ {
+ if (player_node)
+ player_node->pickedUp(itemInfo, amount);
+
+ if (inventory)
+ {
+ Item *item = inventory->getItem(index);
+
+ if (item && item->getId() == itemId)
+ amount += inventory->getItem(index)->getQuantity();
+
+ inventory->setItem(index, itemId, amount, refine,
+ equipType != 0);
+ }
+ }
+ } break;
+
+ case SMSG_PLAYER_INVENTORY_REMOVE:
+ index = msg.readInt16() - INVENTORY_OFFSET;
+ amount = msg.readInt16();
+ if (inventory)
+ {
+ if (Item *item = inventory->getItem(index))
+ {
+ item->increaseQuantity(-amount);
+ if (item->getQuantity() == 0)
+ inventory->removeItemAt(index);
+ }
+ }
+ break;
+
+ case SMSG_PLAYER_INVENTORY_USE:
+ index = msg.readInt16() - INVENTORY_OFFSET;
+ msg.readInt16(); // item id
+ msg.readInt32(); // id
+ amount = msg.readInt16();
+ msg.readInt8(); // type
+
+ if (inventory)
+ {
+ if (Item *item = inventory->getItem(index))
+ {
+ if (amount)
+ item->setQuantity(amount);
+ else
+ inventory->removeItemAt(index);
+ }
+ }
+ break;
+
+ case SMSG_ITEM_USE_RESPONSE:
+ index = msg.readInt16() - INVENTORY_OFFSET;
+ amount = msg.readInt16();
+
+ if (msg.readInt8() == 0)
+ {
+ SERVER_NOTICE(_("Failed to use item."))
+ }
+ else
+ {
+ if (inventory)
+ {
+ if (Item *item = inventory->getItem(index))
+ {
+ if (amount)
+ item->setQuantity(amount);
+ else
+ inventory->removeItemAt(index);
+ }
+ }
+ }
+ break;
+
+ case SMSG_PLAYER_STORAGE_STATUS:
+ /*
+ * This is the closest we get to an "Open Storage" packet from the
+ * server. It always comes after the two SMSG_PLAYER_STORAGE_...
+ * packets that update storage contents.
+ */
+ {
+ msg.readInt16(); // Used count
+ int size = msg.readInt16(); // Max size
+
+ if (!mStorage)
+ mStorage = new Inventory(Inventory::STORAGE, size);
+
+ InventoryItems::iterator it = mInventoryItems.begin();
+ InventoryItems::iterator it_end = mInventoryItems.end();
+ for (; it != it_end; it++)
+ mStorage->setItem((*it).slot, (*it).id, (*it).quantity,
+ (*it).equip);
+ mInventoryItems.clear();
+
+ if (!mStorageWindow)
+ mStorageWindow = new InventoryWindow(mStorage);
+ }
+ break;
+
+ case SMSG_PLAYER_STORAGE_ADD:
+ // Move an item into storage
+ index = msg.readInt16() - STORAGE_OFFSET;
+ amount = msg.readInt32();
+ itemId = msg.readInt16();
+ identified = msg.readInt8();
+ msg.readInt8(); // attribute
+ refine = msg.readInt8();
+ for (int i = 0; i < 4; i++)
+ cards[i] = msg.readInt16();
+
+ if (Item *item = mStorage->getItem(index))
+ {
+ item->setId(itemId);
+ item->increaseQuantity(amount);
+ }
+ else
+ {
+ if (mStorage)
+ mStorage->setItem(index, itemId, amount, false);
+ }
+ break;
+
+ case SMSG_PLAYER_STORAGE_REMOVE:
+ // Move an item out of storage
+ index = msg.readInt16() - STORAGE_OFFSET;
+ amount = msg.readInt16();
+ if (mStorage)
+ {
+ if (Item *item = mStorage->getItem(index))
+ {
+ item->increaseQuantity(-amount);
+ if (item->getQuantity() == 0)
+ mStorage->removeItemAt(index);
+ }
+ }
+ break;
+
+ case SMSG_PLAYER_STORAGE_CLOSE:
+ // Storage access has been closed
+
+ // Storage window deletes itself
+ mStorageWindow = 0;
+
+ if (mStorage)
+ mStorage->clear();
+
+ delete mStorage;
+ mStorage = 0;
+ break;
+
+ case SMSG_PLAYER_EQUIPMENT:
+ msg.readInt16(); // length
+ number = (msg.getLength() - 4) / 20;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ index = msg.readInt16() - INVENTORY_OFFSET;
+ itemId = msg.readInt16();
+ msg.readInt8(); // type
+ msg.readInt8(); // identify flag
+ msg.readInt16(); // equip type
+ equipType = msg.readInt16();
+ msg.readInt8(); // attribute
+ refine = msg.readInt8();
+ msg.skip(8); // card
+
+ if (inventory)
+ inventory->setItem(index, itemId, 1, refine, true);
+
+ if (equipType)
+ mEquips.setEquipment(getSlot(equipType), index);
+ }
+ break;
+
+ case SMSG_PLAYER_EQUIP:
+ index = msg.readInt16() - INVENTORY_OFFSET;
+ equipType = msg.readInt16();
+ flag = msg.readInt8();
+
+ if (!flag)
+ SERVER_NOTICE(_("Unable to equip."))
+ else
+ mEquips.setEquipment(getSlot(equipType), index);
+ break;
+
+ case SMSG_PLAYER_UNEQUIP:
+ index = msg.readInt16() - INVENTORY_OFFSET;
+ equipType = msg.readInt16();
+ flag = msg.readInt8();
+
+ if (flag)
+ mEquips.setEquipment(getSlot(equipType), -1);
+ break;
+
+ case SMSG_PLAYER_ATTACK_RANGE:
+ {
+ int range = msg.readInt16();
+ if (player_node)
+ player_node->setAttackRange(range);
+ PlayerInfo::setStatBase(ATTACK_RANGE, range);
+ PlayerInfo::setStatMod(ATTACK_RANGE, 0);
+ break;
+ }
+
+ case SMSG_PLAYER_ARROW_EQUIP:
+ index = msg.readInt16();
+
+ if (index <= 1)
+ break;
+
+ index -= INVENTORY_OFFSET;
+
+ logger->log("Arrows equipped: %i", index);
+ mEquips.setEquipment(Equipment::EQUIP_PROJECTILE_SLOT, index);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void InventoryHandler::equipItem(const Item *item)
+{
+ if (!item)
+ return;
+
+ MessageOut outMsg(CMSG_PLAYER_EQUIP);
+ outMsg.writeInt16(static_cast<Sint16>(
+ item->getInvIndex() + INVENTORY_OFFSET));
+ outMsg.writeInt16(0);
+}
+
+void InventoryHandler::unequipItem(const Item *item)
+{
+ if (!item)
+ return;
+
+ MessageOut outMsg(CMSG_PLAYER_UNEQUIP);
+ outMsg.writeInt16(static_cast<Sint16>(
+ item->getInvIndex() + INVENTORY_OFFSET));
+}
+
+void InventoryHandler::useItem(const Item *item)
+{
+ if (!item)
+ return;
+
+ MessageOut outMsg(CMSG_PLAYER_INVENTORY_USE);
+ outMsg.writeInt16(static_cast<Sint16>(
+ item->getInvIndex() + INVENTORY_OFFSET));
+ outMsg.writeInt32(item->getId()); // unused
+}
+
+void InventoryHandler::dropItem(const Item *item, int amount)
+{
+ if (!item)
+ return;
+
+ // TODO: Fix wrong coordinates of drops, serverside? (what's wrong here?)
+ MessageOut outMsg(CMSG_PLAYER_INVENTORY_DROP);
+ outMsg.writeInt16(static_cast<Sint16>(
+ item->getInvIndex() + INVENTORY_OFFSET));
+ outMsg.writeInt16(static_cast<Sint16>(amount));
+}
+
+bool InventoryHandler::canSplit(const Item *item _UNUSED_)
+{
+ return false;
+}
+
+void InventoryHandler::splitItem(const Item *item _UNUSED_,
+ int amount _UNUSED_)
+{
+ // Not implemented for eAthena (possible?)
+}
+
+void InventoryHandler::moveItem(int oldIndex _UNUSED_, int newIndex _UNUSED_)
+{
+ // Not implemented for eAthena (possible?)
+}
+
+void InventoryHandler::openStorage(int type _UNUSED_)
+{
+ // Doesn't apply to eAthena, since opening happens through NPCs?
+}
+
+void InventoryHandler::closeStorage(int type _UNUSED_)
+{
+ MessageOut outMsg(CMSG_CLOSE_STORAGE);
+}
+
+void InventoryHandler::moveItem(int source, int slot, int amount,
+ int destination)
+{
+ if (source == Inventory::INVENTORY && destination == Inventory::STORAGE)
+ {
+ MessageOut outMsg(CMSG_MOVE_TO_STORAGE);
+ outMsg.writeInt16(slot + INVENTORY_OFFSET);
+ outMsg.writeInt32(amount);
+ }
+ else if (source == Inventory::STORAGE
+ && destination == Inventory::INVENTORY)
+ {
+ MessageOut outMsg(CSMG_MOVE_FROM_STORAGE);
+ outMsg.writeInt16(slot + STORAGE_OFFSET);
+ outMsg.writeInt32(amount);
+ }
+}
+
+size_t InventoryHandler::getSize(int type) const
+{
+ switch (type)
+ {
+ case Inventory::INVENTORY:
+ return 100;
+ case Inventory::STORAGE:
+ return 0; // Comes from server after items
+ case Inventory::TRADE:
+ return 12;
+ case GUILD_STORAGE:
+ return 0; // Comes from server after items
+ default:
+ return 0;
+ }
+}
+int InventoryHandler::convertFromServerSlot(int serverSlot)
+{
+ if (serverSlot < 0 || serverSlot > 13)
+ return 0;
+
+ return EQUIP_CONVERT[serverSlot];
+}
+} // namespace TmwAthena
diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h
new file mode 100644
index 000000000..1a10b6ba0
--- /dev/null
+++ b/src/net/tmwa/inventoryhandler.h
@@ -0,0 +1,177 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_INVENTORYHANDLER_H
+#define NET_TA_INVENTORYHANDLER_H
+
+#include "equipment.h"
+#include "inventory.h"
+#include "playerinfo.h"
+
+#include "gui/inventorywindow.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#include <list>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class EquipBackend : public Equipment::Backend
+{
+ public:
+ EquipBackend()
+ {
+ memset(mEquipment, -1, sizeof(mEquipment));
+ }
+
+ Item *getEquipment(int index) const
+ {
+ int invyIndex = mEquipment[index];
+ if (invyIndex == -1)
+ {
+ return NULL;
+ }
+ return PlayerInfo::getInventory()->getItem(invyIndex);
+ }
+
+ void clear()
+ {
+ for (int i = 0; i < EQUIPMENT_SIZE; i++)
+ {
+ if (mEquipment[i] != -1)
+ {
+ Item* item = PlayerInfo::getInventory()->getItem(i);
+ if (item)
+ {
+ item->setEquipped(false);
+ }
+ }
+
+ mEquipment[i] = -1;
+ }
+ }
+
+ void setEquipment(int index, int inventoryIndex)
+ {
+ // Unequip existing item
+ Item* item = PlayerInfo::getInventory()
+ ->getItem(mEquipment[index]);
+
+ if (item)
+ item->setEquipped(false);
+
+ mEquipment[index] = inventoryIndex;
+
+ item = PlayerInfo::getInventory()->getItem(inventoryIndex);
+ if (item)
+ item->setEquipped(true);
+ }
+
+ private:
+ int mEquipment[EQUIPMENT_SIZE];
+};
+
+/**
+ * Used to cache storage data until we get size data for it.
+ */
+class InventoryItem
+{
+ public:
+ int slot;
+ int id;
+ int quantity;
+ int refine;
+ bool equip;
+
+ InventoryItem(int slot, int id, int quantity, int refine, bool equip)
+ {
+ this->slot = slot;
+ this->id = id;
+ this->quantity = quantity;
+ this->refine = refine;
+ this->equip = equip;
+ }
+};
+
+typedef std::list<InventoryItem> InventoryItems;
+
+class InventoryHandler : public MessageHandler, public Net::InventoryHandler
+{
+ public:
+ enum
+ {
+ GUILD_STORAGE = Inventory::TYPE_END,
+ CART
+ };
+
+ InventoryHandler();
+
+ ~InventoryHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void equipItem(const Item *item);
+
+ void unequipItem(const Item *item);
+
+ void useItem(const Item *item);
+
+ void dropItem(const Item *item, int amount);
+
+ bool canSplit(const Item *item);
+
+ void splitItem(const Item *item, int amount);
+
+ void moveItem(int oldIndex, int newIndex);
+
+ void openStorage(int type);
+
+ void closeStorage(int type);
+
+ void moveItem(int source, int slot, int amount,
+ int destination);
+
+ size_t getSize(int type) const;
+
+ int convertFromServerSlot(int serverSlot);
+
+ private:
+ EquipBackend mEquips;
+ InventoryItems mInventoryItems;
+ Inventory *mStorage;
+ InventoryWindow *mStorageWindow;
+};
+
+} // namespace TmwAthena
+
+int getSlot(int eAthenaSlot);
+
+#endif // NET_TA_INVENTORYHANDLER_H
diff --git a/src/net/tmwa/itemhandler.cpp b/src/net/tmwa/itemhandler.cpp
new file mode 100644
index 000000000..7ae124646
--- /dev/null
+++ b/src/net/tmwa/itemhandler.cpp
@@ -0,0 +1,93 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/itemhandler.h"
+
+#include "actorspritemanager.h"
+
+#include "net/messagein.h"
+
+#include "net/tmwa/protocol.h"
+
+namespace TmwAthena
+{
+
+ItemHandler::ItemHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_ITEM_VISIBLE,
+ SMSG_ITEM_DROPPED,
+ SMSG_ITEM_REMOVE,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void ItemHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case SMSG_ITEM_VISIBLE:
+ case SMSG_ITEM_DROPPED:
+ {
+ int id = msg.readInt32();
+ int itemId = msg.readInt16();
+ msg.readInt8(); // identify flag
+ int x = msg.readInt16();
+ int y = msg.readInt16();
+// msg.skip(4); // amount,subX,subY / subX,subY,amount
+ int amount1 = msg.readInt16();
+ int amount2 = msg.readInt16();
+
+ if (actorSpriteManager)
+ {
+ if (msg.getId() == SMSG_ITEM_VISIBLE)
+ {
+ actorSpriteManager->createItem(id, itemId,
+ x, y, amount1);
+ }
+ else
+ {
+ actorSpriteManager->createItem(id, itemId,
+ x, y, amount2);
+ }
+ }
+ }
+ break;
+
+ case SMSG_ITEM_REMOVE:
+ if (actorSpriteManager)
+ {
+ if (FloorItem *item = actorSpriteManager->findItem(
+ msg.readInt32()))
+ {
+ actorSpriteManager->destroy(item);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/itemhandler.h b/src/net/tmwa/itemhandler.h
new file mode 100644
index 000000000..0f740fe58
--- /dev/null
+++ b/src/net/tmwa/itemhandler.h
@@ -0,0 +1,40 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_ITEMHANDLER_H
+#define NET_TA_ITEMHANDLER_H
+
+#include "net/tmwa/messagehandler.h"
+
+namespace TmwAthena
+{
+
+class ItemHandler : public MessageHandler
+{
+ public:
+ ItemHandler();
+
+ virtual void handleMessage(Net::MessageIn &msg);
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_ITEMHANDLER_H
diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp
new file mode 100644
index 000000000..73fec1322
--- /dev/null
+++ b/src/net/tmwa/loginhandler.cpp
@@ -0,0 +1,342 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/loginhandler.h"
+
+#include "client.h"
+#include "log.h"
+#include "configuration.h"
+
+#include "net/logindata.h"
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/network.h"
+#include "net/tmwa/protocol.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern Net::LoginHandler *loginHandler;
+
+namespace TmwAthena
+{
+
+extern ServerInfo charServer;
+
+LoginHandler::LoginHandler():
+ mVersionResponse(false),
+ mRegistrationEnabled(true)
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_UPDATE_HOST,
+ SMSG_LOGIN_DATA,
+ SMSG_LOGIN_ERROR,
+ SMSG_CHAR_PASSWORD_RESPONSE,
+ SMSG_SERVER_VERSION_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+ loginHandler = this;
+}
+
+LoginHandler::~LoginHandler()
+{
+ delete_all(mWorlds);
+}
+
+void LoginHandler::handleMessage(Net::MessageIn &msg)
+{
+ int code, worldCount;
+
+ switch (msg.getId())
+ {
+ case SMSG_CHAR_PASSWORD_RESPONSE:
+ {
+ // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short
+ int errMsg = msg.readInt8();
+ // Successful pass change
+ if (errMsg == 1)
+ {
+ Client::setState(STATE_CHANGEPASSWORD_SUCCESS);
+ }
+ // pass change failed
+ else
+ {
+ switch (errMsg)
+ {
+ case 0:
+ errorMessage =
+ _("Account was not found. Please re-login.");
+ break;
+ case 2:
+ errorMessage = _("Old password incorrect.");
+ break;
+ case 3:
+ errorMessage = _("New password too short.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ Client::setState(STATE_ACCOUNTCHANGE_ERROR);
+ }
+ }
+ break;
+
+ case SMSG_UPDATE_HOST:
+ int len;
+
+ len = msg.readInt16() - 4;
+ mUpdateHost = msg.readString(len);
+ loginData.updateHost = mUpdateHost;
+
+ logger->log("Received update host \"%s\" from login server.",
+ mUpdateHost.c_str());
+ break;
+
+ case SMSG_LOGIN_DATA:
+ // Skip the length word
+ msg.skip(2);
+
+ clearWorlds();
+
+ worldCount = (msg.getLength() - 47) / 32;
+
+ mToken.session_ID1 = msg.readInt32();
+ mToken.account_ID = msg.readInt32();
+ mToken.session_ID2 = msg.readInt32();
+ msg.skip(30); // unknown
+ mToken.sex = msg.readInt8() ? GENDER_MALE : GENDER_FEMALE;
+
+ for (int i = 0; i < worldCount; i++)
+ {
+ WorldInfo *world = new WorldInfo;
+
+ world->address = msg.readInt32();
+ world->port = msg.readInt16();
+ world->name = msg.readString(20);
+ world->online_users = msg.readInt32();
+ config.setValue("updatehost", mUpdateHost);
+ world->updateHost = mUpdateHost;
+ msg.skip(2); // unknown
+
+ logger->log("Network: Server: %s (%s:%d)",
+ world->name.c_str(),
+ ipToString(world->address),
+ world->port);
+
+ mWorlds.push_back(world);
+ }
+ Client::setState(STATE_WORLD_SELECT);
+ break;
+
+ case SMSG_LOGIN_ERROR:
+ code = msg.readInt8();
+ logger->log("Login::error code: %i", code);
+
+ switch (code)
+ {
+ case 0:
+ errorMessage = _("Unregistered ID.");
+ break;
+ case 1:
+ errorMessage = _("Wrong password.");
+ break;
+ case 2:
+ errorMessage = _("Account expired.");
+ break;
+ case 3:
+ errorMessage = _("Rejected from server.");
+ break;
+ case 4:
+ errorMessage = _("You have been permanently banned from "
+ "the game. Please contact the GM team.");
+ break;
+ case 6:
+ errorMessage = strprintf(_("You have been temporarily "
+ "banned from the game until "
+ "%s.\nPlease contact the GM "
+ "team via the forums."),
+ msg.readString(20).c_str());
+ break;
+ case 9:
+ errorMessage = _("This user name is already taken.");
+ break;
+ default:
+ errorMessage = _("Unknown error.");
+ break;
+ }
+ Client::setState(STATE_ERROR);
+ break;
+
+ case SMSG_SERVER_VERSION_RESPONSE:
+ {
+ // TODO: verify these!
+
+ msg.readInt8(); // -1
+ msg.readInt8(); // T
+ msg.readInt8(); // M
+ msg.readInt8(); // W
+
+ unsigned int options = msg.readInt32();
+
+ mRegistrationEnabled = options;
+// mRegistrationEnabled = (options & 1);
+
+ // Leave this last
+ mVersionResponse = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void LoginHandler::connect()
+{
+ if (!mNetwork)
+ return;
+
+ mNetwork->connect(mServer);
+ MessageOut outMsg(CMSG_SERVER_VERSION_REQUEST);
+}
+
+bool LoginHandler::isConnected()
+{
+ if (!mNetwork)
+ return false;
+
+ return mVersionResponse && mNetwork->isConnected();
+}
+
+void LoginHandler::disconnect()
+{
+ if (mNetwork && mNetwork->getServer() == mServer)
+ mNetwork->disconnect();
+}
+
+bool LoginHandler::isRegistrationEnabled()
+{
+ return mRegistrationEnabled;
+}
+
+void LoginHandler::getRegistrationDetails()
+{
+ // Not supported, so move on
+ Client::setState(STATE_REGISTER);
+}
+
+void LoginHandler::loginAccount(LoginData *loginData)
+{
+
+ if (loginData)
+ {
+ // Since we're attempting to use the tAthena protocol,
+ // let's reset the character slots to the good value,
+ // in case we just logged out a Manaserv server
+ // with a different config.
+ loginData->resetCharacterSlots();
+
+ sendLoginRegister(loginData->username, loginData->password);
+ }
+}
+
+void LoginHandler::logout()
+{
+ // TODO
+}
+
+void LoginHandler::changeEmail(const std::string &email _UNUSED_)
+{
+ // TODO
+}
+
+void LoginHandler::changePassword(const std::string &username _UNUSED_,
+ const std::string &oldPassword,
+ const std::string &newPassword)
+{
+ MessageOut outMsg(CMSG_CHAR_PASSWORD_CHANGE);
+ outMsg.writeString(oldPassword, 24);
+ outMsg.writeString(newPassword, 24);
+}
+
+void LoginHandler::chooseServer(unsigned int server)
+{
+ if (server >= mWorlds.size() || !mWorlds[server])
+ return;
+
+ charServer.clear();
+ charServer.hostname = ipToString(mWorlds[server]->address);
+ charServer.port = mWorlds[server]->port;
+
+ Client::setState(STATE_UPDATE);
+}
+
+void LoginHandler::registerAccount(LoginData *loginData)
+{
+ if (!loginData)
+ return;
+
+ std::string username = loginData->username;
+ username.append((loginData->gender == GENDER_FEMALE) ? "_F" : "_M");
+
+ sendLoginRegister(username, loginData->password);
+}
+
+void LoginHandler::unregisterAccount(const std::string &username _UNUSED_,
+ const std::string &password _UNUSED_)
+{
+ // TODO
+}
+
+void LoginHandler::sendLoginRegister(const std::string &username,
+ const std::string &password)
+{
+ MessageOut outMsg(0x0064);
+ outMsg.writeInt32(0); // client version
+ outMsg.writeString(username, 24);
+ outMsg.writeString(password, 24);
+
+ /*
+ * eAthena calls the last byte "client version 2", but it isn't used at
+ * at all. We're retasking it, as a bit mask:
+ * 0 - can handle the 0x63 "update host" packet
+ * 1 - defaults to the first char-server (instead of the last)
+ */
+ outMsg.writeInt8(0x03);
+}
+
+Worlds LoginHandler::getWorlds() const
+{
+ return mWorlds;
+}
+
+void LoginHandler::clearWorlds()
+{
+ delete_all(mWorlds);
+ mWorlds.clear();
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h
new file mode 100644
index 000000000..977b4ce0a
--- /dev/null
+++ b/src/net/tmwa/loginhandler.h
@@ -0,0 +1,105 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TMWA_LOGINHANDLER_H
+#define NET_TMWA_LOGINHANDLER_H
+
+#include "net/loginhandler.h"
+
+#include "net/tmwa/messagehandler.h"
+#include "net/tmwa/token.h"
+
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+struct LoginData;
+
+namespace TmwAthena
+{
+
+class LoginHandler : public MessageHandler, public Net::LoginHandler
+{
+ public:
+ LoginHandler();
+
+ ~LoginHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
+ int supportedOptionalActions() const
+ { return SetGenderOnRegister; }
+
+ bool isRegistrationEnabled();
+
+ void getRegistrationDetails();
+
+ unsigned int getMaxPasswordLength() const
+ { return 25; }
+
+ void loginAccount(LoginData *loginData);
+
+ void logout();
+
+ void changeEmail(const std::string &email);
+
+ void changePassword(const std::string &username,
+ const std::string &oldPassword,
+ const std::string &newPassword);
+
+ void chooseServer(unsigned int server);
+
+ void registerAccount(LoginData *loginData);
+
+ void unregisterAccount(const std::string &username,
+ const std::string &password);
+
+ Worlds getWorlds() const;
+
+ void clearWorlds();
+
+ const Token &getToken() const
+ { return mToken; }
+
+ private:
+ void sendLoginRegister(const std::string &username,
+ const std::string &password);
+
+ bool mVersionResponse;
+ bool mRegistrationEnabled;
+ std::string mUpdateHost;
+ Worlds mWorlds;
+ Token mToken;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_LOGINHANDLER_H
diff --git a/src/net/tmwa/messagehandler.cpp b/src/net/tmwa/messagehandler.cpp
new file mode 100644
index 000000000..85a0caeae
--- /dev/null
+++ b/src/net/tmwa/messagehandler.cpp
@@ -0,0 +1,48 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/messagehandler.h"
+
+#include "net/tmwa/network.h"
+
+#include <cassert>
+
+namespace TmwAthena
+{
+
+MessageHandler::MessageHandler()
+ : mNetwork(NULL)
+{
+}
+
+MessageHandler::~MessageHandler()
+{
+ if (mNetwork)
+ mNetwork->unregisterHandler(this);
+}
+
+void MessageHandler::setNetwork(Network *network)
+{
+ assert(!(network && mNetwork));
+ mNetwork = network;
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/messagehandler.h b/src/net/tmwa/messagehandler.h
new file mode 100644
index 000000000..d4b0c8094
--- /dev/null
+++ b/src/net/tmwa/messagehandler.h
@@ -0,0 +1,59 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_MESSAGEHANDLER_H
+#define NET_TA_MESSAGEHANDLER_H
+
+#include "net/messagehandler.h"
+#include "net/messagein.h"
+
+#include "net/tmwa/messageout.h"
+
+#include <SDL_types.h>
+
+#include <memory>
+
+namespace TmwAthena
+{
+
+class Network;
+
+/**
+ * \ingroup Network
+ */
+class MessageHandler : public Net::MessageHandler
+{
+ public:
+ MessageHandler();
+
+ ~MessageHandler();
+
+ void setNetwork(Network *network);
+
+ protected:
+ Network *mNetwork;
+};
+
+typedef const std::auto_ptr<MessageHandler> MessageHandlerPtr;
+
+}
+
+#endif // NET_TA_MESSAGEHANDLER_H
diff --git a/src/net/tmwa/messagein.cpp b/src/net/tmwa/messagein.cpp
new file mode 100644
index 000000000..23f5e09c1
--- /dev/null
+++ b/src/net/tmwa/messagein.cpp
@@ -0,0 +1,85 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/messagein.h"
+
+#include "net/packetcounters.h"
+
+#include "log.h"
+
+#include "utils/stringutils.h"
+
+#include <SDL.h>
+#include <SDL_endian.h>
+
+#define MAKEWORD(low, high) \
+ ((unsigned short)(((unsigned char)(low)) | \
+ ((unsigned short)((unsigned char)(high))) << 8))
+
+namespace TmwAthena
+{
+
+MessageIn::MessageIn(const char *data, unsigned int length):
+ Net::MessageIn(data, length)
+{
+ // Read the message ID
+ mId = readInt16();
+}
+
+Sint16 MessageIn::readInt16()
+{
+ Sint16 value = -1;
+ if (mPos + 2 <= mLength)
+ {
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Sint16 swap;
+ memcpy(&swap, mData + mPos, sizeof(Sint16));
+ value = SDL_Swap16(swap);
+#else
+ memcpy(&value, mData + mPos, sizeof(Sint16));
+#endif
+ }
+ mPos += 2;
+ PacketCounters::incInBytes(2);
+ DEBUGLOG("readInt16: " + toString((int)value));
+ return value;
+}
+
+int MessageIn::readInt32()
+{
+ Sint32 value = -1;
+ if (mPos + 4 <= mLength)
+ {
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Sint32 swap;
+ memcpy(&swap, mData + mPos, sizeof(Sint32));
+ value = SDL_Swap32(swap);
+#else
+ memcpy(&value, mData + mPos, sizeof(Sint32));
+#endif
+ }
+ mPos += 4;
+ PacketCounters::incInBytes(4);
+ DEBUGLOG(strprintf("readInt32: %u", value));
+ return value;
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/messagein.h b/src/net/tmwa/messagein.h
new file mode 100644
index 000000000..b3dedc7af
--- /dev/null
+++ b/src/net/tmwa/messagein.h
@@ -0,0 +1,52 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_MESSAGEIN_H
+#define NET_TA_MESSAGEIN_H
+
+#include "net/messagein.h"
+
+#include <SDL_types.h>
+#include <string>
+
+namespace TmwAthena
+{
+
+/**
+ * Used for parsing an incoming message.
+ *
+ * \ingroup Network
+ */
+ class MessageIn : public Net::MessageIn
+{
+ public:
+ /**
+ * Constructor.
+ */
+ MessageIn(const char *data, unsigned int length);
+
+ Sint16 readInt16(); /**< Reads a short. */
+ int readInt32(); /**< Reads a long. */
+};
+
+}
+
+#endif // NET_TA_MESSAGEIN_H
diff --git a/src/net/tmwa/messageout.cpp b/src/net/tmwa/messageout.cpp
new file mode 100644
index 000000000..42d4f582c
--- /dev/null
+++ b/src/net/tmwa/messageout.cpp
@@ -0,0 +1,142 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/messageout.h"
+
+#include "net/packetcounters.h"
+
+#include "net/tmwa/network.h"
+
+#include "log.h"
+
+#include "utils/stringutils.h"
+
+#include <SDL.h>
+#include <SDL_endian.h>
+
+#include <cstring>
+#include <string>
+
+namespace TmwAthena
+{
+
+MessageOut::MessageOut(short id):
+ Net::MessageOut(id)
+{
+ mNetwork = TmwAthena::Network::instance();
+ mData = mNetwork->mOutBuffer + mNetwork->mOutSize;
+ writeInt16(id);
+}
+
+void MessageOut::expand(size_t bytes)
+{
+ mNetwork->mOutSize += static_cast<unsigned>(bytes);
+ PacketCounters::incOutBytes(static_cast<int>(bytes));
+}
+
+void MessageOut::writeInt16(Sint16 value)
+{
+ DEBUGLOG("writeInt16: " + toString((int)value));
+ expand(2);
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Sint16 swap = SDL_Swap16(value);
+ memcpy(mData + mPos, &swap, sizeof(Sint16));
+#else
+ memcpy(mData + mPos, &value, sizeof(Sint16));
+#endif
+ mPos += 2;
+ PacketCounters::incOutBytes(2);
+}
+
+void MessageOut::writeInt32(Sint32 value)
+{
+ DEBUGLOG("writeInt32: " + toString(value));
+ expand(4);
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Sint32 swap = SDL_Swap32(value);
+ memcpy(mData + mPos, &swap, sizeof(Sint32));
+#else
+ memcpy(mData + mPos, &value, sizeof(Sint32));
+#endif
+ mPos += 4;
+ PacketCounters::incOutBytes(4);
+}
+
+#define LOBYTE(w) ((unsigned char)(w))
+#define HIBYTE(w) ((unsigned char)(((unsigned short)(w)) >> 8))
+
+void MessageOut::writeCoordinates(unsigned short x, unsigned short y,
+ unsigned char direction)
+{
+ DEBUGLOG(strprintf("writeCoordinates: %u,%u %u", x, y, direction));
+ char *data = mData + mPos;
+ mNetwork->mOutSize += 3;
+ mPos += 3;
+
+ short temp;
+ temp = x;
+ temp <<= 6;
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 2;
+ data[0] = HIBYTE(temp);
+ data[1] = (unsigned char) temp;
+ temp = y;
+ temp <<= 4;
+ data[1] |= HIBYTE(temp);
+ data[2] = LOBYTE(temp);
+
+ // Translate direction to eAthena format
+ switch (direction)
+ {
+ case 1:
+ direction = 0;
+ break;
+ case 3:
+ direction = 1;
+ break;
+ case 2:
+ direction = 2;
+ break;
+ case 6:
+ direction = 3;
+ break;
+ case 4:
+ direction = 4;
+ break;
+ case 12:
+ direction = 5;
+ break;
+ case 8:
+ direction = 6;
+ break;
+ case 9:
+ direction = 7;
+ break;
+ default:
+ // OOPSIE! Impossible or unknown
+ direction = (unsigned char) -1;
+ }
+ data[2] |= direction;
+ PacketCounters::incOutBytes(3);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/messageout.h b/src/net/tmwa/messageout.h
new file mode 100644
index 000000000..ae0fc9a49
--- /dev/null
+++ b/src/net/tmwa/messageout.h
@@ -0,0 +1,65 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_MESSAGEOUT_H
+#define NET_TA_MESSAGEOUT_H
+
+#include "net/messageout.h"
+
+#include <iosfwd>
+#include <SDL_types.h>
+
+namespace TmwAthena
+{
+
+class Network;
+
+/**
+ * Used for building an outgoing message.
+ *
+ * \ingroup Network
+ */
+class MessageOut : public Net::MessageOut
+{
+ public:
+ /**
+ * Constructor.
+ */
+ MessageOut(short id);
+
+ void writeInt16(Sint16 value); /**< Writes a short. */
+ void writeInt32(Sint32 value); /**< Writes a long. */
+
+ /**
+ * Encodes coordinates and direction in 3 bytes.
+ */
+ void writeCoordinates(unsigned short x, unsigned short y,
+ unsigned char direction);
+
+ private:
+ void expand(size_t size);
+
+ Network *mNetwork;
+};
+
+}
+
+#endif // NET_TA_MESSAGEOUT_H
diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp
new file mode 100644
index 000000000..7aa9ad7d2
--- /dev/null
+++ b/src/net/tmwa/network.cpp
@@ -0,0 +1,483 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/network.h"
+
+#include "log.h"
+
+#include "net/messagehandler.h"
+#include "net/messagein.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <assert.h>
+#include <sstream>
+
+/** Warning: buffers and other variables are shared,
+ so there can be only one connection active at a time */
+
+short packet_lengths[] =
+{
+ 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// #0x0040
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 50, 3, -1, 55, 17, 3, 37, 46, -1, 23, -1, 3, 108, 3, 2,
+ 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
+// #0x0080
+ 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0,
+ 7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6,
+ 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
+ 8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3,
+// #0x00C0
+ 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27,
+ 3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1,
+ 30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2,
+ 3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10,
+// #0x0100
+ 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1,
+ 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16,
+ 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1,
+ 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26,
+// #0x0140
+ 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6,
+ 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42,
+ -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14, 186, 182,
+ 14, 30, 10, 3, -1, 6, 106, -1, 4, 5, 4, -1, 6, 7, -1, -1,
+// #0x0180
+ 6, 3, 106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6,
+ 90, 86, 24, 6, 30, 102, 9, 4, 8, 4, 14, 10, 4, 6, 2, 6,
+ 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
+ 11, 7, -1, 67, 12, 18, 114, 6, 3, 6, 26, 26, 26, 26, 2, 3,
+// #0x01C0
+ 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 29, 6, 28,
+ 8, 14, 10, 35, 6, 8, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6,
+ 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1,
+ -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10,
+// #0x2000
+ 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 10, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+const unsigned int BUFFER_SIZE = 655360;
+
+namespace TmwAthena
+{
+
+int networkThread(void *data)
+{
+ Network *network = static_cast<Network*>(data);
+
+ if (!network || !network->realConnect())
+ return -1;
+
+ network->receive();
+
+ return 0;
+}
+
+Network *Network::mInstance = 0;
+
+Network::Network():
+ mSocket(0),
+ mInBuffer(new char[BUFFER_SIZE]),
+ mOutBuffer(new char[BUFFER_SIZE]),
+ mInSize(0), mOutSize(0),
+ mToSkip(0),
+ mState(IDLE),
+ mWorkerThread(0)
+{
+ SDLNet_Init();
+
+ mMutex = SDL_CreateMutex();
+ mInstance = this;
+}
+
+Network::~Network()
+{
+ clearHandlers();
+
+ if (mState != IDLE && mState != NET_ERROR)
+ disconnect();
+
+ SDL_DestroyMutex(mMutex);
+ mInstance = 0;
+
+ delete[] mInBuffer;
+ delete[] mOutBuffer;
+
+ SDLNet_Quit();
+}
+
+bool Network::connect(ServerInfo server)
+{
+ if (mState != IDLE && mState != NET_ERROR)
+ {
+ logger->log1("Tried to connect an already connected socket!");
+ assert(false);
+ return false;
+ }
+
+ if (server.hostname.empty())
+ {
+ setError(_("Empty address given to Network::connect()!"));
+ return false;
+ }
+
+ logger->log("Network::Connecting to %s:%i", server.hostname.c_str(),
+ server.port);
+
+ mServer.hostname = server.hostname;
+ mServer.port = server.port;
+
+ // Reset to sane values
+ mOutSize = 0;
+ mInSize = 0;
+ mToSkip = 0;
+
+ mState = CONNECTING;
+ mWorkerThread = SDL_CreateThread(networkThread, this);
+ if (!mWorkerThread)
+ {
+ setError("Unable to create network worker thread");
+ return false;
+ }
+
+ return true;
+}
+
+void Network::disconnect()
+{
+ mState = IDLE;
+
+ if (mWorkerThread && SDL_GetThreadID(mWorkerThread))
+ {
+ SDL_WaitThread(mWorkerThread, NULL);
+ mWorkerThread = NULL;
+ }
+
+ if (mSocket)
+ {
+ // need call SDLNet_TCP_DelSocket?
+ SDLNet_TCP_Close(mSocket);
+ mSocket = 0;
+ }
+}
+
+void Network::registerHandler(MessageHandler *handler)
+{
+ if (!handler)
+ return;
+
+ for (const Uint16 *i = handler->handledMessages; *i; ++i)
+ mMessageHandlers[*i] = handler;
+
+ handler->setNetwork(this);
+}
+
+void Network::unregisterHandler(MessageHandler *handler)
+{
+ if (!handler)
+ return;
+
+ for (const Uint16 *i = handler->handledMessages; *i; ++i)
+ mMessageHandlers.erase(*i);
+
+ handler->setNetwork(0);
+}
+
+void Network::clearHandlers()
+{
+ MessageHandlerIterator i;
+ for (i = mMessageHandlers.begin(); i != mMessageHandlers.end(); ++i)
+ {
+ if (i->second)
+ i->second->setNetwork(0);
+ }
+ mMessageHandlers.clear();
+}
+
+void Network::dispatchMessages()
+{
+ while (messageReady())
+ {
+ MessageIn msg = getNextMessage();
+
+ MessageHandlerIterator iter = mMessageHandlers.find(msg.getId());
+
+ if (msg.getLength() == 0)
+ logger->error("Zero length packet received. Exiting.");
+
+ if (iter != mMessageHandlers.end())
+ {
+ if (iter->second)
+ iter->second->handleMessage(msg);
+ }
+ else
+ {
+ logger->log("Unhandled packet: %x", msg.getId());
+ }
+
+ skip(msg.getLength());
+ }
+}
+
+void Network::flush()
+{
+ if (!mOutSize || mState != CONNECTED)
+ return;
+
+ int ret;
+
+ SDL_mutexP(mMutex);
+ ret = SDLNet_TCP_Send(mSocket, mOutBuffer, mOutSize);
+ if (ret < (int)mOutSize)
+ {
+ setError("Error in SDLNet_TCP_Send(): " +
+ std::string(SDLNet_GetError()));
+ }
+ mOutSize = 0;
+ SDL_mutexV(mMutex);
+}
+
+void Network::skip(int len)
+{
+ SDL_mutexP(mMutex);
+ mToSkip += len;
+ if (!mInSize)
+ {
+ SDL_mutexV(mMutex);
+ return;
+ }
+
+ if (mInSize >= mToSkip)
+ {
+ mInSize -= mToSkip;
+ memmove(mInBuffer, mInBuffer + mToSkip, mInSize);
+ mToSkip = 0;
+ }
+ else
+ {
+ mToSkip -= mInSize;
+ mInSize = 0;
+ }
+ SDL_mutexV(mMutex);
+}
+
+bool Network::messageReady()
+{
+ int len = -1, msgId;
+
+ SDL_mutexP(mMutex);
+ if (mInSize >= 2)
+ {
+ msgId = readWord(0);
+ if (msgId == SMSG_SERVER_VERSION_RESPONSE)
+ len = 10;
+ else
+ len = packet_lengths[msgId];
+
+ if (len == -1 && mInSize > 4)
+ len = readWord(2);
+
+ }
+
+ bool ret = (mInSize >= static_cast<unsigned int>(len));
+ SDL_mutexV(mMutex);
+
+ return ret;
+}
+
+MessageIn Network::getNextMessage()
+{
+ while (!messageReady())
+ {
+ if (mState == NET_ERROR)
+ break;
+ }
+
+ SDL_mutexP(mMutex);
+ int msgId = readWord(0);
+ int len;
+ if (msgId == SMSG_SERVER_VERSION_RESPONSE)
+ len = 10;
+ else
+ len = packet_lengths[msgId];
+
+ if (len == -1)
+ len = readWord(2);
+
+#ifdef DEBUG
+ logger->log("Received packet 0x%x of length %d\n", msgId, len);
+#endif
+
+ MessageIn msg(mInBuffer, len);
+ SDL_mutexV(mMutex);
+
+ return msg;
+}
+
+bool Network::realConnect()
+{
+ IPaddress ipAddress;
+
+ if (SDLNet_ResolveHost(&ipAddress, mServer.hostname.c_str(),
+ mServer.port) == -1)
+ {
+ std::string errorMessage = _("Unable to resolve host \"") +
+ mServer.hostname + "\"";
+ setError(errorMessage);
+ logger->log("SDLNet_ResolveHost: %s", errorMessage.c_str());
+ return false;
+ }
+
+ mState = CONNECTING;
+
+ mSocket = SDLNet_TCP_Open(&ipAddress);
+ if (!mSocket)
+ {
+ logger->log("Error in SDLNet_TCP_Open(): %s", SDLNet_GetError());
+ setError(SDLNet_GetError());
+ return false;
+ }
+
+ logger->log("Network::Started session with %s:%i",
+ ipToString(ipAddress.host), ipAddress.port);
+
+ mState = CONNECTED;
+
+ return true;
+}
+
+void Network::receive()
+{
+ SDLNet_SocketSet set;
+
+ if (!(set = SDLNet_AllocSocketSet(1)))
+ {
+ setError("Error in SDLNet_AllocSocketSet(): " +
+ std::string(SDLNet_GetError()));
+ return;
+ }
+
+ if (SDLNet_TCP_AddSocket(set, mSocket) == -1)
+ {
+ setError("Error in SDLNet_AddSocket(): " +
+ std::string(SDLNet_GetError()));
+ }
+
+ while (mState == CONNECTED)
+ {
+ // TODO Try to get this to block all the time while still being able
+ // to escape the loop
+ int numReady = SDLNet_CheckSockets(set, ((Uint32)500));
+ int ret;
+ switch (numReady)
+ {
+ case -1:
+ logger->log1("Error: SDLNet_CheckSockets");
+ // FALLTHROUGH
+ case 0:
+ break;
+
+ case 1:
+ // Receive data from the socket
+ SDL_mutexP(mMutex);
+ ret = SDLNet_TCP_Recv(mSocket, mInBuffer + mInSize,
+ BUFFER_SIZE - mInSize);
+
+ if (!ret)
+ {
+ // We got disconnected
+ mState = IDLE;
+ logger->log1("Disconnected.");
+ }
+ else if (ret < 0)
+ {
+ setError(_("Connection to server terminated. ") +
+ std::string(SDLNet_GetError()));
+ }
+ else
+ {
+ mInSize += ret;
+ if (mToSkip)
+ {
+ if (mInSize >= mToSkip)
+ {
+ mInSize -= mToSkip;
+ memmove(mInBuffer, mInBuffer + mToSkip, mInSize);
+ mToSkip = 0;
+ }
+ else
+ {
+ mToSkip -= mInSize;
+ mInSize = 0;
+ }
+ }
+ }
+ SDL_mutexV(mMutex);
+ break;
+
+ default:
+ // more than one socket is ready..
+ // this should not happen since we only listen once socket.
+ std::stringstream errorStream;
+ errorStream << "Error in SDLNet_TCP_Recv(), " << numReady
+ << " sockets are ready: " << SDLNet_GetError();
+ setError(errorStream.str());
+ break;
+ }
+ }
+
+ if (SDLNet_TCP_DelSocket(set, mSocket) == -1)
+ logger->log("Error in SDLNet_DelSocket(): %s", SDLNet_GetError());
+
+ SDLNet_FreeSocketSet(set);
+}
+
+Network *Network::instance()
+{
+ return mInstance;
+}
+
+void Network::setError(const std::string &error)
+{
+ logger->log("Network error: %s", error.c_str());
+ mError = error;
+ mState = NET_ERROR;
+}
+
+Uint16 Network::readWord(int pos)
+{
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ return SDL_Swap16((*(Uint16*)(mInBuffer + (pos))));
+#else
+ return (*(Uint16*)(mInBuffer + (pos)));
+#endif
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/network.h b/src/net/tmwa/network.h
new file mode 100644
index 000000000..bdafd6a09
--- /dev/null
+++ b/src/net/tmwa/network.h
@@ -0,0 +1,136 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_NETWORK_H
+#define NET_TA_NETWORK_H
+
+#include "net/serverinfo.h"
+
+#include "net/tmwa/messagehandler.h"
+#include "net/tmwa/messagein.h"
+#include "net/tmwa/messageout.h"
+
+#include <SDL_net.h>
+#include <SDL_thread.h>
+
+#include <map>
+#include <string>
+
+/**
+ * Protocol version, reported to the eAthena char and mapserver who can adjust
+ * the protocol accordingly.
+ */
+#define CLIENT_PROTOCOL_VERSION 1
+
+namespace TmwAthena
+{
+
+class Network
+{
+ public:
+ Network();
+
+ ~Network();
+
+ bool connect(ServerInfo server);
+
+ void disconnect();
+
+ ServerInfo getServer() const
+ { return mServer; }
+
+ void registerHandler(MessageHandler *handler);
+
+ void unregisterHandler(MessageHandler *handler);
+
+ void clearHandlers();
+
+ int getState() const
+ { return mState; }
+
+ const std::string &getError() const
+ { return mError; }
+
+ bool isConnected() const
+ { return mState == CONNECTED; }
+
+ int getInSize() const
+ { return mInSize; }
+
+ void skip(int len);
+
+ bool messageReady();
+
+ MessageIn getNextMessage();
+
+ void dispatchMessages();
+
+ void flush();
+
+ // ERROR replaced by NET_ERROR because already defined in Windows
+ enum
+ {
+ IDLE = 0,
+ CONNECTED,
+ CONNECTING,
+ DATA,
+ NET_ERROR
+ };
+
+ protected:
+ friend int networkThread(void *data);
+ friend class MessageOut;
+
+ static Network *instance();
+
+ void setError(const std::string &error);
+
+ Uint16 readWord(int pos);
+
+ bool realConnect();
+
+ void receive();
+
+ TCPsocket mSocket;
+
+ ServerInfo mServer;
+
+ char *mInBuffer, *mOutBuffer;
+ unsigned int mInSize, mOutSize;
+
+ unsigned int mToSkip;
+
+ int mState;
+ std::string mError;
+
+ SDL_Thread *mWorkerThread;
+ SDL_mutex *mMutex;
+
+ typedef std::map<Uint16, MessageHandler*> MessageHandlers;
+ typedef MessageHandlers::iterator MessageHandlerIterator;
+ MessageHandlers mMessageHandlers;
+
+ static Network *mInstance;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_NETWORK_H
diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp
new file mode 100644
index 000000000..84fe1789c
--- /dev/null
+++ b/src/net/tmwa/npchandler.cpp
@@ -0,0 +1,249 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/npchandler.h"
+
+#include "actorspritemanager.h"
+#include "localplayer.h"
+
+#include "gui/npcdialog.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+
+#include "net/tmwa/protocol.h"
+
+#include <SDL_types.h>
+
+extern Net::NpcHandler *npcHandler;
+
+namespace TmwAthena
+{
+
+NpcHandler::NpcHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_NPC_CHOICE,
+ SMSG_NPC_MESSAGE,
+ SMSG_NPC_NEXT,
+ SMSG_NPC_CLOSE,
+ SMSG_NPC_INT_INPUT,
+ SMSG_NPC_STR_INPUT,
+ 0
+ };
+ handledMessages = _messages;
+ npcHandler = this;
+}
+
+void NpcHandler::handleMessage(Net::MessageIn &msg)
+{
+ if (msg.getId() == SMSG_NPC_CHOICE || msg.getId() == SMSG_NPC_MESSAGE)
+ msg.readInt16(); // length
+
+ int npcId = msg.readInt32();
+ NpcDialogs::iterator diag = mNpcDialogs.find(npcId);
+ NpcDialog *dialog = 0;
+
+ if (diag == mNpcDialogs.end())
+ {
+ // Empty dialogs don't help
+ if (msg.getId() == SMSG_NPC_CLOSE)
+ {
+ closeDialog(npcId);
+ return;
+ }
+ else if (msg.getId() == SMSG_NPC_NEXT)
+ {
+ nextDialog(npcId);
+ return;
+ }
+ else
+ {
+ dialog = new NpcDialog(npcId);
+ Wrapper wrap;
+ wrap.dialog = dialog;
+ mNpcDialogs[npcId] = wrap;
+ }
+ }
+ else
+ {
+ dialog = diag->second.dialog;
+ }
+
+ switch (msg.getId())
+ {
+ case SMSG_NPC_CHOICE:
+ if (dialog)
+ {
+ dialog->choiceRequest();
+ dialog->parseListItems(msg.readString(msg.getLength() - 8));
+ }
+ else
+ {
+ msg.readString(msg.getLength() - 8);
+ }
+ break;
+
+ case SMSG_NPC_MESSAGE:
+ if (dialog)
+ dialog->addText(msg.readString(msg.getLength() - 8));
+ else
+ msg.readString(msg.getLength() - 8);
+ break;
+
+ case SMSG_NPC_CLOSE:
+ // Show the close button
+ if (dialog)
+ dialog->showCloseButton();
+ break;
+
+ case SMSG_NPC_NEXT:
+ // Show the next button
+ if (dialog)
+ dialog->showNextButton();
+ break;
+
+ case SMSG_NPC_INT_INPUT:
+ // Request for an integer
+ if (dialog)
+ dialog->integerRequest(0);
+ break;
+
+ case SMSG_NPC_STR_INPUT:
+ // Request for a string
+ if (dialog)
+ dialog->textRequest("");
+ break;
+
+ default:
+ break;
+ }
+
+ if (player_node && player_node->getCurrentAction() != Being::SIT)
+ player_node->setAction(Being::STAND);
+}
+
+void NpcHandler::talk(int npcId)
+{
+ MessageOut outMsg(CMSG_NPC_TALK);
+ outMsg.writeInt32(npcId);
+ outMsg.writeInt8(0); // Unused
+}
+
+void NpcHandler::nextDialog(int npcId)
+{
+ MessageOut outMsg(CMSG_NPC_NEXT_REQUEST);
+ outMsg.writeInt32(npcId);
+}
+
+void NpcHandler::closeDialog(int npcId)
+{
+ MessageOut outMsg(CMSG_NPC_CLOSE);
+ outMsg.writeInt32(npcId);
+
+ NpcDialogs::iterator it = mNpcDialogs.find(npcId);
+ if (it != mNpcDialogs.end())
+ {
+ if ((*it).second.dialog)
+ (*it).second.dialog->close();
+ mNpcDialogs.erase(it);
+ }
+}
+
+void NpcHandler::listInput(int npcId, unsigned char value)
+{
+ MessageOut outMsg(CMSG_NPC_LIST_CHOICE);
+ outMsg.writeInt32(npcId);
+ outMsg.writeInt8(static_cast<unsigned char>(value));
+}
+
+void NpcHandler::integerInput(int npcId, int value)
+{
+ MessageOut outMsg(CMSG_NPC_INT_RESPONSE);
+ outMsg.writeInt32(npcId);
+ outMsg.writeInt32(value);
+}
+
+void NpcHandler::stringInput(int npcId, const std::string &value)
+{
+ MessageOut outMsg(CMSG_NPC_STR_RESPONSE);
+ outMsg.writeInt16(value.length() + 9);
+ outMsg.writeInt32(npcId);
+ outMsg.writeString(value, value.length());
+ outMsg.writeInt8(0); // Prevent problems with string reading
+}
+
+void NpcHandler::sendLetter(int npcId _UNUSED_,
+ const std::string &recipient _UNUSED_,
+ const std::string &text _UNUSED_)
+{
+ // TODO
+}
+
+void NpcHandler::startShopping(int beingId _UNUSED_)
+{
+ // TODO
+}
+
+void NpcHandler::buy(int beingId)
+{
+ MessageOut outMsg(CMSG_NPC_BUY_SELL_REQUEST);
+ outMsg.writeInt32(beingId);
+ outMsg.writeInt8(0); // Buy
+}
+
+void NpcHandler::sell(int beingId)
+{
+ MessageOut outMsg(CMSG_NPC_BUY_SELL_REQUEST);
+ outMsg.writeInt32(beingId);
+ outMsg.writeInt8(1); // Sell
+}
+
+void NpcHandler::buyItem(int beingId _UNUSED_, int itemId, int amount)
+{
+ MessageOut outMsg(CMSG_NPC_BUY_REQUEST);
+ outMsg.writeInt16(8); // One item (length of packet)
+ outMsg.writeInt16(amount);
+ outMsg.writeInt16(itemId);
+}
+
+void NpcHandler::sellItem(int beingId _UNUSED_, int itemId, int amount)
+{
+ MessageOut outMsg(CMSG_NPC_SELL_REQUEST);
+ outMsg.writeInt16(8); // One item (length of packet)
+ outMsg.writeInt16(itemId + INVENTORY_OFFSET);
+ outMsg.writeInt16(amount);
+}
+
+void NpcHandler::endShopping(int beingId _UNUSED_)
+{
+ // TODO
+}
+
+void NpcHandler::clearDialogs()
+{
+ mNpcDialogs.clear();
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/npchandler.h b/src/net/tmwa/npchandler.h
new file mode 100644
index 000000000..7931a3d8b
--- /dev/null
+++ b/src/net/tmwa/npchandler.h
@@ -0,0 +1,90 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_NPCHANDLER_H
+#define NET_TA_NPCHANDLER_H
+
+#include "net/net.h"
+#include "net/npchandler.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#include <map>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class NpcDialog;
+
+namespace TmwAthena
+{
+
+class NpcHandler : public MessageHandler, public Net::NpcHandler
+{
+ public:
+ NpcHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void talk(int npcId);
+
+ void nextDialog(int npcId);
+
+ void closeDialog(int npcId);
+
+ void listInput(int npcId, unsigned char value);
+
+ void integerInput(int npcId, int value);
+
+ void stringInput(int npcId, const std::string &value);
+
+ void sendLetter(int npcId, const std::string &recipient,
+ const std::string &text);
+
+ void startShopping(int beingId);
+
+ void buy(int beingId);
+
+ void sell(int beingId);
+
+ void buyItem(int beingId, int itemId, int amount);
+
+ void sellItem(int beingId, int itemId, int amount);
+
+ void endShopping(int beingId);
+
+ void clearDialogs();
+
+ private:
+ typedef struct
+ {
+ NpcDialog* dialog;
+ } Wrapper;
+ typedef std::map<int, Wrapper> NpcDialogs;
+ NpcDialogs mNpcDialogs;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_NPCHANDLER_H
diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp
new file mode 100644
index 000000000..eecbf0c0e
--- /dev/null
+++ b/src/net/tmwa/partyhandler.cpp
@@ -0,0 +1,547 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/partyhandler.h"
+
+#include "actorspritemanager.h"
+#include "event.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/socialwindow.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "net/tmwa/gui/partytab.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#define PARTY_ID 1
+
+extern Net::PartyHandler *partyHandler;
+
+namespace TmwAthena
+{
+
+PartyTab *partyTab = 0;
+Party *taParty;
+
+PartyHandler::PartyHandler():
+ mShareExp(PARTY_SHARE_UNKNOWN), mShareItems(PARTY_SHARE_UNKNOWN)
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_PARTY_CREATE,
+ SMSG_PARTY_INFO,
+ SMSG_PARTY_INVITE_RESPONSE,
+ SMSG_PARTY_INVITED,
+ SMSG_PARTY_SETTINGS,
+ SMSG_PARTY_MOVE,
+ SMSG_PARTY_LEAVE,
+ SMSG_PARTY_UPDATE_HP,
+ SMSG_PARTY_UPDATE_COORDS,
+ SMSG_PARTY_MESSAGE,
+ 0
+ };
+ handledMessages = _messages;
+ partyHandler = this;
+ taParty = Party::getParty(1);
+}
+
+PartyHandler::~PartyHandler()
+{
+ delete partyTab;
+ partyTab = 0;
+}
+
+void PartyHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case SMSG_PARTY_CREATE:
+ if (msg.readInt8())
+ SERVER_NOTICE(_("Could not create party."))
+ else
+ SERVER_NOTICE(_("Party successfully created."))
+ break;
+ case SMSG_PARTY_INFO:
+ {
+ if (!taParty)
+ {
+ logger->log1("error: party empty in SMSG_PARTY_INFO");
+ taParty = Party::getParty(1);
+ }
+ if (!player_node)
+ logger->log1("error: player_node==0 in SMSG_PARTY_INFO");
+
+ if (taParty)
+ taParty->clearMembers();
+
+ int length = msg.readInt16();
+ if (taParty)
+ taParty->setName(msg.readString(24));
+
+ int count = (length - 28) / 46;
+ if (player_node && taParty)
+ {
+ player_node->setParty(taParty);
+ player_node->setPartyName(taParty->getName());
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ int id = msg.readInt32();
+ std::string nick = msg.readString(24);
+ std::string map = msg.readString(16);
+ bool leader = msg.readInt8() == 0;
+ bool online = msg.readInt8() == 0;
+
+ if (taParty)
+ {
+ PartyMember *member = taParty->addMember(id, nick);
+ if (member)
+ {
+ member->setLeader(leader);
+ member->setOnline(online);
+ member->setMap(map);
+ }
+ }
+ }
+
+ if (taParty)
+ taParty->sort();
+
+ if (player_node && taParty)
+ {
+ player_node->setParty(taParty);
+ player_node->setPartyName(taParty->getName());
+ }
+ }
+ break;
+ case SMSG_PARTY_INVITE_RESPONSE:
+ {
+ if (!partyTab)
+ break;
+
+ std::string nick = msg.readString(24);
+
+ switch (msg.readInt8())
+ {
+ case 0:
+ partyTab->chatLog(strprintf(
+ _("%s is already a member of a party."),
+ nick.c_str()), BY_SERVER);
+ break;
+ case 1:
+ partyTab->chatLog(strprintf(
+ _("%s refused your invitation."),
+ nick.c_str()), BY_SERVER);
+ break;
+ case 2:
+ partyTab->chatLog(strprintf(
+ _("%s is now a member of your party."),
+ nick.c_str()), BY_SERVER);
+ break;
+ case 3:
+ partyTab->chatLog(strprintf(
+ _("%s cant joid your party because party is "
+ "full."), nick.c_str()), BY_SERVER);
+ break;
+ default:
+ partyTab->chatLog(strprintf(
+ _("QQQ Unknown invite response for %s."),
+ nick.c_str()), BY_SERVER);
+ break;
+ }
+ break;
+ }
+ case SMSG_PARTY_INVITED:
+ {
+ int id = msg.readInt32();
+ std::string partyName = msg.readString(24);
+ std::string nick = "";
+ Being *being;
+
+ if (actorSpriteManager)
+ {
+ if ((being = actorSpriteManager->findBeing(id)))
+ {
+ if (being && being->getType() == Being::PLAYER)
+ nick = being->getName();
+ }
+ }
+
+ if (socialWindow)
+ socialWindow->showPartyInvite(partyName, nick);
+ break;
+ }
+ case SMSG_PARTY_SETTINGS:
+ {
+ if (!partyTab)
+ {
+ if (!chatWindow)
+ break;
+
+ partyTab = new PartyTab();
+ }
+
+ // These seem to indicate the sharing mode for exp and items
+ short exp = msg.readInt16();
+ short item = msg.readInt16();
+
+ if (!partyTab)
+ break;
+
+ switch (exp)
+ {
+ case PARTY_SHARE:
+ if (mShareExp == PARTY_SHARE)
+ break;
+ mShareExp = PARTY_SHARE;
+ if (partyTab)
+ {
+ partyTab->chatLog(
+ _("Experience sharing enabled."), BY_SERVER);
+ }
+ break;
+ case PARTY_SHARE_NO:
+ if (mShareExp == PARTY_SHARE_NO)
+ break;
+ mShareExp = PARTY_SHARE_NO;
+ if (partyTab)
+ {
+ partyTab->chatLog(
+ _("Experience sharing disabled."), BY_SERVER);
+ }
+ break;
+ case PARTY_SHARE_NOT_POSSIBLE:
+ if (mShareExp == PARTY_SHARE_NOT_POSSIBLE)
+ break;
+ mShareExp = PARTY_SHARE_NOT_POSSIBLE;
+ if (partyTab)
+ {
+ partyTab->chatLog(
+ _("Experience sharing not possible."),
+ BY_SERVER);
+ }
+ break;
+ default:
+ logger->log("QQQ Unknown party exp option: %d\n", exp);
+ break;
+ }
+
+ switch (item)
+ {
+ case PARTY_SHARE:
+ if (mShareItems == PARTY_SHARE)
+ break;
+ mShareItems = PARTY_SHARE;
+ if (partyTab)
+ {
+ partyTab->chatLog(
+ _("Item sharing enabled."), BY_SERVER);
+ }
+ break;
+ case PARTY_SHARE_NO:
+ if (mShareItems == PARTY_SHARE_NO)
+ break;
+ mShareItems = PARTY_SHARE_NO;
+ if (partyTab)
+ {
+ partyTab->chatLog(
+ _("Item sharing disabled."), BY_SERVER);
+ }
+ break;
+ case PARTY_SHARE_NOT_POSSIBLE:
+ if (mShareItems == PARTY_SHARE_NOT_POSSIBLE)
+ break;
+ mShareItems = PARTY_SHARE_NOT_POSSIBLE;
+ if (partyTab)
+ {
+ partyTab->chatLog(
+ _("Item sharing not possible."), BY_SERVER);
+ }
+ break;
+ default:
+ logger->log("QQQ Unknown party item option: %d\n",
+ exp);
+ break;
+ }
+ break;
+ }
+ case SMSG_PARTY_MOVE:
+ {
+ int id = msg.readInt32(); // id
+ PartyMember *m = 0;
+ if (taParty)
+ m = taParty->getMember(id);
+ if (m)
+ {
+ msg.skip(4);
+ m->setX(msg.readInt16()); // x
+ m->setY(msg.readInt16()); // y
+ m->setOnline(msg.readInt8()); // online (if 0)
+ msg.readString(24); // party
+ msg.readString(24); // nick
+ m->setMap(msg.readString(16)); // map
+ }
+ else
+ {
+ msg.skip(4);
+ msg.readInt16(); // x
+ msg.readInt16(); // y
+ msg.readInt8(); // online (if 0)
+ msg.readString(24); // party
+ msg.readString(24); // nick
+ msg.readString(16); // map
+ }
+ }
+ break;
+ case SMSG_PARTY_LEAVE:
+ {
+ int id = msg.readInt32();
+ std::string nick = msg.readString(24);
+ msg.readInt8(); // fail
+ if (player_node && id == player_node->getId())
+ {
+ if (taParty)
+ {
+ taParty->removeFromMembers();
+ taParty->clearMembers();
+ }
+ SERVER_NOTICE(_("You have left the party."))
+ delete partyTab;
+ partyTab = 0;
+
+ if (socialWindow && taParty)
+ socialWindow->removeTab(taParty);
+ }
+ else
+ {
+ if (partyTab)
+ {
+ partyTab->chatLog(strprintf(
+ _("%s has left your party."),
+ nick.c_str()), BY_SERVER);
+ }
+ if (actorSpriteManager)
+ {
+ Being *b = actorSpriteManager->findBeing(id);
+ if (b && b->getType() == Being::PLAYER)
+ b->setParty(0);
+ }
+ if (taParty)
+ taParty->removeMember(id);
+ }
+ break;
+ }
+ case SMSG_PARTY_UPDATE_HP:
+ {
+ int id = msg.readInt32();
+ int hp = msg.readInt16();
+ int maxhp = msg.readInt16();
+ PartyMember *m = 0;
+ if (taParty)
+ m = taParty->getMember(id);
+ if (m)
+ {
+ m->setHp(hp);
+ m->setMaxHp(maxhp);
+ }
+
+ // The server only sends this when the member is in range, so
+ // lets make sure they get the party hilight.
+ if (actorSpriteManager && taParty)
+ {
+ if (Being *b = actorSpriteManager->findBeing(id))
+ b->setParty(taParty);
+ }
+ }
+ break;
+ case SMSG_PARTY_UPDATE_COORDS:
+ {
+ int id = msg.readInt32(); // id
+ PartyMember *m = 0;
+ if (taParty)
+ m = taParty->getMember(id);
+ if (m)
+ {
+ m->setX(msg.readInt16()); // x
+ m->setY(msg.readInt16()); // y
+ }
+ else
+ {
+ msg.readInt16(); // x
+ msg.readInt16(); // y
+ }
+ }
+ break;
+ case SMSG_PARTY_MESSAGE:
+ {
+ int msgLength = msg.readInt16() - 8;
+ if (msgLength <= 0)
+ return;
+
+ int id = msg.readInt32();
+ std::string chatMsg = msg.readString(msgLength);
+
+ if (taParty)
+ {
+ PartyMember *member = taParty->getMember(id);
+ if (partyTab)
+ {
+ if (member)
+ {
+ partyTab->chatLog(member->getName(), chatMsg);
+ }
+ else
+ {
+ partyTab->chatLog(strprintf(
+ _("An unknown member tried to say: %s"),
+ chatMsg.c_str()), BY_SERVER);
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void PartyHandler::create(const std::string &name)
+{
+ MessageOut outMsg(CMSG_PARTY_CREATE);
+ outMsg.writeString(name.substr(0, 23), 24);
+}
+
+void PartyHandler::join(int partyId _UNUSED_)
+{
+ // TODO?
+}
+
+void PartyHandler::invite(Being *being)
+{
+ if (being)
+ {
+ MessageOut outMsg(CMSG_PARTY_INVITE);
+ outMsg.writeInt32(being->getId());
+ }
+}
+
+void PartyHandler::invite(const std::string &name)
+{
+ if (!actorSpriteManager)
+ return;
+
+ Being* being = actorSpriteManager->findBeingByName(name, Being::PLAYER);
+ if (being)
+ {
+ MessageOut outMsg(CMSG_PARTY_INVITE);
+ outMsg.writeInt32(being->getId());
+ }
+}
+
+void PartyHandler::inviteResponse(const std::string &inviter _UNUSED_,
+ bool accept)
+{
+ if (player_node)
+ {
+ MessageOut outMsg(CMSG_PARTY_INVITED);
+ outMsg.writeInt32(player_node->getId());
+ outMsg.writeInt32(accept ? 1 : 0);
+ }
+}
+
+void PartyHandler::leave()
+{
+ MessageOut outMsg(CMSG_PARTY_LEAVE);
+}
+
+void PartyHandler::kick(Being *being)
+{
+ if (being)
+ {
+ MessageOut outMsg(CMSG_PARTY_KICK);
+ outMsg.writeInt32(being->getId());
+ outMsg.writeString("", 24); //Unused
+ }
+}
+
+void PartyHandler::kick(const std::string &name)
+{
+ if (!taParty)
+ return;
+
+ PartyMember *m = taParty->getMember(name);
+ if (!m)
+ {
+ if (partyTab)
+ {
+ partyTab->chatLog(strprintf(_("%s is not in your party!"),
+ name.c_str()), BY_SERVER);
+ }
+ return;
+ }
+
+ MessageOut outMsg(CMSG_PARTY_KICK);
+ outMsg.writeInt32(m->getID());
+ outMsg.writeString(name, 24); //Unused
+}
+
+void PartyHandler::chat(const std::string &text)
+{
+ MessageOut outMsg(CMSG_PARTY_MESSAGE);
+ outMsg.writeInt16(text.length() + 4);
+ outMsg.writeString(text, text.length());
+}
+
+void PartyHandler::requestPartyMembers()
+{
+ // Our eAthena doesn't have this message
+ // Not needed anyways
+}
+
+void PartyHandler::setShareExperience(PartyShare share)
+{
+ if (share == PARTY_SHARE_NOT_POSSIBLE)
+ return;
+
+ MessageOut outMsg(CMSG_PARTY_SETTINGS);
+ outMsg.writeInt16(share);
+ outMsg.writeInt16(mShareItems);
+}
+
+void PartyHandler::setShareItems(PartyShare share)
+{
+ if (share == PARTY_SHARE_NOT_POSSIBLE)
+ return;
+
+ MessageOut outMsg(CMSG_PARTY_SETTINGS);
+ outMsg.writeInt16(mShareExp);
+ outMsg.writeInt16(share);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/partyhandler.h b/src/net/tmwa/partyhandler.h
new file mode 100644
index 000000000..8a199ded3
--- /dev/null
+++ b/src/net/tmwa/partyhandler.h
@@ -0,0 +1,85 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_PARTYHANDLER_H
+#define NET_TA_PARTYHANDLER_H
+
+#include "net/net.h"
+#include "net/partyhandler.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#include "party.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class PartyHandler : public MessageHandler, public Net::PartyHandler
+{
+ public:
+ PartyHandler();
+
+ ~PartyHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void create(const std::string &name = "");
+
+ void join(int partyId);
+
+ void invite(Being *being);
+
+ void invite(const std::string &name);
+
+ void inviteResponse(const std::string &inviter, bool accept);
+
+ void leave();
+
+ void kick(Being *being);
+
+ void kick(const std::string &name);
+
+ void chat(const std::string &text);
+
+ void requestPartyMembers();
+
+ PartyShare getShareExperience()
+ { return mShareExp; }
+
+ void setShareExperience(PartyShare share);
+
+ PartyShare getShareItems()
+ { return mShareItems; }
+
+ void setShareItems(PartyShare share);
+
+ private:
+ PartyShare mShareExp, mShareItems;
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_PARTYHANDLER_H
diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp
new file mode 100644
index 000000000..1d0d3e67d
--- /dev/null
+++ b/src/net/tmwa/playerhandler.cpp
@@ -0,0 +1,752 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/playerhandler.h"
+
+#include "event.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "party.h"
+#include "playerinfo.h"
+#include "units.h"
+
+#include "gui/buy.h"
+#include "gui/buysell.h"
+#include "gui/gui.h"
+#include "gui/npcdialog.h"
+#include "gui/okdialog.h"
+#include "gui/sell.h"
+#include "gui/statuswindow.h"
+#include "gui/viewport.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/protocol.h"
+#include "net/tmwa/npchandler.h"
+
+#include "utils/stringutils.h"
+#include "utils/gettext.h"
+
+extern OkDialog *weightNotice;
+extern OkDialog *deathNotice;
+
+// Max. distance we are willing to scroll after a teleport;
+// everything beyond will reset the port hard.
+static const int MAP_TELEPORT_SCROLL_DISTANCE = 8;
+
+// TODO Move somewhere else
+namespace
+{
+ /**
+ * Listener used for handling the overweigth message.
+ */
+ struct WeightListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event _UNUSED_)
+ {
+ weightNotice = NULL;
+ }
+ } weightListener;
+
+ /**
+ * Listener used for handling death message.
+ */
+ struct DeathListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event _UNUSED_)
+ {
+ Net::getPlayerHandler()->respawn();
+ deathNotice = NULL;
+
+ BuyDialog::closeAll();
+ BuySellDialog::closeAll();
+ NpcDialog::closeAll();
+ SellDialog::closeAll();
+
+ if (viewport)
+ viewport->closePopupMenu();
+
+ TmwAthena::NpcHandler *handler =
+ static_cast<TmwAthena::NpcHandler*>(Net::getNpcHandler());
+ if (handler)
+ handler->clearDialogs();
+ if (player_node)
+ player_node->respawn();
+ }
+ } deathListener;
+
+} // anonymous namespace
+
+static const char *randomDeathMessage()
+{
+ static char const *const deadMsg[] =
+ {
+ N_("You are dead."),
+ N_("We regret to inform you that your character was killed in "
+ "battle."),
+ N_("You are not that alive anymore."),
+ N_("The cold hands of the grim reaper are grabbing for your soul."),
+ N_("Game Over!"),
+ N_("Insert coin to continue."),
+ N_("No, kids. Your character did not really die. It... "
+ "err... went to a better place."),
+ N_("Your plan of breaking your enemies weapon by "
+ "bashing it with your throat failed."),
+ N_("I guess this did not run too well."),
+ // NetHack reference:
+ N_("Do you want your possessions identified?"),
+ // Secret of Mana reference:
+ N_("Sadly, no trace of you was ever found..."),
+ // Final Fantasy VI reference:
+ N_("Annihilated."),
+ // Earthbound reference:
+ N_("Looks like you got your head handed to you."),
+ // Leisure Suit Larry 1 reference:
+ N_("You screwed up again, dump your body down the tubes "
+ "and get you another one."),
+ // Monty Python references (Dead Parrot sketch mostly):
+ N_("You're not dead yet. You're just resting."),
+ N_("You are no more."),
+ N_("You have ceased to be."),
+ N_("You've expired and gone to meet your maker."),
+ N_("You're a stiff."),
+ N_("Bereft of life, you rest in peace."),
+ N_("If you weren't so animated, you'd be pushing up the daisies."),
+ N_("Your metabolic processes are now history."),
+ N_("You're off the twig."),
+ N_("You've kicked the bucket."),
+ N_("You've shuffled off your mortal coil, run down the "
+ "curtain and joined the bleedin' choir invisibile."),
+ N_("You are an ex-player."),
+ N_("You're pining for the fjords.")
+ };
+
+ const int random = rand() % (sizeof(deadMsg) / sizeof(deadMsg[0]));
+ return gettext(deadMsg[random]);
+}
+
+extern Net::PlayerHandler *playerHandler;
+
+namespace TmwAthena
+{
+
+PlayerHandler::PlayerHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_WALK_RESPONSE,
+ SMSG_PLAYER_WARP,
+ SMSG_PLAYER_STAT_UPDATE_1,
+ SMSG_PLAYER_STAT_UPDATE_2,
+ SMSG_PLAYER_STAT_UPDATE_3,
+ SMSG_PLAYER_STAT_UPDATE_4,
+ SMSG_PLAYER_STAT_UPDATE_5,
+ SMSG_PLAYER_STAT_UPDATE_6,
+ SMSG_PLAYER_ARROW_MESSAGE,
+ 0
+ };
+ handledMessages = _messages;
+ playerHandler = this;
+}
+
+void PlayerHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case SMSG_WALK_RESPONSE:
+ /*
+ * This client assumes that all walk messages succeed,
+ * and that the server will send a correction notice
+ * otherwise.
+ */
+ Uint16 srcX, srcY, dstX, dstY;
+ msg.readInt32(); //tick
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
+ if (player_node)
+ player_node->setRealPos(dstX, dstY);
+// if (debugChatTab)
+// debugChatTab->chatLog("move resp: " + toString((int)srcX) + "," + toString((int)srcY) + " "
+// + toString((int)dstX) + "," + toString((int)dstY));
+
+ break;
+
+ case SMSG_PLAYER_WARP:
+ {
+ std::string mapPath = msg.readString(16);
+ int x = msg.readInt16();
+ int y = msg.readInt16();
+
+ logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);
+
+ if (!player_node)
+ logger->log1("SMSG_PLAYER_WARP player_node null");
+
+ /*
+ * We must clear the local player's target *before* the call
+ * to changeMap, as it deletes all beings.
+ */
+ if (player_node)
+ player_node->stopAttack();
+
+ Game *game = Game::instance();
+
+ const std::string &currentMapName = game->getCurrentMapName();
+ bool sameMap = (currentMapName == mapPath);
+
+ // Switch the actual map, deleting the previous one if necessary
+ mapPath = mapPath.substr(0, mapPath.rfind("."));
+ game->changeMap(mapPath);
+
+ float scrollOffsetX = 0.0f;
+ float scrollOffsetY = 0.0f;
+
+ if (player_node)
+ {
+ /* Scroll if neccessary */
+ if (!sameMap
+ || (abs(x - player_node->getTileX())
+ > MAP_TELEPORT_SCROLL_DISTANCE)
+ || (abs(y - player_node->getTileY())
+ > MAP_TELEPORT_SCROLL_DISTANCE))
+ {
+ Map *map = game->getCurrentMap();
+ if (map)
+ {
+ scrollOffsetX = (x - player_node->getTileX())
+ * map->getTileWidth();
+ scrollOffsetY = (y - player_node->getTileY())
+ * map->getTileHeight();
+ }
+ }
+
+ player_node->setAction(Being::STAND);
+ player_node->setTileCoords(x, y);
+ player_node->naviageClean();
+// player_node->updateNavigateList();
+ }
+
+ logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
+ (int) scrollOffsetY);
+
+ if (viewport)
+ viewport->scrollBy(scrollOffsetX, scrollOffsetY);
+ }
+ break;
+
+ case SMSG_PLAYER_STAT_UPDATE_1:
+ {
+ int type = msg.readInt16();
+ int value = msg.readInt32();
+ if (!player_node)
+ return;
+
+ switch (type)
+ {
+ case 0x0000:
+ player_node->setWalkSpeed(Vector(value, value, 0));
+ PlayerInfo::setStatBase(WALK_SPEED, value);
+ PlayerInfo::setStatMod(WALK_SPEED, 0);
+ break;
+ case 0x0004: break; // manner
+ case 0x0005:
+ PlayerInfo::setAttribute(HP, value);
+ if (player_node->isInParty() && Party::getParty(1))
+ {
+ PartyMember *m = Party::getParty(1)
+ ->getMember(player_node->getId());
+ if (m)
+ {
+ m->setHp(value);
+ m->setMaxHp(PlayerInfo::getAttribute(MAX_HP));
+ }
+ }
+ break;
+ case 0x0006:
+ PlayerInfo::setAttribute(MAX_HP, value);
+
+ if (player_node->isInParty() && Party::getParty(1))
+ {
+ PartyMember *m = Party::getParty(1)->getMember(
+ player_node->getId());
+ if (m)
+ {
+ m->setHp(PlayerInfo::getAttribute(HP));
+ m->setMaxHp(value);
+ }
+ }
+ break;
+ case 0x0007:
+ PlayerInfo::setAttribute(MP, value);
+ break;
+ case 0x0008:
+ PlayerInfo::setAttribute(MAX_MP, value);
+ break;
+ case 0x0009:
+ PlayerInfo::setAttribute(CHAR_POINTS, value);
+ break;
+ case 0x000b:
+ PlayerInfo::setAttribute(LEVEL, value);
+ if (player_node)
+ {
+ player_node->setLevel(value);
+ player_node->updateName();
+ }
+ break;
+ case 0x000c:
+ PlayerInfo::setAttribute(SKILL_POINTS, value);
+ break;
+ case 0x0018:
+ if (!weightNotice)
+ {
+ const int max
+ = PlayerInfo::getAttribute(MAX_WEIGHT) / 2;
+ const int total
+ = PlayerInfo::getAttribute(TOTAL_WEIGHT);
+ if (value >= max && total < max)
+ {
+ weightNotice = new OkDialog(_("Message"),
+ _("You are carrying more than "
+ "half your weight. You are "
+ "unable to regain health."));
+ weightNotice->addActionListener(
+ &weightListener);
+ }
+ else if (value < max && total >= max)
+ {
+ weightNotice = new OkDialog(_("Message"),
+ _("You are carrying less than "
+ "half your weight. You are "
+ "can regain health."));
+ weightNotice->addActionListener(
+ &weightListener);
+ }
+ }
+ PlayerInfo::setAttribute(TOTAL_WEIGHT, value);
+ break;
+ case 0x0019:
+ PlayerInfo::setAttribute(MAX_WEIGHT, value);
+ break;
+
+ case 0x0029:
+ PlayerInfo::setStatBase(ATK, value);
+ break;
+ case 0x002a:
+ PlayerInfo::setStatMod(ATK, value);
+ break;
+
+ case 0x002b:
+ PlayerInfo::setStatBase(MATK, value);
+ break;
+ case 0x002c:
+ PlayerInfo::setStatMod(MATK, value);
+ break;
+
+ case 0x002d:
+ PlayerInfo::setStatBase(DEF, value);
+ break;
+ case 0x002e:
+ PlayerInfo::setStatMod(DEF, value);
+ break;
+
+ case 0x002f:
+ PlayerInfo::setStatBase(MDEF, value);
+ break;
+ case 0x0030:
+ PlayerInfo::setStatMod(MDEF, value);
+ break;
+
+ case 0x0031:
+ PlayerInfo::setStatBase(HIT, value);
+ break;
+
+ case 0x0032:
+ PlayerInfo::setStatBase(FLEE, value);
+ break;
+ case 0x0033:
+ PlayerInfo::setStatMod(FLEE, value);
+ break;
+
+ case 0x0034:
+ PlayerInfo::setStatBase(CRIT, value);
+ break;
+
+ case 0x0035:
+ player_node->setAttackSpeed(value);
+ PlayerInfo::setStatBase(ATTACK_SPEED, value);
+ PlayerInfo::setStatMod(ATTACK_SPEED, 0);
+ break;
+
+ case 0x0037:
+ PlayerInfo::setStatBase(JOB, value);
+ break;
+
+ case 500:
+ player_node->setGMLevel(value);
+ break;
+
+ default:
+ logger->log("QQQQ PLAYER_STAT_UPDATE_1 "
+ + toString(type) + "," + toString(value));
+ break;
+ }
+
+ if (PlayerInfo::getAttribute(HP) == 0 && !deathNotice)
+ {
+ deathNotice = new OkDialog(_("Message"),
+ randomDeathMessage(),
+ false);
+ deathNotice->addActionListener(&deathListener);
+ player_node->setAction(Being::DEAD);
+ }
+ }
+ break;
+
+ case SMSG_PLAYER_STAT_UPDATE_2:
+ {
+ int type = msg.readInt16();
+ switch (type)
+ {
+ case 0x0001:
+ PlayerInfo::setAttribute(EXP, msg.readInt32());
+ break;
+ case 0x0002:
+ PlayerInfo::setStatExperience(JOB, msg.readInt32(),
+ PlayerInfo::getStatExperience(JOB).second);
+ break;
+ case 0x0014:
+ {
+ int oldMoney = PlayerInfo::getAttribute(MONEY);
+ int newMoney = msg.readInt32();
+ if (newMoney > oldMoney)
+ {
+ SERVER_NOTICE(strprintf(_("You picked up %s."),
+ Units::formatCurrency(newMoney -
+ oldMoney).c_str()))
+ }
+ else if (newMoney < oldMoney)
+ {
+ SERVER_NOTICE(strprintf(_("You spent %s."),
+ Units::formatCurrency(oldMoney -
+ newMoney).c_str()))
+ }
+
+ PlayerInfo::setAttribute(MONEY, newMoney);
+ break;
+ }
+ case 0x0016:
+ PlayerInfo::setAttribute(EXP_NEEDED, msg.readInt32());
+ break;
+ case 0x0017:
+ PlayerInfo::setStatExperience(JOB,
+ PlayerInfo::getStatExperience(JOB).first,
+ msg.readInt32());
+ break;
+ default:
+ logger->log("QQQQ PLAYER_STAT_UPDATE_2 " + toString(type));
+ break;
+ }
+ break;
+ }
+ case SMSG_PLAYER_STAT_UPDATE_3: // Update a base attribute
+ {
+ int type = msg.readInt32();
+ int base = msg.readInt32();
+ int bonus = msg.readInt32();
+
+ PlayerInfo::setStatBase(type, base, false);
+ PlayerInfo::setStatMod(type, bonus);
+ }
+ break;
+
+ case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack
+ {
+ int type = msg.readInt16();
+ int ok = msg.readInt8();
+ int value = msg.readInt8();
+
+ if (ok != 1)
+ {
+ int oldValue = PlayerInfo::getStatBase(type);
+ int points = PlayerInfo::getAttribute(CHAR_POINTS);
+ points += oldValue - value;
+ PlayerInfo::setAttribute(CHAR_POINTS, points);
+ SERVER_NOTICE(_("Cannot raise skill!"))
+ }
+
+ PlayerInfo::setStatBase(type, value);
+ }
+ break;
+
+ // Updates stats and status points
+ case SMSG_PLAYER_STAT_UPDATE_5:
+ PlayerInfo::setAttribute(CHAR_POINTS, msg.readInt16());
+ {
+ int val = msg.readInt8();
+ PlayerInfo::setStatBase(STR, val);
+ if (statusWindow)
+ statusWindow->setPointsNeeded(STR, msg.readInt8());
+ else
+ msg.readInt8();
+
+ val = msg.readInt8();
+ PlayerInfo::setStatBase(AGI, val);
+ if (statusWindow)
+ statusWindow->setPointsNeeded(AGI, msg.readInt8());
+ else
+ msg.readInt8();
+
+ val = msg.readInt8();
+ PlayerInfo::setStatBase(VIT, val);
+ if (statusWindow)
+ statusWindow->setPointsNeeded(VIT, msg.readInt8());
+ else
+ msg.readInt8();
+
+ val = msg.readInt8();
+ PlayerInfo::setStatBase(INT, val);
+ if (statusWindow)
+ statusWindow->setPointsNeeded(INT, msg.readInt8());
+ else
+ msg.readInt8();
+
+ val = msg.readInt8();
+ PlayerInfo::setStatBase(DEX, val);
+ if (statusWindow)
+ statusWindow->setPointsNeeded(DEX, msg.readInt8());
+ else
+ msg.readInt8();
+
+ val = msg.readInt8();
+ PlayerInfo::setStatBase(LUK, val);
+ if (statusWindow)
+ statusWindow->setPointsNeeded(LUK, msg.readInt8());
+ else
+ msg.readInt8();
+
+ PlayerInfo::setStatBase(ATK, msg.readInt16(), false);
+ PlayerInfo::setStatMod(ATK, msg.readInt16());
+
+ val = msg.readInt16();
+ PlayerInfo::setStatBase(MATK, val, false);
+
+ val = msg.readInt16();
+ PlayerInfo::setStatMod(MATK, val);
+
+ PlayerInfo::setStatBase(DEF, msg.readInt16(), false);
+ PlayerInfo::setStatMod(DEF, msg.readInt16());
+
+ PlayerInfo::setStatBase(MDEF, msg.readInt16(), false);
+ PlayerInfo::setStatMod(MDEF, msg.readInt16());
+
+ PlayerInfo::setStatBase(HIT, msg.readInt16());
+
+ PlayerInfo::setStatBase(FLEE, msg.readInt16(), false);
+ PlayerInfo::setStatMod(FLEE, msg.readInt16());
+
+ PlayerInfo::setStatBase(CRIT, msg.readInt16());
+ }
+
+ msg.readInt16(); // manner
+ break;
+
+ case SMSG_PLAYER_STAT_UPDATE_6:
+ {
+ int type = msg.readInt16();
+ if (statusWindow)
+ {
+ switch (type)
+ {
+ case 0x0020:
+ statusWindow->setPointsNeeded(STR, msg.readInt8());
+ break;
+ case 0x0021:
+ statusWindow->setPointsNeeded(AGI, msg.readInt8());
+ break;
+ case 0x0022:
+ statusWindow->setPointsNeeded(VIT, msg.readInt8());
+ break;
+ case 0x0023:
+ statusWindow->setPointsNeeded(INT, msg.readInt8());
+ break;
+ case 0x0024:
+ statusWindow->setPointsNeeded(DEX, msg.readInt8());
+ break;
+ case 0x0025:
+ statusWindow->setPointsNeeded(LUK, msg.readInt8());
+ break;
+ default:
+ logger->log("QQQQ PLAYER_STAT_UPDATE_6 "
+ + toString(type));
+ break;
+ }
+ }
+ break;
+ }
+ case SMSG_PLAYER_ARROW_MESSAGE:
+ {
+ int type = msg.readInt16();
+
+ switch (type)
+ {
+ case 0:
+ {
+ SERVER_NOTICE(_("Equip arrows first."))
+ }
+ break;
+ case 3:
+ // arrows equiped
+ break;
+ default:
+ logger->log("QQQQ 0x013b: Unhandled message %i", type);
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void PlayerHandler::attack(int id, bool keep)
+{
+ MessageOut outMsg(CMSG_PLAYER_ATTACK);
+ outMsg.writeInt32(id);
+ if (keep)
+ outMsg.writeInt8(7);
+ else
+ outMsg.writeInt8(0);
+}
+
+void PlayerHandler::stopAttack()
+{
+ MessageOut outMsg(CMSG_PLAYER_STOP_ATTACK);
+}
+
+void PlayerHandler::emote(int emoteId)
+{
+ MessageOut outMsg(CMSG_PLAYER_EMOTE);
+ outMsg.writeInt8(emoteId);
+}
+
+void PlayerHandler::increaseAttribute(int attr)
+{
+ if (attr >= STR && attr <= LUK)
+ {
+ MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST);
+ outMsg.writeInt16(attr);
+ outMsg.writeInt8(1);
+ }
+}
+
+void PlayerHandler::decreaseAttribute(int attr _UNUSED_)
+{
+ // Supported by eA?
+}
+
+void PlayerHandler::increaseSkill(int skillId)
+{
+ if (PlayerInfo::getAttribute(SKILL_POINTS) <= 0)
+ return;
+
+ MessageOut outMsg(CMSG_SKILL_LEVELUP_REQUEST);
+ outMsg.writeInt16(skillId);
+}
+
+void PlayerHandler::pickUp(FloorItem *floorItem)
+{
+ if (!floorItem)
+ return;
+
+ MessageOut outMsg(CMSG_ITEM_PICKUP);
+ outMsg.writeInt32(floorItem->getId());
+}
+
+void PlayerHandler::setDirection(char direction)
+{
+ MessageOut outMsg(CMSG_PLAYER_CHANGE_DIR);
+ outMsg.writeInt16(0);
+ outMsg.writeInt8(direction);
+}
+
+void PlayerHandler::setDestination(int x, int y, int direction)
+{
+ MessageOut outMsg(CMSG_PLAYER_CHANGE_DEST);
+ outMsg.writeCoordinates(x, y, direction);
+}
+
+void PlayerHandler::changeAction(Being::Action action)
+{
+ char type;
+ switch (action)
+ {
+ case Being::SIT: type = 2; break;
+ case Being::STAND: type = 3; break;
+ default: return;
+ }
+
+ MessageOut outMsg(CMSG_PLAYER_CHANGE_ACT);
+ outMsg.writeInt32(0);
+ outMsg.writeInt8(type);
+}
+
+void PlayerHandler::respawn()
+{
+ MessageOut outMsg(CMSG_PLAYER_RESTART);
+ outMsg.writeInt8(0);
+}
+
+void PlayerHandler::ignorePlayer(const std::string &player _UNUSED_,
+ bool ignore _UNUSED_)
+{
+ // TODO
+}
+
+void PlayerHandler::ignoreAll(bool ignore _UNUSED_)
+{
+ // TODO
+}
+
+bool PlayerHandler::canUseMagic()
+{
+ return PlayerInfo::getStatEffective(MATK) > 0;
+}
+
+bool PlayerHandler::canCorrectAttributes()
+{
+ return false;
+}
+
+int PlayerHandler::getJobLocation()
+{
+ return JOB;
+}
+
+Vector PlayerHandler::getDefaultWalkSpeed()
+{
+ // Return an normalized speed for any side
+ // as the offset is calculated elsewhere.
+ return Vector(150, 150, 0);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h
new file mode 100644
index 000000000..6e1c6dc78
--- /dev/null
+++ b/src/net/tmwa/playerhandler.h
@@ -0,0 +1,74 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_PLAYERHANDLER_H
+#define NET_TA_PLAYERHANDLER_H
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class PlayerHandler : public MessageHandler, public Net::PlayerHandler
+{
+ public:
+ PlayerHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void attack(int id, bool keep = false);
+ void stopAttack();
+ void emote(int emoteId);
+
+ void increaseAttribute(int attr);
+ void decreaseAttribute(int attr);
+ void increaseSkill(int skillId);
+
+ void pickUp(FloorItem *floorItem);
+ void setDirection(char direction);
+ void setDestination(int x, int y, int direction = -1);
+ void changeAction(Being::Action action);
+
+ void respawn();
+
+ void ignorePlayer(const std::string &player, bool ignore);
+ void ignoreAll(bool ignore);
+
+ bool canUseMagic();
+ bool canCorrectAttributes();
+
+ int getJobLocation();
+
+ Vector getDefaultWalkSpeed();
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_PLAYERHANDLER_H
diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h
new file mode 100644
index 000000000..6001fae3b
--- /dev/null
+++ b/src/net/tmwa/protocol.h
@@ -0,0 +1,327 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TA_PROTOCOL_H
+#define TA_PROTOCOL_H
+
+enum
+{
+ JOB = 0xa,
+
+ STR = 0xd,
+ AGI,
+ VIT,
+ INT,
+ DEX,
+ LUK,
+
+ ATK,
+ DEF,
+ MATK,
+ MDEF,
+ HIT,
+ FLEE,
+ CRIT
+
+// KARMA,
+// MANNER
+};
+
+enum
+{
+ SPRITE_BASE = 0,
+ SPRITE_SHOE,
+ SPRITE_BOTTOMCLOTHES,
+ SPRITE_TOPCLOTHES,
+ SPRITE_MISC1,
+ SPRITE_MISC2,
+ SPRITE_HAIR,
+ SPRITE_HAT,
+ SPRITE_CAPE,
+ SPRITE_GLOVES,
+ SPRITE_WEAPON,
+ SPRITE_SHIELD,
+ SPRITE_VECTOREND
+};
+
+static const int INVENTORY_OFFSET = 2;
+static const int STORAGE_OFFSET = 1;
+
+/*********************************
+ * Packets from server to client *
+ *********************************/
+#define SMSG_SERVER_VERSION_RESPONSE 0x7531
+
+#define SMSG_SERVER_PING 0x007f /**< Contains server tick */
+#define SMSG_CONNECTION_PROBLEM 0x0081
+
+#define SMSG_UPDATE_HOST 0x0063 /**< Custom update host packet */
+#define SMSG_LOGIN_DATA 0x0069
+#define SMSG_LOGIN_ERROR 0x006a
+
+#define SMSG_CHAR_LOGIN 0x006b
+#define SMSG_CHAR_LOGIN_ERROR 0x006c
+#define SMSG_CHAR_CREATE_SUCCEEDED 0x006d
+#define SMSG_CHAR_CREATE_FAILED 0x006e
+#define SMSG_CHAR_DELETE_SUCCEEDED 0x006f
+#define SMSG_CHAR_DELETE_FAILED 0x0070
+#define SMSG_CHAR_MAP_INFO 0x0071
+#define SMSG_CHAR_PASSWORD_RESPONSE 0x0062 /**< Custom packet reply to password change request */
+
+#define SMSG_CHAR_SWITCH_RESPONSE 0x00b3
+#define SMSG_CHANGE_MAP_SERVER 0x0092
+
+#define SMSG_MAP_LOGIN_SUCCESS 0x0073 /**< Contains starting location */
+#define SMSG_MAP_QUIT_RESPONSE 0x018b
+#define SMSG_PLAYER_UPDATE_1 0x01d8
+#define SMSG_PLAYER_UPDATE_2 0x01d9
+#define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */
+#define SMSG_PLAYER_STOP 0x0088 /**< Stop walking, set position */
+#define SMSG_PLAYER_MOVE_TO_ATTACK 0x0139 /**< Move to within attack range */
+#define SMSG_PLAYER_STAT_UPDATE_1 0x00b0
+#define SMSG_PLAYER_STAT_UPDATE_2 0x00b1
+#define SMSG_PLAYER_STAT_UPDATE_3 0x0141
+#define SMSG_PLAYER_STAT_UPDATE_4 0x00bc
+#define SMSG_PLAYER_STAT_UPDATE_5 0x00bd
+#define SMSG_PLAYER_STAT_UPDATE_6 0x00be
+#define SMSG_WHO_ANSWER 0x00c2
+#define SMSG_PLAYER_WARP 0x0091 /**< Warp player to map/location */
+#define SMSG_PLAYER_INVENTORY 0x01ee
+#define SMSG_PLAYER_INVENTORY_ADD 0x00a0
+#define SMSG_PLAYER_INVENTORY_REMOVE 0x00af
+#define SMSG_PLAYER_INVENTORY_USE 0x01c8
+#define SMSG_PLAYER_EQUIPMENT 0x00a4
+#define SMSG_PLAYER_EQUIP 0x00aa
+#define SMSG_PLAYER_UNEQUIP 0x00ac
+#define SMSG_PLAYER_ATTACK_RANGE 0x013a
+#define SMSG_PLAYER_ARROW_EQUIP 0x013c
+#define SMSG_PLAYER_ARROW_MESSAGE 0x013b
+#define SMSG_PLAYER_SKILLS 0x010f
+#define SMSG_PLAYER_SKILL_UP 0x010e
+#define SMSG_SKILL_FAILED 0x0110
+#define SMSG_SKILL_DAMAGE 0x01de
+#define SMSG_ITEM_USE_RESPONSE 0x00a8
+#define SMSG_ITEM_VISIBLE 0x009d /**< An item is on the floor */
+#define SMSG_ITEM_DROPPED 0x009e /**< An item is dropped */
+#define SMSG_ITEM_REMOVE 0x00a1 /**< An item disappers */
+#define SMSG_BEING_VISIBLE 0x0078
+#define SMSG_BEING_MOVE 0x007b /**< A nearby monster moves */
+#define SMSG_BEING_SPAWN 0x007c /**< A being spawns nearby */
+#define SMSG_BEING_MOVE2 0x0086 /**< New eAthena being moves */
+#define SMSG_BEING_REMOVE 0x0080
+#define SMSG_BEING_CHANGE_LOOKS 0x00c3
+#define SMSG_BEING_CHANGE_LOOKS2 0x01d7 /**< Same as 0x00c3, but 16 bit ID */
+#define SMSG_BEING_SELFEFFECT 0x019b
+#define SMSG_BEING_EMOTION 0x00c0
+#define SMSG_BEING_ACTION 0x008a /**< Attack, sit, stand up, ... */
+#define SMSG_BEING_CHAT 0x008d /**< A being talks */
+#define SMSG_BEING_NAME_RESPONSE 0x0095 /**< Has to be requested */
+#define SMSG_BEING_CHANGE_DIRECTION 0x009c
+#define SMSG_BEING_RESURRECT 0x0148
+
+#define SMSG_PLAYER_STATUS_CHANGE 0x0119
+#define SMSG_PLAYER_GUILD_PARTY_INFO 0x0195
+#define SMSG_BEING_STATUS_CHANGE 0x0196
+
+#define SMSG_NPC_MESSAGE 0x00b4
+#define SMSG_NPC_NEXT 0x00b5
+#define SMSG_NPC_CLOSE 0x00b6
+#define SMSG_NPC_CHOICE 0x00b7 /**< Display a choice */
+#define SMSG_NPC_BUY_SELL_CHOICE 0x00c4
+#define SMSG_NPC_BUY 0x00c6
+#define SMSG_NPC_SELL 0x00c7
+#define SMSG_NPC_BUY_RESPONSE 0x00ca
+#define SMSG_NPC_SELL_RESPONSE 0x00cb
+#define SMSG_NPC_INT_INPUT 0x0142 /**< Integer input */
+#define SMSG_NPC_STR_INPUT 0x01d4 /**< String input */
+#define SMSG_PLAYER_CHAT 0x008e /**< Player talks */
+#define SMSG_WHISPER 0x0097 /**< Whisper Recieved */
+#define SMSG_WHISPER_RESPONSE 0x0098
+#define SMSG_GM_CHAT 0x009a /**< GM announce */
+#define SMSG_WALK_RESPONSE 0x0087
+
+#define SMSG_TRADE_REQUEST 0x00e5 /**< Receiving a request to trade */
+#define SMSG_TRADE_RESPONSE 0x00e7
+#define SMSG_TRADE_ITEM_ADD 0x00e9
+#define SMSG_TRADE_ITEM_ADD_RESPONSE 0x01b1 /**< Not standard eAthena! */
+#define SMSG_TRADE_OK 0x00ec
+#define SMSG_TRADE_CANCEL 0x00ee
+#define SMSG_TRADE_COMPLETE 0x00f0
+
+#define SMSG_PARTY_CREATE 0x00fa
+#define SMSG_PARTY_INFO 0x00fb
+#define SMSG_PARTY_INVITE_RESPONSE 0x00fd
+#define SMSG_PARTY_INVITED 0x00fe
+#define SMSG_PARTY_SETTINGS 0x0101
+#define SMSG_PARTY_MOVE 0x0104
+#define SMSG_PARTY_LEAVE 0x0105
+#define SMSG_PARTY_UPDATE_HP 0x0106
+#define SMSG_PARTY_UPDATE_COORDS 0x0107
+#define SMSG_PARTY_MESSAGE 0x0109
+
+#define SMSG_PLAYER_STORAGE_ITEMS 0x01f0 /**< Item list for storage */
+#define SMSG_PLAYER_STORAGE_EQUIP 0x00a6 /**< Equipment list for storage */
+#define SMSG_PLAYER_STORAGE_STATUS 0x00f2 /**< Slots used and total slots */
+#define SMSG_PLAYER_STORAGE_ADD 0x00f4 /**< Add item/equip to storage */
+#define SMSG_PLAYER_STORAGE_REMOVE 0x00f6 /**< Remove item/equip from storage */
+#define SMSG_PLAYER_STORAGE_CLOSE 0x00f8 /**< Storage access closed */
+
+#define SMSG_ADMIN_KICK_ACK 0x00cd
+
+#define SMSG_GUILD_CREATE_RESPONSE 0x0167
+#define SMSG_GUILD_POSITION_INFO 0x016c
+#define SMSG_GUILD_MEMBER_LOGIN 0x016d
+#define SMSG_GUILD_MASTER_OR_MEMBER 0x014e
+#define SMSG_GUILD_BASIC_INFO 0x01b6
+#define SMSG_GUILD_ALIANCE_INFO 0x014c
+#define SMSG_GUILD_MEMBER_LIST 0x0154
+#define SMSG_GUILD_POS_NAME_LIST 0x0166
+#define SMSG_GUILD_POS_INFO_LIST 0x0160
+#define SMSG_GUILD_POSITION_CHANGED 0x0174
+#define SMSG_GUILD_MEMBER_POS_CHANGE 0x0156
+#define SMSG_GUILD_EMBLEM 0x0152
+#define SMSG_GUILD_SKILL_INFO 0x0162
+#define SMSG_GUILD_NOTICE 0x016f
+#define SMSG_GUILD_INVITE 0x016a
+#define SMSG_GUILD_INVITE_ACK 0x0169
+#define SMSG_GUILD_LEAVE 0x015a
+#define SMSG_GUILD_EXPULSION 0x015c
+#define SMSG_GUILD_EXPULSION_LIST 0x0163
+#define SMSG_GUILD_MESSAGE 0x017f
+#define SMSG_GUILD_SKILL_UP 0x010e
+#define SMSG_GUILD_REQ_ALLIANCE 0x0171
+#define SMSG_GUILD_REQ_ALLIANCE_ACK 0x0173
+#define SMSG_GUILD_DEL_ALLIANCE 0x0184
+#define SMSG_GUILD_OPPOSITION_ACK 0x0181
+#define SMSG_GUILD_BROKEN 0x015e
+
+#define SMSG_MVP 0x010c
+
+/**********************************
+ * Packets from client to server *
+ **********************************/
+#define CMSG_SERVER_VERSION_REQUEST 0x7530
+
+#define CMSG_CHAR_PASSWORD_CHANGE 0x0061 /**< Custom change password packet */
+#define CMSG_CHAR_SERVER_CONNECT 0x0065
+#define CMSG_CHAR_SELECT 0x0066
+#define CMSG_CHAR_CREATE 0x0067
+#define CMSG_CHAR_DELETE 0x0068
+
+#define CMSG_MAP_SERVER_CONNECT 0x0072
+#define CMSG_CLIENT_PING 0x007e /**< Send to server with tick */
+#define CMSG_MAP_LOADED 0x007d
+#define CMSG_CLIENT_QUIT 0x018A
+
+#define CMSG_CHAT_MESSAGE 0x008c
+#define CMSG_CHAT_WHISPER 0x0096
+#define CMSG_CHAT_ANNOUNCE 0x0099
+#define CMSG_CHAT_WHO 0x00c1
+
+#define CMSG_SKILL_LEVELUP_REQUEST 0x0112
+#define CMSG_STAT_UPDATE_REQUEST 0x00bb
+#define CMSG_SKILL_USE_BEING 0x0113
+#define CMSG_SKILL_USE_POSITION 0x0116
+// Variant of 0x116 with 80 char string at end (unsure of use)
+#define CMSG_SKILL_USE_POSITION_MORE 0x0190
+#define CMSG_SKILL_USE_MAP 0x011b
+
+#define CMSG_PLAYER_INVENTORY_USE 0x00a7
+#define CMSG_PLAYER_INVENTORY_DROP 0x00a2
+#define CMSG_PLAYER_EQUIP 0x00a9
+#define CMSG_PLAYER_UNEQUIP 0x00ab
+
+#define CMSG_ITEM_PICKUP 0x009f
+#define CMSG_PLAYER_CHANGE_DIR 0x009b
+#define CMSG_PLAYER_CHANGE_DEST 0x0085
+#define CMSG_PLAYER_CHANGE_ACT 0x0089
+#define CMSG_PLAYER_RESTART 0x00b2
+#define CMSG_PLAYER_EMOTE 0x00bf
+#define CMSG_PLAYER_ATTACK 0x0089
+#define CMSG_PLAYER_STOP_ATTACK 0x0118
+#define CMSG_WHO_REQUEST 0x00c1
+
+#define CMSG_NPC_TALK 0x0090
+#define CMSG_NPC_NEXT_REQUEST 0x00b9
+#define CMSG_NPC_CLOSE 0x0146
+#define CMSG_NPC_LIST_CHOICE 0x00b8
+#define CMSG_NPC_INT_RESPONSE 0x0143
+#define CMSG_NPC_STR_RESPONSE 0x01d5
+#define CMSG_NPC_BUY_SELL_REQUEST 0x00c5
+#define CMSG_NPC_BUY_REQUEST 0x00c8
+#define CMSG_NPC_SELL_REQUEST 0x00c9
+
+#define CMSG_TRADE_REQUEST 0x00e4
+#define CMSG_TRADE_RESPONSE 0x00e6
+#define CMSG_TRADE_ITEM_ADD_REQUEST 0x00e8
+#define CMSG_TRADE_CANCEL_REQUEST 0x00ed
+#define CMSG_TRADE_ADD_COMPLETE 0x00eb
+#define CMSG_TRADE_OK 0x00ef
+
+#define CMSG_PARTY_CREATE 0x00f9
+#define CMSG_PARTY_INVITE 0x00fc
+#define CMSG_PARTY_INVITED 0x00ff
+#define CMSG_PARTY_LEAVE 0x0100
+#define CMSG_PARTY_SETTINGS 0x0102
+#define CMSG_PARTY_KICK 0x0103
+#define CMSG_PARTY_MESSAGE 0x0108
+
+#define CMSG_MOVE_TO_STORAGE 0x00f3 /** Move item to storage */
+#define CSMG_MOVE_FROM_STORAGE 0x00f5 /** Remove item from storage */
+#define CMSG_CLOSE_STORAGE 0x00f7 /** Request storage close */
+
+#define CMSG_ADMIN_ANNOUNCE 0x0099
+#define CMSG_ADMIN_LOCAL_ANNOUNCE 0x019C
+#define CMSG_ADMIN_HIDE 0x019D
+#define CMSG_ADMIN_KICK 0x00CC
+#define CMSG_ADMIN_MUTE 0x0149
+
+#define CMSG_GUILD_CHECK_MASTER 0x014d
+#define CMSG_GUILD_REQUEST_INFO 0x014f
+#define CMSG_GUILD_REQUEST_EMBLEM 0x0151
+#define CMSG_GUILD_CHANGE_EMBLEM 0x0153
+#define CMSG_GUILD_CHANGE_MEMBER_POS 0x0155
+#define CMSG_GUILD_LEAVE 0x0159
+#define CMSG_GUILD_EXPULSION 0x015b
+#define CMSG_GUILD_BREAK 0x015d
+#define CMSG_GUILD_CHANGE_POS_INFO 0x0161
+#define CMSG_GUILD_CREATE 0x0165
+#define CMSG_GUILD_INVITE 0x0168
+#define CMSG_GUILD_INVITE_REPLY 0x016b
+#define CMSG_GUILD_CHANGE_NOTICE 0x016e
+#define CMSG_GUILD_ALLIANCE_REQUEST 0x0170
+#define CMSG_GUILD_ALLIANCE_REPLY 0x0172
+#define CMSG_GUILD_MESSAGE 0x017e
+#define CMSG_GUILD_OPPOSITION 0x0180
+#define CMSG_GUILD_ALLIANCE_DELETE 0x0183
+
+#define CMSG_SOLVE_CHAR_NAME 0x0193
+#define SMSG_SOLVE_CHAR_NAME 0x0194
+#define CMSG_CLIENT_DISCONNECT 0x7532
+#define SMSG_SKILL_CASTING 0x013e
+#define SMSG_SKILL_CAST_CANCEL 0x01b9
+#define SMSG_SKILL_NO_DAMAGE 0x011a
+
+#define SMSG_BEING_IP_RESPONSE 0x020c
+#define SMSG_PVP_MAP_MODE 0x0199
+#define SMSG_PVP_SET 0x019a
+
+#endif
diff --git a/src/net/tmwa/specialhandler.cpp b/src/net/tmwa/specialhandler.cpp
new file mode 100644
index 000000000..d502cc85f
--- /dev/null
+++ b/src/net/tmwa/specialhandler.cpp
@@ -0,0 +1,273 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/specialhandler.h"
+
+#include "log.h"
+#include "playerinfo.h"
+
+#include "gui/skilldialog.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "utils/gettext.h"
+
+/** job dependend identifiers (?) */
+#define SKILL_BASIC 0x0001
+#define SKILL_WARP 0x001b
+#define SKILL_STEAL 0x0032
+#define SKILL_ENVENOM 0x0034
+
+/** basic skills identifiers */
+#define BSKILL_TRADE 0x0000
+#define BSKILL_EMOTE 0x0001
+#define BSKILL_SIT 0x0002
+#define BSKILL_CREATECHAT 0x0003
+#define BSKILL_JOINPARTY 0x0004
+#define BSKILL_SHOUT 0x0005
+#define BSKILL_PK 0x0006 // ??
+#define BSKILL_SETALLIGN 0x0007 // ??
+
+/** reasons why action failed */
+#define RFAIL_SKILLDEP 0x00
+#define RFAIL_INSUFSP 0x01
+#define RFAIL_INSUFHP 0x02
+#define RFAIL_NOMEMO 0x03
+#define RFAIL_SKILLDELAY 0x04
+#define RFAIL_ZENY 0x05
+#define RFAIL_WEAPON 0x06
+#define RFAIL_REDGEM 0x07
+#define RFAIL_BLUEGEM 0x08
+#define RFAIL_OVERWEIGHT 0x09
+#define RFAIL_GENERIC 0x0a
+
+/** should always be zero if failed */
+#define SKILL_FAILED 0x00
+
+extern Net::SpecialHandler *specialHandler;
+
+namespace TmwAthena
+{
+
+SpecialHandler::SpecialHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_PLAYER_SKILLS,
+ SMSG_SKILL_FAILED,
+ SMSG_PLAYER_SKILL_UP,
+ 0
+ };
+ handledMessages = _messages;
+ specialHandler = this;
+}
+
+void SpecialHandler::handleMessage(Net::MessageIn &msg)
+{
+ int skillCount;
+ int skillId;
+
+ switch (msg.getId())
+ {
+ case SMSG_PLAYER_SKILLS:
+ {
+ msg.readInt16(); // length
+ skillCount = (msg.getLength() - 4) / 37;
+
+ for (int k = 0; k < skillCount; k++)
+ {
+ skillId = msg.readInt16();
+ msg.readInt16(); // target type
+ msg.skip(2); // unused
+ int level = msg.readInt16();
+ msg.readInt16(); // sp
+ msg.readInt16(); // range
+ msg.skip(24); // unused
+ int up = msg.readInt8();
+
+ PlayerInfo::setStatBase(skillId, level);
+ if (skillDialog)
+ skillDialog->setModifiable(skillId, up);
+ }
+ break;
+ }
+ case SMSG_PLAYER_SKILL_UP:
+ {
+ skillId = msg.readInt16();
+ int level = msg.readInt16();
+ msg.readInt16(); // sp
+ msg.readInt16(); // range
+ int up = msg.readInt8();
+
+ PlayerInfo::setStatBase(skillId, level);
+ if (skillDialog)
+ skillDialog->setModifiable(skillId, up);
+ }
+ break;
+
+ case SMSG_SKILL_FAILED:
+ {
+ // Action failed (ex. sit because you have not reached the
+ // right level)
+ skillId = msg.readInt16();
+ short bskill = msg.readInt16();
+ msg.readInt16(); // btype
+ char success = msg.readInt8();
+ char reason = msg.readInt8();
+ if (success != SKILL_FAILED && bskill == BSKILL_EMOTE)
+ logger->log("Action: %d/%d", bskill, success);
+
+ std::string msg;
+ if (success == SKILL_FAILED && skillId == SKILL_BASIC)
+ {
+ switch (bskill)
+ {
+ case BSKILL_TRADE:
+ msg = _("Trade failed!");
+ break;
+ case BSKILL_EMOTE:
+ msg = _("Emote failed!");
+ break;
+ case BSKILL_SIT:
+ msg = _("Sit failed!");
+ break;
+ case BSKILL_CREATECHAT:
+ msg = _("Chat creating failed!");
+ break;
+ case BSKILL_JOINPARTY:
+ msg = _("Could not join party!");
+ break;
+ case BSKILL_SHOUT:
+ msg = _("Cannot shout!");
+ break;
+ default:
+ logger->log("QQQ SMSG_SKILL_FAILED: bskill "
+ + toString(bskill));
+ break;
+ }
+
+ msg += " ";
+
+ switch (reason)
+ {
+ case RFAIL_SKILLDEP:
+ msg += _("You have not yet reached a high enough "
+ "lvl!");
+ break;
+ case RFAIL_INSUFHP:
+ msg += _("Insufficient HP!");
+ break;
+ case RFAIL_INSUFSP:
+ msg += _("Insufficient SP!");
+ break;
+ case RFAIL_NOMEMO:
+ msg += _("You have no memos!");
+ break;
+ case RFAIL_SKILLDELAY:
+ msg += _("You cannot do that right now!");
+ break;
+ case RFAIL_ZENY:
+ msg += _("Seems you need more money... ;-)");
+ break;
+ case RFAIL_WEAPON:
+ msg += _("You cannot use this skill with that "
+ "kind of weapon!");
+ break;
+ case RFAIL_REDGEM:
+ msg += _("You need another red gem!");
+ break;
+ case RFAIL_BLUEGEM:
+ msg += _("You need another blue gem!");
+ break;
+ case RFAIL_OVERWEIGHT:
+ msg += _("You're carrying to much to do this!");
+ break;
+ default:
+ msg += _("Huh? What's that?");
+ logger->log("QQQ SMSG_SKILL_FAILED: reason "
+ + toString(reason));
+ break;
+ }
+ }
+ else
+ {
+ switch (skillId)
+ {
+ case SKILL_WARP :
+ msg = _("Warp failed...");
+ break;
+ case SKILL_STEAL :
+ msg = _("Could not steal anything...");
+ break;
+ case SKILL_ENVENOM :
+ msg = _("Poison had no effect...");
+ break;
+ default:
+ logger->log("QQQ SMSG_SKILL_FAILED: skillId "
+ + toString(skillId));
+ break;
+ }
+ }
+
+ if (localChatTab)
+ localChatTab->chatLog(msg);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SpecialHandler::use(int id _UNUSED_)
+{
+ // TODO
+}
+
+void SpecialHandler::use(int id, int level, int beingId)
+{
+ MessageOut outMsg(CMSG_SKILL_USE_BEING);
+ outMsg.writeInt16(level);
+ outMsg.writeInt16(id);
+ outMsg.writeInt16(beingId);
+}
+
+void SpecialHandler::use(int id, int level, int x, int y)
+{
+ MessageOut outMsg(CMSG_SKILL_USE_POSITION);
+ outMsg.writeInt16(level);
+ outMsg.writeInt16(id);
+ outMsg.writeInt16(x);
+ outMsg.writeInt16(y);
+}
+
+void SpecialHandler::use(int id, const std::string &map)
+{
+ MessageOut outMsg(CMSG_SKILL_USE_MAP);
+ outMsg.writeInt16(id);
+ outMsg.writeString(map, 16);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/specialhandler.h b/src/net/tmwa/specialhandler.h
new file mode 100644
index 000000000..e4e65c607
--- /dev/null
+++ b/src/net/tmwa/specialhandler.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_SKILLHANDLER_H
+#define NET_TA_SKILLHANDLER_H
+
+#include "net/net.h"
+#include "net/specialhandler.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class SpecialHandler : public MessageHandler, public Net::SpecialHandler
+{
+ public:
+ SpecialHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void use(int id);
+
+ void use(int id, int level, int beingId);
+
+ void use(int id, int level, int x, int y);
+
+ void use(int id, const std::string &map);
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_SKILLHANDLER_H
diff --git a/src/net/tmwa/token.h b/src/net/tmwa/token.h
new file mode 100644
index 000000000..3e781cd89
--- /dev/null
+++ b/src/net/tmwa/token.h
@@ -0,0 +1,43 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "being.h"
+
+#ifndef NET_TA_TOKEN_H
+#define NET_TA_TOKEN_H
+
+struct Token
+{
+ int account_ID;
+ int session_ID1;
+ int session_ID2;
+ Gender sex;
+
+ void clear()
+ {
+ account_ID = 0;
+ session_ID1 = 0;
+ session_ID2 = 0;
+ sex = GENDER_UNSPECIFIED;
+ }
+};
+
+#endif // NET_TA_TOKEN_H
diff --git a/src/net/tmwa/tradehandler.cpp b/src/net/tmwa/tradehandler.cpp
new file mode 100644
index 000000000..6c48d5e6c
--- /dev/null
+++ b/src/net/tmwa/tradehandler.cpp
@@ -0,0 +1,347 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "net/tmwa/tradehandler.h"
+
+#include "event.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "log.h"
+#include "playerinfo.h"
+#include "playerrelations.h"
+
+#include "gui/confirmdialog.h"
+#include "gui/trade.h"
+
+#include "net/inventoryhandler.h"
+#include "net/messagein.h"
+#include "net/messageout.h"
+
+#include "net/tmwa/protocol.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+extern std::string tradePartnerName;
+ConfirmDialog *confirmDlg;
+
+/**
+ * Listener for request trade dialogs
+ */
+namespace
+{
+ struct RequestTradeListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event)
+ {
+ confirmDlg = 0;
+ if (event.getId() == "ignore")
+ player_relations.ignoreTrade(tradePartnerName);
+ Net::getTradeHandler()->respond(event.getId() == "yes");
+ }
+ } listener;
+}
+
+extern Net::TradeHandler *tradeHandler;
+
+namespace TmwAthena
+{
+
+TradeHandler::TradeHandler()
+{
+ static const Uint16 _messages[] =
+ {
+ SMSG_TRADE_REQUEST,
+ SMSG_TRADE_RESPONSE,
+ SMSG_TRADE_ITEM_ADD,
+ SMSG_TRADE_ITEM_ADD_RESPONSE,
+ SMSG_TRADE_OK,
+ SMSG_TRADE_CANCEL,
+ SMSG_TRADE_COMPLETE,
+ 0
+ };
+ handledMessages = _messages;
+ tradeHandler = this;
+ confirmDlg = 0;
+}
+
+
+void TradeHandler::handleMessage(Net::MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case SMSG_TRADE_REQUEST:
+ {
+ // If a trade window or request window is already open, send a
+ // trade cancel to any other trade request.
+ //
+ // Note that it would be nice if the server would prevent this
+ // situation, and that the requesting player would get a
+ // special message about the player being occupied.
+ std::string tradePartnerNameTemp = msg.readString(24);
+
+ if (player_relations.hasPermission(tradePartnerName,
+ PlayerRelation::TRADE))
+ {
+ if (PlayerInfo::isTrading() || confirmDlg)
+ {
+ Net::getTradeHandler()->respond(false);
+ break;
+ }
+
+ tradePartnerName = tradePartnerNameTemp;
+ PlayerInfo::setTrading(true);
+ if (tradeWindow)
+ {
+ if (tradePartnerName.empty()
+ || tradeWindow->getAutoTradeNick()
+ != tradePartnerName)
+ {
+ tradeWindow->clear();
+ confirmDlg = new ConfirmDialog(
+ _("Request for Trade"),
+ strprintf(_("%s wants to trade with you, do"
+ " you accept?"), tradePartnerName.c_str()),
+ true);
+ confirmDlg->addActionListener(&listener);
+ }
+ else
+ {
+ Net::getTradeHandler()->respond(true);
+ }
+ }
+ }
+ else
+ {
+ Net::getTradeHandler()->respond(false);
+ break;
+ }
+ }
+ break;
+
+ case SMSG_TRADE_RESPONSE:
+ switch (msg.readInt8())
+ {
+ case 0: // Too far away
+ SERVER_NOTICE(_("Trading isn't possible. Trade "
+ "partner is too far away."))
+ break;
+ case 1: // Character doesn't exist
+ SERVER_NOTICE(_("Trading isn't possible. Character "
+ "doesn't exist."))
+ break;
+ case 2: // Invite request check failed...
+ SERVER_NOTICE(_("Trade cancelled due to an unknown "
+ "reason."))
+ break;
+ case 3: // Trade accepted
+ if (tradeWindow)
+ {
+ tradeWindow->reset();
+ tradeWindow->setCaption(strprintf(
+ _("Trade: You and %s"),
+ tradePartnerName.c_str()));
+ tradeWindow->initTrade(tradePartnerName);
+ tradeWindow->setVisible(true);
+ }
+ break;
+ case 4: // Trade cancelled
+ if (player_relations.hasPermission(tradePartnerName,
+ PlayerRelation::SPEECH_LOG))
+ {
+ SERVER_NOTICE(strprintf(_("Trade with %s cancelled."),
+ tradePartnerName.c_str()))
+ }
+ // otherwise ignore silently
+
+ if (tradeWindow)
+ {
+ tradeWindow->setVisible(false);
+// tradeWindow->clear();
+ }
+ PlayerInfo::setTrading(false);
+ break;
+ default: // Shouldn't happen as well, but to be sure
+ SERVER_NOTICE(_("Unhandled trade cancel packet."))
+ if (tradeWindow)
+ tradeWindow->clear();
+ break;
+ }
+ break;
+
+ case SMSG_TRADE_ITEM_ADD:
+ {
+ int amount = msg.readInt32();
+ int type = msg.readInt16();
+ msg.readInt8(); // identified flag
+ msg.readInt8(); // attribute
+ msg.readInt8(); // refine
+ msg.skip(8); // card (4 shorts)
+
+ // TODO: handle also identified, etc
+ if (tradeWindow)
+ {
+ if (type == 0)
+ tradeWindow->setMoney(amount);
+ else
+ tradeWindow->addItem(type, false, amount, false);
+ }
+ }
+ break;
+
+ case SMSG_TRADE_ITEM_ADD_RESPONSE:
+ // Trade: New Item add response (was 0x00ea, now 01b1)
+ {
+ const int index = msg.readInt16() - INVENTORY_OFFSET;
+ Item *item = PlayerInfo::getInventory()->getItem(index);
+ if (!item)
+ {
+ if (tradeWindow)
+ tradeWindow->receivedOk(true);
+ return;
+ }
+ int quantity = msg.readInt16();
+
+ int res = msg.readInt8();
+ switch (res)
+ {
+ case 0:
+ // Successfully added item
+ if (item->isEquipment() && item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+
+ if (tradeWindow)
+ {
+ tradeWindow->addItem(item->getId(), true, quantity,
+ item->isEquipment());
+ }
+ item->increaseQuantity(-quantity);
+ break;
+ case 1:
+ // Add item failed - player overweighted
+ SERVER_NOTICE(_("Failed adding item. Trade "
+ "partner is over weighted."))
+ break;
+ case 2:
+ // Add item failed - player has no free slot
+ SERVER_NOTICE(_("Failed adding item. Trade "
+ "partner has no free slot."))
+ break;
+ default:
+ SERVER_NOTICE(_("Failed adding item for "
+ "unknown reason."))
+ logger->log("QQQ SMSG_TRADE_ITEM_ADD_RESPONSE: "
+ + toString(res));
+ break;
+ }
+ }
+ break;
+
+ case SMSG_TRADE_OK:
+ // 0 means ok from myself, 1 means ok from other;
+ if (tradeWindow)
+ tradeWindow->receivedOk(msg.readInt8() == 0);
+ else
+ msg.readInt8();
+ break;
+
+ case SMSG_TRADE_CANCEL:
+ SERVER_NOTICE(_("Trade canceled."))
+ if (tradeWindow)
+ {
+ tradeWindow->setVisible(false);
+ tradeWindow->reset();
+ }
+ PlayerInfo::setTrading(false);
+ break;
+
+ case SMSG_TRADE_COMPLETE:
+ SERVER_NOTICE(_("Trade completed."))
+ if (tradeWindow)
+ {
+ tradeWindow->setVisible(false);
+ tradeWindow->reset();
+ }
+ PlayerInfo::setTrading(false);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void TradeHandler::request(Being *being)
+{
+ if (!being)
+ return;
+
+ MessageOut outMsg(CMSG_TRADE_REQUEST);
+ outMsg.writeInt32(being->getId());
+}
+
+void TradeHandler::respond(bool accept)
+{
+ if (!accept)
+ PlayerInfo::setTrading(false);
+
+ MessageOut outMsg(CMSG_TRADE_RESPONSE);
+ outMsg.writeInt8(accept ? 3 : 4);
+}
+
+void TradeHandler::addItem(Item *item, int amount)
+{
+ if (!item)
+ return;
+
+ MessageOut outMsg(CMSG_TRADE_ITEM_ADD_REQUEST);
+ outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET);
+ outMsg.writeInt32(amount);
+}
+
+void TradeHandler::removeItem(int slotNum _UNUSED_, int amount _UNUSED_)
+{
+ // TODO
+}
+
+void TradeHandler::setMoney(int amount)
+{
+ MessageOut outMsg(CMSG_TRADE_ITEM_ADD_REQUEST);
+ outMsg.writeInt16(0);
+ outMsg.writeInt32(amount);
+}
+
+void TradeHandler::confirm()
+{
+ MessageOut outMsg(CMSG_TRADE_ADD_COMPLETE);
+}
+
+void TradeHandler::finish()
+{
+ MessageOut outMsg(CMSG_TRADE_OK);
+}
+
+void TradeHandler::cancel()
+{
+ MessageOut outMsg(CMSG_TRADE_CANCEL_REQUEST);
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/tradehandler.h b/src/net/tmwa/tradehandler.h
new file mode 100644
index 000000000..39364e52d
--- /dev/null
+++ b/src/net/tmwa/tradehandler.h
@@ -0,0 +1,65 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NET_TA_TRADEHANDLER_H
+#define NET_TA_TRADEHANDLER_H
+
+#include "net/net.h"
+#include "net/tradehandler.h"
+
+#include "net/tmwa/messagehandler.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace TmwAthena
+{
+
+class TradeHandler : public MessageHandler, public Net::TradeHandler
+{
+ public:
+ TradeHandler();
+
+ void handleMessage(Net::MessageIn &msg);
+
+ void request(Being *being);
+
+ void respond(bool accept);
+
+ void addItem(Item *item, int amount);
+
+ void removeItem(int slotNum, int amount);
+
+ void setMoney(int amount);
+
+ void confirm();
+
+ void finish();
+
+ void cancel();
+};
+
+} // namespace TmwAthena
+
+#endif // NET_TA_TRADEHANDLER_H
diff --git a/src/net/tradehandler.h b/src/net/tradehandler.h
new file mode 100644
index 000000000..d433cacbf
--- /dev/null
+++ b/src/net/tradehandler.h
@@ -0,0 +1,67 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TRADEHANDLER_H
+#define TRADEHANDLER_H
+
+#include "being.h"
+
+#include <iosfwd>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+namespace Net
+{
+class TradeHandler
+{
+ public:
+ virtual void request(Being *being _UNUSED_)
+ { }
+// virtual ~TradeHandler() {}
+
+ virtual void respond(bool accept _UNUSED_)
+ { }
+
+ virtual void addItem(Item *item _UNUSED_, int amount _UNUSED_)
+ { }
+
+ virtual void removeItem(int slotNum _UNUSED_, int amount _UNUSED_)
+ { }
+
+ virtual void setMoney(int amount _UNUSED_)
+ { }
+
+ virtual void confirm()
+ { }
+
+ virtual void finish()
+ { }
+
+ virtual void cancel()
+ { }
+};
+}
+
+#endif // TRADEHANDLER_H
diff --git a/src/net/worldinfo.h b/src/net/worldinfo.h
new file mode 100644
index 000000000..a92a5735e
--- /dev/null
+++ b/src/net/worldinfo.h
@@ -0,0 +1,39 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WORLD_INFO_H
+#define WORLD_INFO_H
+
+#include <string>
+#include <vector>
+
+struct WorldInfo
+{
+ int address;
+ std::string name;
+ short port;
+ short online_users;
+ std::string updateHost;
+};
+
+typedef std::vector<WorldInfo*> Worlds;
+
+#endif // WORLD_INFO_H
diff --git a/src/opengl1graphics.cpp b/src/opengl1graphics.cpp
new file mode 100644
index 000000000..acd4c9d13
--- /dev/null
+++ b/src/opengl1graphics.cpp
@@ -0,0 +1,603 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "log.h"
+#include "opengl1graphics.h"
+
+#include "resources/image.h"
+
+#ifdef USE_OPENGL
+
+#ifdef __APPLE__
+#include <OpenGL/OpenGL.h>
+#endif
+
+#include <SDL.h>
+
+#ifndef GL_TEXTURE_RECTANGLE_ARB
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+GLuint OpenGL1Graphics::mLastImage = 0;
+
+OpenGL1Graphics::OpenGL1Graphics():
+ mAlpha(false), mTexture(false), mColorAlpha(false),
+ mSync(false)
+{
+}
+
+OpenGL1Graphics::~OpenGL1Graphics()
+{
+}
+
+void OpenGL1Graphics::setSync(bool sync)
+{
+ mSync = sync;
+}
+
+bool OpenGL1Graphics::setVideoMode(int w, int h, int bpp,
+ bool fs, bool hwaccel)
+{
+ logger->log("Setting video mode %dx%d %s",
+ w, h, fs ? "fullscreen" : "windowed");
+
+ int displayFlags = SDL_ANYFORMAT | SDL_OPENGL;
+
+ mWidth = w;
+ mHeight = h;
+ mBpp = bpp;
+ mFullscreen = fs;
+ mHWAccel = hwaccel;
+
+ if (fs)
+ displayFlags |= SDL_FULLSCREEN;
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ if (!(mTarget = SDL_SetVideoMode(w, h, bpp, displayFlags)))
+ return false;
+
+#ifdef __APPLE__
+ if (mSync)
+ {
+ const GLint VBL = 1;
+ CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
+ }
+#endif
+
+ // Setup OpenGL
+ glViewport(0, 0, w, h);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ int gotDoubleBuffer;
+ SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gotDoubleBuffer);
+ logger->log("Using OpenGL %s double buffering.",
+ (gotDoubleBuffer ? "with" : "without"));
+
+ char const *glExtensions = (char const *)glGetString(GL_EXTENSIONS);
+ GLint texSize;
+ bool rectTex = strstr(glExtensions, "GL_ARB_texture_rectangle");
+ if (rectTex)
+ {
+ Image::mTextureType = GL_TEXTURE_RECTANGLE_ARB;
+ glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texSize);
+ }
+ else
+ {
+ Image::mTextureType = GL_TEXTURE_2D;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
+ }
+ Image::mTextureSize = texSize;
+ logger->log("OpenGL texture size: %d pixels%s", Image::mTextureSize,
+ rectTex ? " (rectangle textures)" : "");
+
+ return true;
+}
+
+static inline void drawQuad(Image *image,
+ int srcX, int srcY, int dstX, int dstY,
+ int width, int height)
+{
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ // Find OpenGL normalized texture coordinates.
+ float texX1 = srcX / (float) image->getTextureWidth();
+ float texY1 = srcY / (float) image->getTextureHeight();
+ float texX2 = (srcX + width) / (float) image->getTextureWidth();
+ float texY2 = (srcY + height) / (float) image->getTextureHeight();
+
+ glTexCoord2f(texX1, texY1);
+ glVertex2i(dstX, dstY);
+ glTexCoord2f(texX2, texY1);
+ glVertex2i(dstX + width, dstY);
+ glTexCoord2f(texX2, texY2);
+ glVertex2i(dstX + width, dstY + height);
+ glTexCoord2f(texX1, texY2);
+ glVertex2i(dstX, dstY + height);
+ }
+ else
+ {
+ glTexCoord2i(srcX, srcY);
+ glVertex2i(dstX, dstY);
+ glTexCoord2i(srcX + width, srcY);
+ glVertex2i(dstX + width, dstY);
+ glTexCoord2i(srcX + width, srcY + height);
+ glVertex2i(dstX + width, dstY + height);
+ glTexCoord2i(srcX, srcY + height);
+ glVertex2i(dstX, dstY + height);
+ }
+}
+
+static inline void drawRescaledQuad(Image *image, int srcX, int srcY,
+ int dstX, int dstY, int width, int height,
+ int desiredWidth, int desiredHeight)
+{
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ // Find OpenGL normalized texture coordinates.
+ float texX1 = srcX / (float) image->getTextureWidth();
+ float texY1 = srcY / (float) image->getTextureHeight();
+ float texX2 = (srcX + width) / (float) image->getTextureWidth();
+ float texY2 = (srcY + height) / (float) image->getTextureHeight();
+
+ glTexCoord2f(texX1, texY1);
+ glVertex2i(dstX, dstY);
+ glTexCoord2f(texX2, texY1);
+ glVertex2i(dstX + desiredWidth, dstY);
+ glTexCoord2f(texX2, texY2);
+ glVertex2i(dstX + desiredWidth, dstY + desiredHeight);
+ glTexCoord2f(texX1, texY2);
+ glVertex2i(dstX, dstY + desiredHeight);
+ }
+ else
+ {
+ glTexCoord2i(srcX, srcY);
+ glVertex2i(dstX, dstY);
+ glTexCoord2i(srcX + width, srcY);
+ glVertex2i(dstX + desiredWidth, dstY);
+ glTexCoord2i(srcX + width, srcY + height);
+ glVertex2i(dstX + desiredWidth, dstY + desiredHeight);
+ glTexCoord2i(srcX, srcY + height);
+ glVertex2i(dstX, dstY + desiredHeight);
+ }
+}
+
+
+bool OpenGL1Graphics::drawImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height, bool useColor)
+{
+ if (!image)
+ return false;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ if (!useColor)
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a textured quad.
+ glBegin(GL_QUADS);
+ drawQuad(image, srcX, srcY, dstX, dstY, width, height);
+ glEnd();
+
+ if (!useColor)
+ {
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+ }
+
+ return true;
+}
+
+bool OpenGL1Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor)
+{
+ return drawRescaledImage(image, srcX, srcY,
+ dstX, dstY,
+ width, height,
+ desiredWidth, desiredHeight,
+ useColor, true);
+}
+
+bool OpenGL1Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor, bool smooth)
+{
+ if (!image)
+ return false;
+
+ // Just draw the image normally when no resizing is necessary,
+ if (width == desiredWidth && height == desiredHeight)
+ {
+ return drawImage(image, srcX, srcY, dstX, dstY,
+ width, height, useColor);
+ }
+
+ // When the desired image is smaller than the current one,
+ // disable smooth effect.
+ if (width > desiredWidth && height > desiredHeight)
+ smooth = false;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ if (!useColor)
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a textured quad.
+ glBegin(GL_QUADS);
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY, width, height,
+ desiredWidth, desiredHeight);
+
+ if (smooth) // A basic smooth effect...
+ {
+ glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
+ drawRescaledQuad(image, srcX, srcY, dstX - 1, dstY - 1, width, height,
+ desiredWidth + 1, desiredHeight + 1);
+ drawRescaledQuad(image, srcX, srcY, dstX + 1, dstY + 1, width, height,
+ desiredWidth - 1, desiredHeight - 1);
+
+ drawRescaledQuad(image, srcX, srcY, dstX + 1, dstY, width, height,
+ desiredWidth - 1, desiredHeight);
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY + 1, width, height,
+ desiredWidth, desiredHeight - 1);
+ }
+
+ glEnd();
+
+ if (!useColor)
+ {
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+ }
+
+ return true;
+}
+
+/* Optimising the functions that Graphics::drawImagePattern would call,
+ * so that glBegin...glEnd are outside the main loop. */
+void OpenGL1Graphics::drawImagePattern(Image *image, int x, int y,
+ int w, int h)
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = image->getWidth();
+ const int ih = image->getHeight();
+ if (iw == 0 || ih == 0)
+ return;
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a set of textured rectangles
+ glBegin(GL_QUADS);
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ drawQuad(image, srcX, srcY, dstX, dstY, width, height);
+ }
+ }
+
+ glEnd();
+
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+}
+
+void OpenGL1Graphics::drawRescaledImagePattern(Image *image, int x, int y,
+ int w, int h,
+ int scaledWidth,
+ int scaledHeight)
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = scaledWidth;
+ const int ih = scaledHeight;
+ if (iw == 0 || ih == 0)
+ return;
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a set of textured rectangles
+ glBegin(GL_QUADS);
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY,
+ width, height, scaledWidth, scaledHeight);
+ }
+ }
+
+ glEnd();
+
+ glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
+}
+
+void OpenGL1Graphics::updateScreen()
+{
+ glFlush();
+ glFinish();
+ SDL_GL_SwapBuffers();
+}
+
+void OpenGL1Graphics::_beginDraw()
+{
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glOrtho(0.0, (double)mTarget->w, (double)mTarget->h, 0.0, -1.0, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ pushClipArea(gcn::Rectangle(0, 0, mTarget->w, mTarget->h));
+}
+
+void OpenGL1Graphics::_endDraw()
+{
+}
+
+SDL_Surface* OpenGL1Graphics::getScreenshot()
+{
+ int h = mTarget->h;
+ int w = mTarget->w;
+
+ SDL_Surface *screenshot = SDL_CreateRGBSurface(
+ SDL_SWSURFACE,
+ w, h, 24,
+ 0xff0000, 0x00ff00, 0x0000ff, 0x000000);
+
+ if (SDL_MUSTLOCK(screenshot))
+ SDL_LockSurface(screenshot);
+
+ // Grap the pixel buffer and write it to the SDL surface
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, screenshot->pixels);
+
+ // Flip the screenshot, as OpenGL has 0,0 in bottom left
+ unsigned int lineSize = 3 * w;
+ GLubyte* buf = (GLubyte*)malloc(lineSize);
+
+ for (int i = 0; i < (h / 2); i++)
+ {
+ GLubyte *top = (GLubyte*)screenshot->pixels + lineSize * i;
+ GLubyte *bot = (GLubyte*)screenshot->pixels + lineSize * (h - 1 - i);
+
+ memcpy(buf, top, lineSize);
+ memcpy(top, bot, lineSize);
+ memcpy(bot, buf, lineSize);
+ }
+
+ free(buf);
+
+ if (SDL_MUSTLOCK(screenshot))
+ SDL_UnlockSurface(screenshot);
+
+ return screenshot;
+}
+
+bool OpenGL1Graphics::pushClipArea(gcn::Rectangle area)
+{
+ int transX = 0;
+ int transY = 0;
+
+ if (!mClipStack.empty())
+ {
+ transX = -mClipStack.top().xOffset;
+ transY = -mClipStack.top().yOffset;
+ }
+
+ bool result = gcn::Graphics::pushClipArea(area);
+
+ transX += mClipStack.top().xOffset;
+ transY += mClipStack.top().yOffset;
+
+ glPushMatrix();
+ glTranslatef(static_cast<GLfloat>(transX),
+ static_cast<GLfloat>(transY), 0);
+ glScissor(mClipStack.top().x,
+ mTarget->h - mClipStack.top().y - mClipStack.top().height,
+ mClipStack.top().width,
+ mClipStack.top().height);
+
+ return result;
+}
+
+void OpenGL1Graphics::popClipArea()
+{
+ gcn::Graphics::popClipArea();
+
+ if (mClipStack.empty())
+ return;
+
+ glPopMatrix();
+ glScissor(mClipStack.top().x,
+ mTarget->h - mClipStack.top().y - mClipStack.top().height,
+ mClipStack.top().width,
+ mClipStack.top().height);
+}
+
+void OpenGL1Graphics::setColor(const gcn::Color& color)
+{
+ mColor = color;
+ glColor4ub(static_cast<GLubyte>(color.r),
+ static_cast<GLubyte>(color.g),
+ static_cast<GLubyte>(color.b),
+ static_cast<GLubyte>(color.a));
+
+ mColorAlpha = (color.a != 255);
+}
+
+void OpenGL1Graphics::drawPoint(int x, int y)
+{
+ setTexturingAndBlending(false);
+
+ glBegin(GL_POINTS);
+ glVertex2i(x, y);
+ glEnd();
+}
+
+void OpenGL1Graphics::drawLine(int x1, int y1, int x2, int y2)
+{
+ setTexturingAndBlending(false);
+
+ glBegin(GL_LINES);
+ glVertex2f(x1 + 0.5f, y1 + 0.5f);
+ glVertex2f(x2 + 0.5f, y2 + 0.5f);
+ glEnd();
+
+ glBegin(GL_POINTS);
+ glVertex2f(x2 + 0.5f, y2 + 0.5f);
+ glEnd();
+}
+
+void OpenGL1Graphics::drawRectangle(const gcn::Rectangle& rect)
+{
+ drawRectangle(rect, false);
+}
+
+void OpenGL1Graphics::fillRectangle(const gcn::Rectangle& rect)
+{
+ drawRectangle(rect, true);
+}
+
+void OpenGL1Graphics::setTargetPlane(int width _UNUSED_, int height _UNUSED_)
+{
+}
+
+void OpenGL1Graphics::setTexturingAndBlending(bool enable)
+{
+ if (enable)
+ {
+ if (!mTexture)
+ {
+ glEnable(Image::mTextureType);
+ mTexture = true;
+ }
+
+ if (!mAlpha)
+ {
+ glEnable(GL_BLEND);
+ mAlpha = true;
+ }
+ }
+ else
+ {
+ mLastImage = 0;
+ if (mAlpha && !mColorAlpha)
+ {
+ glDisable(GL_BLEND);
+ mAlpha = false;
+ }
+ else if (!mAlpha && mColorAlpha)
+ {
+ glEnable(GL_BLEND);
+ mAlpha = true;
+ }
+
+ if (mTexture)
+ {
+ glDisable(Image::mTextureType);
+ mTexture = false;
+ }
+ }
+}
+
+void OpenGL1Graphics::drawRectangle(const gcn::Rectangle& rect, bool filled)
+{
+ const float offset = filled ? 0 : 0.5f;
+
+ setTexturingAndBlending(false);
+
+ glBegin(filled ? GL_QUADS : GL_LINE_LOOP);
+ glVertex2f(rect.x + offset, rect.y + offset);
+ glVertex2f(rect.x + rect.width - offset, rect.y + offset);
+ glVertex2f(rect.x + rect.width - offset, rect.y + rect.height - offset);
+ glVertex2f(rect.x + offset, rect.y + rect.height - offset);
+ glEnd();
+}
+
+void OpenGL1Graphics::bindTexture(GLenum target, GLuint texture)
+{
+ if (mLastImage != texture)
+ {
+ mLastImage = texture;
+ glBindTexture(target, texture);
+ }
+}
+
+#endif // USE_OPENGL
diff --git a/src/opengl1graphics.h b/src/opengl1graphics.h
new file mode 100644
index 000000000..4869244ef
--- /dev/null
+++ b/src/opengl1graphics.h
@@ -0,0 +1,133 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef OPENGL1GRAPHICS_H
+#define OPENGL1GRAPHICS_H
+
+#include "main.h"
+
+#include "graphics.h"
+
+#ifdef USE_OPENGL
+#define NO_SDL_GLEXT
+
+#include <SDL_opengl.h>
+#endif
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class OpenGL1Graphics : public Graphics
+{
+ public:
+ OpenGL1Graphics();
+
+ ~OpenGL1Graphics();
+
+ /**
+ * Sets whether vertical refresh syncing is enabled. Takes effect after
+ * the next call to setVideoMode(). Only implemented on MacOS for now.
+ */
+ void setSync(bool sync);
+ bool getSync() const
+ { return mSync; }
+
+ bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+
+ bool drawImage(Image *image,
+ int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ bool useColor);
+
+ /**
+ * Draws a resclaled version of the image
+ */
+ bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor);
+
+ /**
+ * Used to get the smooth rescale option over the standard function.
+ */
+ bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor, bool smooth);
+
+ void drawImagePattern(Image *image,
+ int x, int y,
+ int w, int h);
+
+ /**
+ * Draw a pattern based on a rescaled version of the given image...
+ */
+ void drawRescaledImagePattern(Image *image,
+ int x, int y, int w, int h,
+ int scaledWidth, int scaledHeight);
+
+ void updateScreen();
+
+ void _beginDraw();
+ void _endDraw();
+
+ bool pushClipArea(gcn::Rectangle area);
+ void popClipArea();
+
+ void setColor(const gcn::Color &color);
+
+ void drawPoint(int x, int y);
+
+ void drawLine(int x1, int y1, int x2, int y2);
+
+ void drawRectangle(const gcn::Rectangle &rect, bool filled);
+
+ void drawRectangle(const gcn::Rectangle &rect);
+
+ void fillRectangle(const gcn::Rectangle &rect);
+
+ void setTargetPlane(int width, int height);
+
+ /**
+ * Takes a screenshot and returns it as SDL surface.
+ */
+ SDL_Surface *getScreenshot();
+
+ static void bindTexture(GLenum target, GLuint texture);
+
+ static GLuint mLastImage;
+
+ protected:
+ void setTexturingAndBlending(bool enable);
+
+ private:
+ bool mAlpha, mTexture;
+ bool mColorAlpha;
+ bool mSync;
+};
+
+#endif
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
new file mode 100644
index 000000000..f1bfffa35
--- /dev/null
+++ b/src/openglgraphics.cpp
@@ -0,0 +1,950 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "main.h"
+
+#ifdef USE_OPENGL
+
+#include "openglgraphics.h"
+
+#include "log.h"
+
+#include "resources/image.h"
+
+#include "utils/stringutils.h"
+
+#ifdef __APPLE__
+#include <OpenGL/OpenGL.h>
+#endif
+
+#include <SDL.h>
+
+#ifndef GL_TEXTURE_RECTANGLE_ARB
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+const unsigned int vertexBufSize = 500;
+
+GLuint OpenGLGraphics::mLastImage = 0;
+
+OpenGLGraphics::OpenGLGraphics():
+ mAlpha(false), mTexture(false), mColorAlpha(false),
+ mSync(false)
+{
+ mFloatTexArray = new GLfloat[vertexBufSize * 4 + 30];
+ mIntTexArray = new GLint[vertexBufSize * 4 + 30];
+ mIntVertArray = new GLint[vertexBufSize * 4 + 30];
+}
+
+OpenGLGraphics::~OpenGLGraphics()
+{
+ delete[] mFloatTexArray;
+ delete[] mIntTexArray;
+ delete[] mIntVertArray;
+}
+
+void OpenGLGraphics::setSync(bool sync)
+{
+ mSync = sync;
+}
+
+bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+{
+ logger->log("Setting video mode %dx%d %s",
+ w, h, fs ? "fullscreen" : "windowed");
+
+ int displayFlags = SDL_ANYFORMAT | SDL_OPENGL;
+
+ mWidth = w;
+ mHeight = h;
+ mBpp = bpp;
+ mFullscreen = fs;
+ mHWAccel = hwaccel;
+
+ if (fs)
+ displayFlags |= SDL_FULLSCREEN;
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ if (!(mTarget = SDL_SetVideoMode(w, h, bpp, displayFlags)))
+ return false;
+
+#ifdef __APPLE__
+ if (mSync)
+ {
+ const GLint VBL = 1;
+ CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
+ }
+#endif
+
+ // Setup OpenGL
+ glViewport(0, 0, w, h);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ int gotDoubleBuffer;
+ SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gotDoubleBuffer);
+ logger->log("Using OpenGL %s double buffering.",
+ (gotDoubleBuffer ? "with" : "without"));
+
+ char const *glExtensions = (char const *)glGetString(GL_EXTENSIONS);
+ GLint texSize;
+ bool rectTex = strstr(glExtensions, "GL_ARB_texture_rectangle");
+ if (rectTex)
+ {
+ Image::mTextureType = GL_TEXTURE_RECTANGLE_ARB;
+ glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texSize);
+ }
+ else
+ {
+ Image::mTextureType = GL_TEXTURE_2D;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
+ }
+ Image::mTextureSize = texSize;
+ logger->log("OpenGL texture size: %d pixels%s", Image::mTextureSize,
+ rectTex ? " (rectangle textures)" : "");
+
+ return true;
+}
+
+static inline void drawQuad(Image *image,
+ int srcX, int srcY, int dstX, int dstY,
+ int width, int height)
+{
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ // Find OpenGL normalized texture coordinates.
+ const float texX1 = static_cast<float>(srcX) /
+ static_cast<float>(image->getTextureWidth());
+ const float texY1 = static_cast<float>(srcY) /
+ static_cast<float>(image->getTextureHeight());
+ const float texX2 = static_cast<float>(srcX + width) /
+ static_cast<float>(image->getTextureWidth());
+ const float texY2 = static_cast<float>(srcY + height) /
+ static_cast<float>(image->getTextureHeight());
+
+ GLfloat tex[] =
+ {
+ texX1, texY1,
+ texX2, texY1,
+ texX2, texY2,
+ texX1, texY2
+ };
+
+ GLint vert[] =
+ {
+ dstX, dstY,
+ dstX + width, dstY,
+ dstX + width, dstY + height,
+ dstX, dstY + height
+ };
+
+ glVertexPointer(2, GL_FLOAT, 0, &vert);
+ glTexCoordPointer(2, GL_INT, 0, &tex);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+ }
+ else
+ {
+ GLint tex[] =
+ {
+ srcX, srcY,
+ srcX + width, srcY,
+ srcX + width, srcY + height,
+ srcX, srcY + height
+ };
+ GLint vert[] =
+ {
+ dstX, dstY,
+ dstX + width, dstY,
+ dstX + width, dstY + height,
+ dstX, dstY + height
+ };
+
+ glVertexPointer(2, GL_INT, 0, &vert);
+ glTexCoordPointer(2, GL_INT, 0, &tex);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+ }
+}
+
+static inline void drawRescaledQuad(Image *image,
+ int srcX, int srcY, int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight)
+{
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ // Find OpenGL normalized texture coordinates.
+ const float texX1 = static_cast<float>(srcX) /
+ static_cast<float>(image->getTextureWidth());
+ const float texY1 = static_cast<float>(srcY) /
+ static_cast<float>(image->getTextureHeight());
+ const float texX2 = static_cast<float>(srcX + width) /
+ static_cast<float>(image->getTextureWidth());
+ const float texY2 = static_cast<float>(srcY + height) /
+ static_cast<float>(image->getTextureHeight());
+
+ GLfloat tex[] =
+ {
+ texX1, texY1,
+ texX2, texY1,
+ texX2, texY2,
+ texX1, texY2
+ };
+
+ GLint vert[] =
+ {
+ dstX, dstY,
+ dstX + desiredWidth, dstY,
+ dstX + desiredWidth, dstY + desiredHeight,
+ dstX, dstY + desiredHeight
+ };
+
+ glVertexPointer(2, GL_FLOAT, 0, &vert);
+ glTexCoordPointer(2, GL_INT, 0, &tex);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+ }
+ else
+ {
+ GLint tex[] =
+ {
+ srcX, srcY,
+ srcX + width, srcY,
+ srcX + width, srcY + height,
+ srcX, srcY + height
+ };
+ GLint vert[] =
+ {
+ dstX, dstY,
+ dstX + desiredWidth, dstY,
+ dstX + desiredWidth, dstY + desiredHeight,
+ dstX, dstY + desiredHeight
+ };
+
+ glVertexPointer(2, GL_INT, 0, &vert);
+ glTexCoordPointer(2, GL_INT, 0, &tex);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+ }
+}
+
+
+bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height, bool useColor)
+{
+ if (!image)
+ return false;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ if (!useColor)
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ drawQuad(image, srcX, srcY, dstX, dstY, width, height);
+
+ if (!useColor)
+ {
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+ }
+
+ return true;
+}
+
+bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor)
+{
+ return drawRescaledImage(image, srcX, srcY,
+ dstX, dstY,
+ width, height,
+ desiredWidth, desiredHeight,
+ useColor, true);
+}
+
+bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor, bool smooth)
+{
+ if (!image)
+ return false;
+
+ // Just draw the image normally when no resizing is necessary,
+ if (width == desiredWidth && height == desiredHeight)
+ {
+ return drawImage(image, srcX, srcY, dstX, dstY,
+ width, height, useColor);
+ }
+
+ // When the desired image is smaller than the current one,
+ // disable smooth effect.
+ if (width > desiredWidth && height > desiredHeight)
+ smooth = false;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ if (!useColor)
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a textured quad.
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY, width, height,
+ desiredWidth, desiredHeight);
+
+ if (smooth) // A basic smooth effect...
+ {
+ glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
+ drawRescaledQuad(image, srcX, srcY, dstX - 1, dstY - 1, width, height,
+ desiredWidth + 1, desiredHeight + 1);
+ drawRescaledQuad(image, srcX, srcY, dstX + 1, dstY + 1, width, height,
+ desiredWidth - 1, desiredHeight - 1);
+
+ drawRescaledQuad(image, srcX, srcY, dstX + 1, dstY, width, height,
+ desiredWidth - 1, desiredHeight);
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY + 1, width, height,
+ desiredWidth, desiredHeight - 1);
+ }
+
+ if (!useColor)
+ {
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+ }
+
+ return true;
+}
+
+void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h)
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = image->getWidth();
+ const int ih = image->getHeight();
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ const float tw = static_cast<float>(image->getTextureWidth());
+ const float th = static_cast<float>(image->getTextureHeight());
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ unsigned int vp = 0;
+ const unsigned int vLimit = vertexBufSize * 4;
+ // Draw a set of textured rectangles
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ float texX1 = static_cast<float>(srcX) / tw;
+ float texY1 = static_cast<float>(srcY) / th;
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ float texX2 = static_cast<float>(srcX + width) / tw;
+ float texY2 = static_cast<float>(srcY + height) / th;
+
+ mFloatTexArray[vp + 0] = texX1;
+ mFloatTexArray[vp + 1] = texY1;
+
+ mFloatTexArray[vp + 2] = texX2;
+ mFloatTexArray[vp + 3] = texY1;
+
+ mFloatTexArray[vp + 4] = texX2;
+ mFloatTexArray[vp + 5] = texY2;
+
+ mFloatTexArray[vp + 6] = texX1;
+ mFloatTexArray[vp + 7] = texY2;
+
+ mIntVertArray[vp + 0] = dstX;
+ mIntVertArray[vp + 1] = dstY;
+
+ mIntVertArray[vp + 2] = dstX + width;
+ mIntVertArray[vp + 3] = dstY;
+
+ mIntVertArray[vp + 4] = dstX + width;
+ mIntVertArray[vp + 5] = dstY + height;
+
+ mIntVertArray[vp + 6] = dstX;
+ mIntVertArray[vp + 7] = dstY + height;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ drawQuadArrayfi(vp);
+ vp = 0;
+ }
+ }
+ }
+ if (vp > 0)
+ drawQuadArrayfi(vp);
+ }
+ else
+ {
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ mIntTexArray[vp + 0] = srcX;
+ mIntTexArray[vp + 1] = srcY;
+
+ mIntTexArray[vp + 2] = srcX + width;
+ mIntTexArray[vp + 3] = srcY;
+
+ mIntTexArray[vp + 4] = srcX + width;
+ mIntTexArray[vp + 5] = srcY + height;
+
+ mIntTexArray[vp + 6] = srcX;
+ mIntTexArray[vp + 7] = srcY + height;
+
+ mIntVertArray[vp + 0] = dstX;
+ mIntVertArray[vp + 1] = dstY;
+
+ mIntVertArray[vp + 2] = dstX + width;
+ mIntVertArray[vp + 3] = dstY;
+
+ mIntVertArray[vp + 4] = dstX + width;
+ mIntVertArray[vp + 5] = dstY + height;
+
+ mIntVertArray[vp + 6] = dstX;
+ mIntVertArray[vp + 7] = dstY + height;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ drawQuadArrayii(vp);
+ vp = 0;
+ }
+ }
+ }
+ if (vp > 0)
+ drawQuadArrayii(vp);
+ }
+
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+}
+
+void OpenGLGraphics::drawRescaledImagePattern(Image *image, int x, int y,
+ int w, int h, int scaledWidth,
+ int scaledHeight)
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = scaledWidth;
+ const int ih = scaledHeight;
+ if (iw == 0 || ih == 0)
+ return;
+
+ const float tw = static_cast<float>(image->getTextureWidth());
+ const float th = static_cast<float>(image->getTextureHeight());
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ bindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ unsigned int vp = 0;
+ const unsigned int vLimit = vertexBufSize * 4;
+
+ float texX1 = static_cast<float>(srcX) / tw;
+ float texY1 = static_cast<float>(srcY) / th;
+
+ // Draw a set of textured rectangles
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ float texX2 = static_cast<float>(srcX + width) / tw;
+ float texY2 = static_cast<float>(srcY + height) / th;
+
+ mFloatTexArray[vp + 0] = texX1;
+ mFloatTexArray[vp + 1] = texY1;
+
+ mFloatTexArray[vp + 2] = texX2;
+ mFloatTexArray[vp + 3] = texY1;
+
+ mFloatTexArray[vp + 4] = texX2;
+ mFloatTexArray[vp + 5] = texY2;
+
+ mFloatTexArray[vp + 6] = texX1;
+ mFloatTexArray[vp + 7] = texY2;
+
+ mIntVertArray[vp + 0] = dstX;
+ mIntVertArray[vp + 1] = dstY;
+
+ mIntVertArray[vp + 2] = dstX + scaledWidth;
+ mIntVertArray[vp + 3] = dstY;
+
+ mIntVertArray[vp + 4] = dstX + scaledWidth;
+ mIntVertArray[vp + 5] = dstY + scaledHeight;
+
+ mIntVertArray[vp + 6] = dstX;
+ mIntVertArray[vp + 7] = dstY + scaledHeight;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ drawQuadArrayfi(vp);
+ vp = 0;
+ }
+ }
+ }
+ if (vp > 0)
+ drawQuadArrayfi(vp);
+ }
+ else
+ {
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ mIntTexArray[vp + 0] = srcX;
+ mIntTexArray[vp + 1] = srcY;
+
+ mIntTexArray[vp + 2] = srcX + width;
+ mIntTexArray[vp + 3] = srcY;
+
+ mIntTexArray[vp + 4] = srcX + width;
+ mIntTexArray[vp + 5] = srcY + height;
+
+ mIntTexArray[vp + 6] = srcX;
+ mIntTexArray[vp + 7] = srcY + height;
+
+ mIntVertArray[vp + 0] = dstX;
+ mIntVertArray[vp + 1] = dstY;
+
+ mIntVertArray[vp + 2] = dstX + scaledWidth;
+ mIntVertArray[vp + 3] = dstY;
+
+ mIntVertArray[vp + 4] = dstX + scaledWidth;
+ mIntVertArray[vp + 5] = dstY + scaledHeight;
+
+ mIntVertArray[vp + 6] = dstX;
+ mIntVertArray[vp + 7] = dstY + scaledHeight;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ drawQuadArrayii(vp);
+ vp = 0;
+ }
+ }
+ }
+ if (vp > 0)
+ drawQuadArrayii(vp);
+ }
+
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+}
+
+void OpenGLGraphics::updateScreen()
+{
+ glFlush();
+ glFinish();
+ SDL_GL_SwapBuffers();
+}
+
+void OpenGLGraphics::_beginDraw()
+{
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glOrtho(0.0, (double)mTarget->w, (double)mTarget->h, 0.0, -1.0, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glEnable(GL_SCISSOR_TEST);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
+
+#ifndef __MINGW32__
+ glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
+#endif
+
+// glScalef(0.5f, 0.5f, 0.5f);
+
+ pushClipArea(gcn::Rectangle(0, 0, mTarget->w, mTarget->h));
+}
+
+void OpenGLGraphics::_endDraw()
+{
+}
+
+SDL_Surface* OpenGLGraphics::getScreenshot()
+{
+ int h = mTarget->h;
+ int w = mTarget->w;
+
+ SDL_Surface *screenshot = SDL_CreateRGBSurface(
+ SDL_SWSURFACE,
+ w, h, 24,
+ 0xff0000, 0x00ff00, 0x0000ff, 0x000000);
+
+ if (SDL_MUSTLOCK(screenshot))
+ SDL_LockSurface(screenshot);
+
+ // Grap the pixel buffer and write it to the SDL surface
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, screenshot->pixels);
+
+ // Flip the screenshot, as OpenGL has 0,0 in bottom left
+ unsigned int lineSize = 3 * w;
+ GLubyte* buf = (GLubyte*)malloc(lineSize);
+
+ for (int i = 0; i < (h / 2); i++)
+ {
+ GLubyte *top = (GLubyte*)screenshot->pixels + lineSize * i;
+ GLubyte *bot = (GLubyte*)screenshot->pixels + lineSize * (h - 1 - i);
+
+ memcpy(buf, top, lineSize);
+ memcpy(top, bot, lineSize);
+ memcpy(bot, buf, lineSize);
+ }
+
+ free(buf);
+
+ if (SDL_MUSTLOCK(screenshot))
+ SDL_UnlockSurface(screenshot);
+
+ return screenshot;
+}
+
+bool OpenGLGraphics::pushClipArea(gcn::Rectangle area)
+{
+ int transX = 0;
+ int transY = 0;
+
+ if (!mClipStack.empty())
+ {
+ transX = -mClipStack.top().xOffset;
+ transY = -mClipStack.top().yOffset;
+ }
+
+ bool result = gcn::Graphics::pushClipArea(area);
+
+ transX += mClipStack.top().xOffset;
+ transY += mClipStack.top().yOffset;
+
+ glPushMatrix();
+ glTranslatef(static_cast<GLfloat>(transX),
+ static_cast<GLfloat>(transY), 0);
+ glScissor(mClipStack.top().x,
+ mTarget->h - mClipStack.top().y - mClipStack.top().height,
+ mClipStack.top().width,
+ mClipStack.top().height);
+
+ return result;
+}
+
+void OpenGLGraphics::popClipArea()
+{
+ gcn::Graphics::popClipArea();
+
+ if (mClipStack.empty())
+ return;
+
+ glPopMatrix();
+ glScissor(mClipStack.top().x,
+ mTarget->h - mClipStack.top().y - mClipStack.top().height,
+ mClipStack.top().width,
+ mClipStack.top().height);
+}
+
+void OpenGLGraphics::setColor(const gcn::Color& color)
+{
+ mColor = color;
+ glColor4ub(static_cast<GLubyte>(color.r),
+ static_cast<GLubyte>(color.g),
+ static_cast<GLubyte>(color.b),
+ static_cast<GLubyte>(color.a));
+
+ mColorAlpha = (color.a != 255);
+}
+
+void OpenGLGraphics::drawPoint(int x, int y)
+{
+ setTexturingAndBlending(false);
+
+ glBegin(GL_POINTS);
+ glVertex2i(x, y);
+ glEnd();
+}
+
+void OpenGLGraphics::drawLine(int x1, int y1, int x2, int y2)
+{
+ setTexturingAndBlending(false);
+
+ float x3 = static_cast<float>(x2) + 0.5f;
+ float y3 = static_cast<float>(y2) + 0.5f;
+
+ glBegin(GL_LINES);
+ glVertex2f(static_cast<float>(x1) + 0.5f, static_cast<float>(y1) + 0.5f);
+ glVertex2f(x3, y3);
+ glEnd();
+
+ glBegin(GL_POINTS);
+ glVertex2f(x3, y3);
+ glEnd();
+}
+
+void OpenGLGraphics::drawRectangle(const gcn::Rectangle& rect)
+{
+ drawRectangle(rect, false);
+}
+
+void OpenGLGraphics::fillRectangle(const gcn::Rectangle& rect)
+{
+ drawRectangle(rect, true);
+}
+
+void OpenGLGraphics::setTargetPlane(int width _UNUSED_, int height _UNUSED_)
+{
+}
+
+void OpenGLGraphics::setTexturingAndBlending(bool enable)
+{
+ if (enable)
+ {
+ if (!mTexture)
+ {
+ glEnable(Image::mTextureType);
+ mTexture = true;
+ }
+
+ if (!mAlpha)
+ {
+ glEnable(GL_BLEND);
+ mAlpha = true;
+ }
+ }
+ else
+ {
+ mLastImage = 0;
+ if (mAlpha && !mColorAlpha)
+ {
+ glDisable(GL_BLEND);
+ mAlpha = false;
+ }
+ else if (!mAlpha && mColorAlpha)
+ {
+ glEnable(GL_BLEND);
+ mAlpha = true;
+ }
+
+ if (mTexture)
+ {
+ glDisable(Image::mTextureType);
+ mTexture = false;
+ }
+ }
+}
+
+void OpenGLGraphics::drawRectangle(const gcn::Rectangle& rect, bool filled)
+{
+ const float offset = filled ? 0 : 0.5f;
+ const float x = static_cast<float>(rect.x);
+ const float y = static_cast<float>(rect.y);
+ const float width = static_cast<float>(rect.width);
+ const float height = static_cast<float>(rect.height);
+
+ setTexturingAndBlending(false);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ GLfloat vert[] =
+ {
+ x + offset, y + offset,
+ x + width - offset, y + offset,
+ x + width - offset, y + height - offset,
+ x + offset, y + height - offset
+ };
+
+ glVertexPointer(2, GL_FLOAT, 0, &vert);
+ glDrawArrays(filled ? GL_QUADS : GL_LINE_LOOP, 0, 4);
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+bool OpenGLGraphics::drawNet(int x1, int y1, int x2, int y2,
+ int width, int height)
+{
+ unsigned int vp = 0;
+ const unsigned int vLimit = vertexBufSize * 4;
+
+ setTexturingAndBlending(false);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ const float xf1 = static_cast<float>(x1);
+ const float xf2 = static_cast<float>(x2);
+ const float yf1 = static_cast<float>(y1);
+ const float yf2 = static_cast<float>(y2);
+
+ for (int y = y1; y < y2; y += height)
+ {
+ mFloatTexArray[vp + 0] = xf1;
+ mFloatTexArray[vp + 1] = static_cast<float>(y);
+
+ mFloatTexArray[vp + 2] = xf2;
+ mFloatTexArray[vp + 3] = static_cast<float>(y);
+
+ vp += 4;
+ if (vp >= vLimit)
+ {
+ drawLineArrayf(vp);
+ vp = 0;
+ }
+ }
+
+ for (int x = x1; x < x2; x += width)
+ {
+ mFloatTexArray[vp + 0] = static_cast<float>(x);
+ mFloatTexArray[vp + 1] = yf1;
+
+ mFloatTexArray[vp + 2] = static_cast<float>(x);
+ mFloatTexArray[vp + 3] = yf2;
+
+ vp += 4;
+ if (vp >= vLimit)
+ {
+ drawLineArrayf(vp);
+ vp = 0;
+ }
+ }
+
+ if (vp > 0)
+ drawLineArrayf(vp);
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ return true;
+}
+
+void OpenGLGraphics::bindTexture(GLenum target, GLuint texture)
+{
+ if (mLastImage != texture)
+ {
+ mLastImage = texture;
+ glBindTexture(target, texture);
+ }
+}
+
+inline void OpenGLGraphics::drawQuadArrayfi(int size)
+{
+ glVertexPointer(2, GL_INT, 0, mIntVertArray);
+ glTexCoordPointer(2, GL_FLOAT, 0, mFloatTexArray);
+
+ glDrawArrays(GL_QUADS, 0, size / 2);
+}
+
+inline void OpenGLGraphics::drawQuadArrayii(int size)
+{
+ glVertexPointer(2, GL_INT, 0, mIntVertArray);
+ glTexCoordPointer(2, GL_INT, 0, mIntTexArray);
+
+ glDrawArrays(GL_QUADS, 0, size / 2);
+}
+
+inline void OpenGLGraphics::drawLineArrayi(int size)
+{
+ glVertexPointer(2, GL_INT, 0, mIntVertArray);
+
+ glDrawArrays(GL_LINES, 0, size / 2);
+}
+
+inline void OpenGLGraphics::drawLineArrayf(int size)
+{
+ glVertexPointer(2, GL_FLOAT, 0, mFloatTexArray);
+
+ glDrawArrays(GL_LINES, 0, size / 2);
+}
+
+#endif // USE_OPENGL
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
new file mode 100644
index 000000000..9740d9bca
--- /dev/null
+++ b/src/openglgraphics.h
@@ -0,0 +1,146 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef OPENGLGRAPHICS_H
+#define OPENGLGRAPHICS_H
+
+#include "main.h"
+
+#include "graphics.h"
+
+#ifdef USE_OPENGL
+#define NO_SDL_GLEXT
+
+#include <SDL_opengl.h>
+#endif
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class OpenGLGraphics : public Graphics
+{
+ public:
+ OpenGLGraphics();
+
+ ~OpenGLGraphics();
+
+ /**
+ * Sets whether vertical refresh syncing is enabled. Takes effect after
+ * the next call to setVideoMode(). Only implemented on MacOS for now.
+ */
+ void setSync(bool sync);
+ bool getSync() const
+ { return mSync; }
+
+ bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+
+ bool drawImage(Image *image,
+ int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ bool useColor);
+
+ /**
+ * Draws a resclaled version of the image
+ */
+ bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor);
+
+ /**
+ * Used to get the smooth rescale option over the standard function.
+ */
+ bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor, bool smooth);
+
+ void drawImagePattern(Image *image,
+ int x, int y,
+ int w, int h);
+
+ /**
+ * Draw a pattern based on a rescaled version of the given image...
+ */
+ void drawRescaledImagePattern(Image *image,
+ int x, int y, int w, int h,
+ int scaledWidth, int scaledHeight);
+
+ void updateScreen();
+
+ void _beginDraw();
+ void _endDraw();
+
+ bool pushClipArea(gcn::Rectangle area);
+ void popClipArea();
+
+ void setColor(const gcn::Color &color);
+
+ void drawPoint(int x, int y);
+
+ void drawLine(int x1, int y1, int x2, int y2);
+
+ void drawRectangle(const gcn::Rectangle &rect, bool filled);
+
+ void drawRectangle(const gcn::Rectangle &rect);
+
+ void fillRectangle(const gcn::Rectangle &rect);
+
+ void setTargetPlane(int width, int height);
+
+ void drawQuadArrayfi(int size);
+
+ void drawQuadArrayii(int size);
+
+ void drawLineArrayi(int size);
+
+ void drawLineArrayf(int size);
+
+ /**
+ * Takes a screenshot and returns it as SDL surface.
+ */
+ SDL_Surface *getScreenshot();
+
+ bool drawNet(int x1, int y1, int x2, int y2, int width, int height);
+
+ static void bindTexture(GLenum target, GLuint texture);
+
+ static GLuint mLastImage;
+
+ protected:
+ void setTexturingAndBlending(bool enable);
+
+ private:
+ GLfloat *mFloatTexArray;
+ GLint *mIntTexArray;
+ GLint *mIntVertArray;
+ bool mAlpha, mTexture;
+ bool mColorAlpha;
+ bool mSync;
+};
+
+#endif
diff --git a/src/particle.cpp b/src/particle.cpp
new file mode 100644
index 000000000..30ed7ea89
--- /dev/null
+++ b/src/particle.cpp
@@ -0,0 +1,450 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <algorithm>
+#include <cmath>
+
+#include "animationparticle.h"
+#include "configuration.h"
+#include "imageparticle.h"
+#include "log.h"
+#include "map.h"
+#include "particle.h"
+#include "particleemitter.h"
+#include "rotationalparticle.h"
+#include "textparticle.h"
+
+#include "resources/resourcemanager.h"
+
+#include "utils/dtor.h"
+#include "utils/mathutils.h"
+#include "utils/xml.h"
+
+#include <guichan/color.hpp>
+
+#include <algorithm>
+#include <cmath>
+
+#define SIN45 0.707106781f
+
+class Graphics;
+class Image;
+
+int Particle::particleCount = 0;
+int Particle::maxCount = 0;
+int Particle::fastPhysics = 0;
+int Particle::emitterSkip = 1;
+bool Particle::enabled = true;
+const float Particle::PARTICLE_SKY = 800.0f;
+
+Particle::Particle(Map *map):
+ mAlpha(1.0f),
+ mLifetimeLeft(-1),
+ mLifetimePast(0),
+ mFadeOut(0),
+ mFadeIn(0),
+ mAlive(ALIVE),
+ mAutoDelete(true),
+ mAllowSizeAdjust(false),
+ mDeathEffectConditions(0x00),
+ mGravity(0.0f),
+ mRandomness(0),
+ mBounce(0.0f),
+ mFollow(false),
+ mTarget(NULL),
+ mAcceleration(0.0f),
+ mInvDieDistance(-1.0f),
+ mMomentum(1.0f)
+{
+ setMap(map);
+ Particle::particleCount++;
+}
+
+Particle::~Particle()
+{
+ // Delete child emitters and child particles
+ clear();
+ //update particle count
+ Particle::particleCount--;
+}
+
+void Particle::setupEngine()
+{
+ Particle::maxCount = config.getIntValue("particleMaxCount");
+ Particle::fastPhysics = config.getIntValue("particleFastPhysics");
+ Particle::emitterSkip = config.getIntValue("particleEmitterSkip") + 1;
+ Particle::enabled = config.getBoolValue("particleeffects");
+ disableAutoDelete();
+ logger->log1("Particle engine set up");
+}
+
+bool Particle::draw(Graphics *, int, int) const
+{
+ return false;
+}
+
+bool Particle::update()
+{
+ if (!mMap)
+ return false;
+
+ if (mLifetimeLeft == 0 && mAlive == ALIVE)
+ mAlive = DEAD_TIMEOUT;
+
+ Vector oldPos = mPos;
+
+ if (mAlive == ALIVE)
+ {
+ //calculate particle movement
+ if (mMomentum != 1.0f)
+ mVelocity *= mMomentum;
+
+ if (mTarget && mAcceleration != 0.0f)
+ {
+ Vector dist = mPos - mTarget->getPosition();
+ dist.x *= SIN45;
+ float invHypotenuse;
+
+ switch (Particle::fastPhysics)
+ {
+ case 1:
+ invHypotenuse = fastInvSqrt(
+ dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
+ break;
+ case 2:
+ invHypotenuse = 0;
+ if (!dist.x)
+ break;
+
+ invHypotenuse = 2.0f / static_cast<float>(fabs(dist.x))
+ + static_cast<float>(fabs(dist.y))
+ + static_cast<float>(fabs(dist.z));
+ break;
+ default:
+ invHypotenuse = 1.0f / sqrt(
+ dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
+ break;
+ }
+
+ if (invHypotenuse)
+ {
+ if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance)
+ mAlive = DEAD_IMPACT;
+ float accFactor = invHypotenuse * mAcceleration;
+ mVelocity -= dist * accFactor;
+ }
+ }
+
+ if (mRandomness > 0)
+ {
+ mVelocity.x += (rand() % mRandomness - rand()
+ % mRandomness) / 1000.0f;
+ mVelocity.y += (rand() % mRandomness - rand()
+ % mRandomness) / 1000.0f;
+ mVelocity.z += (rand() % mRandomness - rand()
+ % mRandomness) / 1000.0f;
+ }
+
+ mVelocity.z -= mGravity;
+
+ // Update position
+ mPos.x += mVelocity.x;
+ mPos.y += mVelocity.y * SIN45;
+ mPos.z += mVelocity.z * SIN45;
+
+ // Update other stuff
+ if (mLifetimeLeft > 0)
+ mLifetimeLeft--;
+
+ mLifetimePast++;
+
+ if (mPos.z < 0.0f)
+ {
+ if (mBounce > 0.0f)
+ {
+ mPos.z *= -mBounce;
+ mVelocity *= mBounce;
+ mVelocity.z = -mVelocity.z;
+ }
+ else
+ {
+ mAlive = DEAD_FLOOR;
+ }
+ } else if (mPos.z > PARTICLE_SKY)
+ {
+ mAlive = DEAD_SKY;
+ }
+
+ // Update child emitters
+ if ((mLifetimePast - 1) % Particle::emitterSkip == 0)
+ {
+ for (EmitterIterator e = mChildEmitters.begin();
+ e != mChildEmitters.end(); e++)
+ {
+ Particles newParticles = (*e)->createParticles(mLifetimePast);
+ for (ParticleIterator p = newParticles.begin();
+ p != newParticles.end(); p++)
+ {
+ (*p)->moveBy(mPos);
+ mChildParticles.push_back (*p);
+ }
+ }
+ }
+ }
+
+ // create death effect when the particle died
+ if (mAlive != ALIVE && mAlive != DEAD_LONG_AGO)
+ {
+ if ((mAlive & mDeathEffectConditions) > 0x00 && !mDeathEffect.empty())
+ {
+ Particle* deathEffect = particleEngine->addEffect(
+ mDeathEffect, 0, 0);
+ if (deathEffect)
+ deathEffect->moveBy(mPos);
+ }
+ mAlive = DEAD_LONG_AGO;
+ }
+
+ Vector change = mPos - oldPos;
+
+ // Update child particles
+
+ for (ParticleIterator p = mChildParticles.begin();
+ p != mChildParticles.end(); )
+ {
+ //move particle with its parent if desired
+ if ((*p)->doesFollow())
+ (*p)->moveBy(change);
+
+ //update particle
+ if ((*p)->update())
+ {
+ p++;
+ }
+ else
+ {
+ delete (*p);
+ p = mChildParticles.erase(p);
+ }
+ }
+ if (mAlive != ALIVE && mChildParticles.empty() && mAutoDelete)
+ return false;
+
+ return true;
+}
+
+void Particle::moveBy(const Vector &change)
+{
+ mPos += change;
+ for (ParticleIterator p = mChildParticles.begin();
+ p != mChildParticles.end(); p++)
+ {
+ if ((*p)->doesFollow())
+ (*p)->moveBy(change);
+ }
+}
+
+void Particle::moveTo(float x, float y)
+{
+ moveTo(Vector(x, y, mPos.z));
+}
+
+Particle *Particle::createChild()
+{
+ Particle *newParticle = new Particle(mMap);
+ mChildParticles.push_back(newParticle);
+ return newParticle;
+}
+
+Particle *Particle::addEffect(const std::string &particleEffectFile,
+ int pixelX, int pixelY, int rotation)
+{
+ Particle *newParticle = NULL;
+
+ XML::Document doc(particleEffectFile);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "effect"))
+ {
+ logger->log("Error loading particle: %s", particleEffectFile.c_str());
+ return NULL;
+ }
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ // Parse particles
+ for_each_xml_child_node(effectChildNode, rootNode)
+ {
+ // We're only interested in particles
+ if (!xmlStrEqual(effectChildNode->name, BAD_CAST "particle"))
+ continue;
+
+ // Determine the exact particle type
+ xmlNodePtr node;
+
+ // Animation
+ if ((node = XML::findFirstChildByName(effectChildNode, "animation")))
+ {
+ newParticle = new AnimationParticle(mMap, node);
+ }
+ // Rotational
+ else if ((node = XML::findFirstChildByName(
+ effectChildNode, "rotation")))
+ {
+ newParticle = new RotationalParticle(mMap, node);
+ }
+ // Image
+ else if ((node = XML::findFirstChildByName(effectChildNode, "image")))
+ {
+ Image *img = resman->getImage((const char*)
+ node->xmlChildrenNode->content);
+
+ newParticle = new ImageParticle(mMap, img);
+ }
+ // Other
+ else
+ {
+ newParticle = new Particle(mMap);
+ }
+
+ // Read and set the basic properties of the particle
+ float offsetX = XML::getFloatProperty(
+ effectChildNode, "position-x", 0);
+ float offsetY = XML::getFloatProperty(
+ effectChildNode, "position-y", 0);
+ float offsetZ = XML::getFloatProperty(
+ effectChildNode, "position-z", 0);
+ Vector position (mPos.x + (float)pixelX + offsetX,
+ mPos.y + (float)pixelY + offsetY,
+ mPos.z + offsetZ);
+ newParticle->moveTo(position);
+
+ int lifetime = XML::getProperty(effectChildNode, "lifetime", -1);
+ newParticle->setLifetime(lifetime);
+ bool resizeable = "false" != XML::getProperty(effectChildNode,
+ "size-adjustable", "false");
+
+ newParticle->setAllowSizeAdjust(resizeable);
+
+ // Look for additional emitters for this particle
+ for_each_xml_child_node(emitterNode, effectChildNode)
+ {
+ if (xmlStrEqual(emitterNode->name, BAD_CAST "emitter"))
+ {
+ ParticleEmitter *newEmitter;
+ newEmitter = new ParticleEmitter(
+ emitterNode, newParticle, mMap, rotation);
+ newParticle->addEmitter(newEmitter);
+ }
+ else if (xmlStrEqual(emitterNode->name, BAD_CAST "deatheffect"))
+ {
+ std::string deathEffect = (const char*)emitterNode
+ ->xmlChildrenNode->content;
+
+ char deathEffectConditions = 0x00;
+ if (XML::getBoolProperty(emitterNode, "on-floor", true))
+ {
+ deathEffectConditions += Particle::DEAD_FLOOR;
+ }
+ if (XML::getBoolProperty(emitterNode, "on-sky", true))
+ {
+ deathEffectConditions += Particle::DEAD_SKY;
+ }
+ if (XML::getBoolProperty(emitterNode, "on-other", false))
+ {
+ deathEffectConditions += Particle::DEAD_OTHER;
+ }
+ if (XML::getBoolProperty(emitterNode, "on-impact", true))
+ {
+ deathEffectConditions += Particle::DEAD_IMPACT;
+ }
+ if (XML::getBoolProperty(emitterNode, "on-timeout", true))
+ {
+ deathEffectConditions += Particle::DEAD_TIMEOUT;
+ }
+ newParticle->setDeathEffect(
+ deathEffect, deathEffectConditions);
+ }
+ }
+
+ mChildParticles.push_back(newParticle);
+ }
+
+ return newParticle;
+}
+
+Particle *Particle::addTextSplashEffect(const std::string &text, int x, int y,
+ const gcn::Color *color,
+ gcn::Font *font, bool outline)
+{
+ Particle *newParticle = new TextParticle(mMap, text, color, font, outline);
+ newParticle->moveTo(static_cast<float>(x), static_cast<float>(y));
+ newParticle->setVelocity(((rand() % 100) - 50) / 200.0f, // X
+ ((rand() % 100) - 50) / 200.0f, // Y
+ ((rand() % 100) / 200.0f) + 4.0f); // Z
+ newParticle->setGravity(0.1f);
+ newParticle->setBounce(0.5f);
+ newParticle->setLifetime(200);
+ newParticle->setFadeOut(100);
+
+ mChildParticles.push_back(newParticle);
+
+ return newParticle;
+}
+
+Particle *Particle::addTextRiseFadeOutEffect(const std::string &text,
+ int x, int y,
+ const gcn::Color *color,
+ gcn::Font *font, bool outline)
+{
+ Particle *newParticle = new TextParticle(mMap, text, color, font, outline);
+ newParticle->moveTo(static_cast<float>(x), static_cast<float>(y));
+ newParticle->setVelocity(0.0f, 0.0f, 0.5f);
+ newParticle->setGravity(0.0015f);
+ newParticle->setLifetime(300);
+ newParticle->setFadeOut(50);
+ newParticle->setFadeIn(200);
+
+ mChildParticles.push_back(newParticle);
+
+ return newParticle;
+}
+
+void Particle::adjustEmitterSize(int w, int h)
+{
+ if (mAllowSizeAdjust)
+ {
+ for (EmitterIterator e = mChildEmitters.begin();
+ e != mChildEmitters.end(); e++)
+ {
+ (*e)->adjustSize(w, h);
+ }
+ }
+}
+
+void Particle::clear()
+{
+ delete_all(mChildEmitters);
+ mChildEmitters.clear();
+
+ delete_all(mChildParticles);
+ mChildParticles.clear();
+}
diff --git a/src/particle.h b/src/particle.h
new file mode 100644
index 000000000..a512e1f61
--- /dev/null
+++ b/src/particle.h
@@ -0,0 +1,331 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PARTICLE_H
+#define PARTICLE_H
+
+#include "actor.h"
+#include "guichanfwd.h"
+#include "vector.h"
+
+#include <list>
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Map;
+class Particle;
+class ParticleEmitter;
+
+typedef std::list<Particle *> Particles;
+typedef Particles::iterator ParticleIterator;
+typedef std::list<ParticleEmitter *> Emitters;
+typedef Emitters::iterator EmitterIterator;
+
+/**
+ * A particle spawned by a ParticleEmitter.
+ */
+class Particle : public Actor
+{
+ public:
+ enum AliveStatus
+ {
+ ALIVE = 0,
+ DEAD_TIMEOUT = 1,
+ DEAD_FLOOR = 2,
+ DEAD_SKY = 4,
+ DEAD_IMPACT = 8,
+ DEAD_OTHER = 16,
+ DEAD_LONG_AGO = 128
+ };
+ static const float PARTICLE_SKY; /**< Maximum Z position
+ of particles */
+ static int fastPhysics; /**< Mode of squareroot calculation */
+ static int particleCount; /**< Current number of particles */
+ static int maxCount; /**< Maximum number of particles */
+ static int emitterSkip; /**< Duration of pause between two
+ emitter updates in ticks */
+ static bool enabled; /**< true when non-crucial particle effects
+ are disabled */
+
+ /**
+ * Constructor.
+ *
+ * @param map the map this particle will add itself to, may be NULL
+ */
+ Particle(Map *map);
+
+ /**
+ * Destructor.
+ */
+ ~Particle();
+
+ /**
+ * Deletes all child particles and emitters.
+ */
+ void clear();
+
+ /**
+ * Gives a particle the properties of an engine root particle and loads
+ * the particle-related config settings.
+ */
+ void setupEngine();
+
+ /**
+ * Updates particle position, returns false when the particle should
+ * be deleted.
+ */
+ virtual bool update();
+
+ /**
+ * Draws the particle image.
+ */
+ virtual bool draw(Graphics *graphics, int offsetX, int offsetY) const;
+
+ /**
+ * Necessary for sorting with the other sprites.
+ */
+ virtual int getPixelY() const
+ { return static_cast<int>(mPos.y + mPos.z) - 64; }
+
+ /**
+ * Creates a blank particle as a child of the current particle
+ * Useful for creating target particles
+ */
+ Particle *createChild();
+
+ /**
+ * Creates a child particle that hosts some emitters described in the
+ * particleEffectFile.
+ */
+ Particle *addEffect(const std::string &particleEffectFile,
+ int pixelX, int pixelY, int rotation = 0);
+
+ /**
+ * Creates a standalone text particle.
+ */
+ Particle *addTextSplashEffect(const std::string &text, int x, int y,
+ const gcn::Color *color, gcn::Font *font,
+ bool outline = false);
+
+ /**
+ * Creates a standalone text particle.
+ */
+ Particle *addTextRiseFadeOutEffect(const std::string &text,
+ int x, int y,
+ const gcn::Color *color,
+ gcn::Font *font,
+ bool outline = false);
+
+ /**
+ * Adds an emitter to the particle.
+ */
+ void addEmitter (ParticleEmitter* emitter)
+ { mChildEmitters.push_back(emitter); }
+
+ /**
+ * Sets the position in 3 dimensional space in pixels relative to map.
+ */
+ void moveTo(const Vector &pos)
+ { moveBy (pos - mPos); }
+
+ /**
+ * Sets the position in 2 dimensional space in pixels relative to map.
+ */
+ void moveTo(float x, float y);
+
+ /**
+ * Changes the particle position relative
+ */
+ void moveBy (const Vector &change);
+
+ /**
+ * Sets the time in game ticks until the particle is destroyed.
+ */
+ void setLifetime(int lifetime)
+ { mLifetimeLeft = lifetime; mLifetimePast = 0; }
+
+ /**
+ * Sets the age of the pixel in game ticks where the particle has
+ * faded in completely.
+ */
+ void setFadeOut(int fadeOut)
+ { mFadeOut = fadeOut; }
+
+ /**
+ * Sets the remaining particle lifetime where the particle starts to
+ * fade out.
+ */
+ void setFadeIn(int fadeIn)
+ { mFadeIn = fadeIn; }
+
+ /**
+ * Sets the current velocity in 3 dimensional space.
+ */
+ void setVelocity(float x, float y, float z)
+ { mVelocity.x = x; mVelocity.y = y; mVelocity.z = z; }
+
+ /**
+ * Sets the downward acceleration.
+ */
+ void setGravity(float gravity)
+ { mGravity = gravity; }
+
+ /**
+ * Sets the ammount of random vector changes
+ */
+ void setRandomness(int r)
+ { mRandomness = r; }
+
+ /**
+ * Sets the ammount of velocity particles retain after
+ * hitting the ground.
+ */
+ void setBounce(float bouncieness)
+ { mBounce = bouncieness; }
+
+ /**
+ * Sets the flag if the particle is supposed to be moved by its parent
+ */
+ void setFollow(bool follow)
+ { mFollow = follow; }
+
+ /**
+ * Gets the flag if the particle is supposed to be moved by its parent
+ */
+ bool doesFollow()
+ { return mFollow; }
+
+ /**
+ * Makes the particle move toward another particle with a
+ * given acceleration and momentum
+ */
+ void setDestination(Particle *target, float accel, float moment)
+ { mTarget = target; mAcceleration = accel; mMomentum = moment; }
+
+ /**
+ * Sets the distance in pixel the particle can come near the target
+ * particle before it is destroyed. Does only make sense after a target
+ * particle has been set using setDestination.
+ */
+ void setDieDistance(float dist)
+ { mInvDieDistance = 1.0f / dist; }
+
+ /**
+ * Changes the size of the emitters so that the effect fills a
+ * rectangle of this size
+ */
+ void adjustEmitterSize(int w, int h);
+
+ void setAllowSizeAdjust(bool adjust)
+ { mAllowSizeAdjust = adjust; }
+
+ bool isAlive() const
+ { return mAlive == ALIVE; }
+
+ /**
+ * Determines whether the particle and its children are all dead
+ */
+ bool isExtinct() const
+ { return !isAlive() && mChildParticles.empty(); }
+
+ /**
+ * Manually marks the particle for deletion.
+ */
+ void kill()
+ { mAlive = DEAD_OTHER; mAutoDelete = true; }
+
+ /**
+ * After calling this function the particle will only request
+ * deletion when kill() is called
+ */
+ void disableAutoDelete()
+ { mAutoDelete = false; }
+
+ /** We consider particles (at least for now) to be one layer-sprites */
+ virtual int getNumberOfLayers() const
+ { return 1; }
+
+ virtual float getAlpha() const
+ { return 1.0f; }
+
+ virtual void setAlpha(float alpha _UNUSED_) {}
+
+ virtual void setDeathEffect(const std::string &effectFile,
+ char conditions)
+ { mDeathEffect = effectFile; mDeathEffectConditions = conditions; }
+
+ protected:
+ float mAlpha; /**< Opacity of the graphical
+ representation of the particle */
+ int mLifetimeLeft; /**< Lifetime left in game ticks*/
+ int mLifetimePast; /**< Age of the particle in game ticks*/
+ int mFadeOut; /**< Lifetime in game ticks left where
+ fading out begins*/
+ int mFadeIn; /**< Age in game ticks where fading in is
+ finished*/
+ Vector mVelocity; /**< Speed in pixels per game-tick. */
+
+ private:
+ AliveStatus mAlive; /**< Is the particle supposed to be
+ drawn and updated?*/
+ // generic properties
+ bool mAutoDelete; /**< May the particle request its deletion
+ by the parent particle? */
+ Emitters mChildEmitters; /**< List of child emitters. */
+ Particles mChildParticles; /**< List of particles controlled by this
+ particle */
+ bool mAllowSizeAdjust; /**< Can the effect size be adjusted by
+ the object props in the map file? */
+ std::string mDeathEffect; /**< Particle effect file to be spawned
+ when the particle dies */
+ char mDeathEffectConditions; /**< Bitfield of death conditions which
+ trigger spawning of the death
+ particle */
+
+ // dynamic particle
+ float mGravity; /**< Downward acceleration in pixels per
+ game-tick. */
+ int mRandomness; /**< Ammount of random vector change */
+ float mBounce; /**< How much the particle bounces off when
+ hitting the ground */
+ bool mFollow; /**< is this particle moved when its parent
+ particle moves? */
+
+ // follow-point particles
+ Particle *mTarget; /**< The particle that attracts
+ this particle*/
+ float mAcceleration; /**< Acceleration towards the target
+ particle in pixels per game-tick*/
+ float mInvDieDistance; /**< Distance in pixels from the target
+ particle that causes the destruction
+ of the particle*/
+ float mMomentum; /**< How much speed the particle retains
+ after each game tick*/
+};
+
+extern Particle *particleEngine;
+
+#endif
diff --git a/src/particlecontainer.cpp b/src/particlecontainer.cpp
new file mode 100644
index 000000000..68e5f64e4
--- /dev/null
+++ b/src/particlecontainer.cpp
@@ -0,0 +1,189 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <cassert>
+
+#include "particle.h"
+#include "particlecontainer.h"
+
+ParticleContainer::ParticleContainer(ParticleContainer *parent,
+ bool delParent):
+ mDelParent(delParent),
+ mNext(parent)
+{}
+
+ParticleContainer::~ParticleContainer()
+{
+ clearLocally();
+ if (mDelParent)
+ {
+ delete mNext;
+ mNext = 0;
+ }
+}
+
+void ParticleContainer::clear()
+{
+ clearLocally();
+ if (mNext)
+ mNext->clear();
+}
+
+void ParticleContainer::moveTo(float x, float y)
+{
+ if (mNext)
+ mNext->moveTo(x, y);
+}
+
+// -- particle list ----------------------------------------
+
+ParticleList::ParticleList(ParticleContainer *parent, bool delParent):
+ ParticleContainer(parent, delParent)
+{}
+
+ParticleList::~ParticleList()
+{}
+
+void ParticleList::addLocally(Particle *particle)
+{
+ if (particle)
+ {
+ // The effect may not die without the beings permission or we segfault
+ particle->disableAutoDelete();
+ mElements.push_back(particle);
+ }
+}
+
+void ParticleList::removeLocally(Particle *particle)
+{
+ std::list<Particle *>::iterator it, it_end;
+ for (it = mElements.begin(), it_end = mElements.end();
+ it != it_end; )
+ {
+ if (*it == particle)
+ {
+ (*it)->kill();
+ it = mElements.erase(it);
+ }
+ else
+ {
+ it++;
+ }
+ }
+}
+
+void ParticleList::clearLocally()
+{
+ for (std::list<Particle *>::iterator it = mElements.begin();
+ it != mElements.end(); it++)
+ {
+ (*it)->kill();
+ }
+
+ mElements.clear();
+}
+
+void ParticleList::moveTo(float x, float y)
+{
+ ParticleContainer::moveTo(x, y);
+
+ for (std::list<Particle *>::iterator it = mElements.begin();
+ it != mElements.end(); )
+ {
+ (*it)->moveTo(x, y);
+ if ((*it)->isExtinct())
+ {
+ (*it)->kill();
+ it = mElements.erase(it);
+ }
+ else
+ {
+ it++;
+ }
+ }
+}
+
+// -- particle vector ----------------------------------------
+
+ParticleVector::ParticleVector(ParticleContainer *parent, bool delParent):
+ ParticleContainer(parent, delParent)
+{}
+
+ParticleVector::~ParticleVector()
+{}
+
+void ParticleVector::setLocally(int index, Particle *particle)
+{
+ if (index < 0)
+ return;
+
+ delLocally(index);
+
+ if (mIndexedElements.size() <= (unsigned) index)
+ mIndexedElements.resize(index + 1, NULL);
+
+ if (particle)
+ particle->disableAutoDelete();
+ mIndexedElements[index] = particle;
+}
+
+void ParticleVector::delLocally(int index)
+{
+ if (index < 0)
+ return;
+
+ if (mIndexedElements.size() <= (unsigned) index)
+ return;
+
+ Particle *p = mIndexedElements[index];
+ if (p)
+ {
+ mIndexedElements[index] = NULL;
+ p->kill();
+ }
+}
+
+void ParticleVector::clearLocally()
+{
+ for (unsigned int i = 0; i < mIndexedElements.size(); i++)
+ delLocally(i);
+}
+
+void ParticleVector::moveTo(float x, float y)
+{
+ ParticleContainer::moveTo(x, y);
+
+ for (std::vector<Particle *>::iterator it = mIndexedElements.begin();
+ it != mIndexedElements.end(); it++)
+ {
+ if (*it)
+ {
+ (*it)->moveTo(x, y);
+
+ if ((*it)->isExtinct())
+ {
+ (*it)->kill();
+ *it = NULL;
+ }
+ }
+ }
+}
+
diff --git a/src/particlecontainer.h b/src/particlecontainer.h
new file mode 100644
index 000000000..6502e4afd
--- /dev/null
+++ b/src/particlecontainer.h
@@ -0,0 +1,121 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PARTICLE_CONTAINER_H
+#define PARTICLE_CONTAINER_H
+
+#include <list>
+#include <vector>
+
+class Particle;
+
+/**
+ * Set of particle effects. May be stacked with other ParticleContainers. All
+ * operations herein affect such stacked containers, unless the operations end
+ * in `Locally'.
+ */
+class ParticleContainer
+{
+public:
+ /**
+ * Constructs a new particle container and assumes responsibility for
+ * its parent (for all operations defined herein, except when ending in `Locally')
+ *
+ * delParent means that the destructor should also free the parent.
+ */
+ ParticleContainer(ParticleContainer *parent = NULL, bool delParent = true);
+ virtual ~ParticleContainer();
+
+ /**
+ * Kills and removes all particle effects
+ */
+ void clear();
+
+ /**
+ * Kills and removes all particle effects (only in this container)
+ */
+ virtual void clearLocally() {}
+
+ /**
+ * Sets the positions of all elements
+ */
+ virtual void moveTo(float x, float y);
+
+protected:
+ bool mDelParent; /**< Delete mNext in destructor */
+ ParticleContainer *mNext; /**< Contained container, if any */
+};
+
+/**
+ * Linked list of particle effects.
+ */
+class ParticleList : public ParticleContainer
+{
+public:
+ ParticleList(ParticleContainer *parent = NULL, bool delParent = true);
+ virtual ~ParticleList();
+
+ /**
+ * Takes control of and adds a particle
+ */
+ void addLocally(Particle *);
+
+ /**
+ * `kills' and removes a particle
+ */
+ void removeLocally(Particle *);
+
+ virtual void clearLocally();
+
+ virtual void moveTo(float x, float y);
+
+protected:
+ std::list<Particle *> mElements; /**< Contained particle effects */
+};
+
+/**
+ * Particle container with indexing facilities
+ */
+class ParticleVector : public ParticleContainer
+{
+public:
+ ParticleVector(ParticleContainer *parent = NULL, bool delParent = true);
+ virtual ~ParticleVector();
+
+ /**
+ * Sets a particle at a specified index. Kills the previous particle
+ * there, if needed.
+ */
+ virtual void setLocally(int index, Particle *particle);
+
+ /**
+ * Removes a particle at a specified index
+ */
+ virtual void delLocally(int index);
+
+ virtual void clearLocally();
+ virtual void moveTo(float x, float y);
+
+protected:
+ std::vector<Particle *> mIndexedElements;
+};
+
+#endif
diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp
new file mode 100644
index 000000000..90b29422f
--- /dev/null
+++ b/src/particleemitter.cpp
@@ -0,0 +1,568 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "animationparticle.h"
+#include "imageparticle.h"
+#include "log.h"
+#include "particle.h"
+#include "particleemitter.h"
+#include "rotationalparticle.h"
+
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/resourcemanager.h"
+
+#include <cmath>
+
+#define SIN45 0.707106781f
+#define DEG_RAD_FACTOR 0.017453293f
+
+ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target,
+ Map *map, int rotation):
+ mOutputPauseLeft(0),
+ mParticleImage(0)
+{
+ mMap = map;
+ mParticleTarget = target;
+
+ // Initializing default values
+ mParticlePosX.set(0.0f);
+ mParticlePosY.set(0.0f);
+ mParticlePosZ.set(0.0f);
+ mParticleAngleHorizontal.set(0.0f);
+ mParticleAngleVertical.set(0.0f);
+ mParticlePower.set(0.0f);
+ mParticleGravity.set(0.0f);
+ mParticleRandomness.set(0);
+ mParticleBounce.set(0.0f);
+ mParticleFollow = false;
+ mParticleAcceleration.set(0.0f);
+ mParticleDieDistance.set(-1.0f);
+ mParticleMomentum.set(1.0f);
+ mParticleLifetime.set(-1);
+ mParticleFadeOut.set(0);
+ mParticleFadeIn.set(0);
+ mOutput.set(1);
+ mOutputPause.set(0);
+ mParticleAlpha.set(1.0f);
+
+ for_each_xml_child_node(propertyNode, emitterNode)
+ {
+ if (xmlStrEqual(propertyNode->name, BAD_CAST "property"))
+ {
+ std::string name = XML::getProperty(propertyNode, "name", "");
+
+ if (name == "position-x")
+ {
+ mParticlePosX = readParticleEmitterProp(propertyNode, 0.0f);
+ }
+ else if (name == "position-y")
+ {
+
+ mParticlePosY = readParticleEmitterProp(propertyNode, 0.0f);
+ mParticlePosY.minVal *= SIN45;
+ mParticlePosY.maxVal *= SIN45;
+ mParticlePosY.changeAmplitude *= SIN45;
+ }
+ else if (name == "position-z")
+ {
+ mParticlePosZ = readParticleEmitterProp(propertyNode, 0.0f);
+ mParticlePosZ.minVal *= SIN45;
+ mParticlePosZ.maxVal *= SIN45;
+ mParticlePosZ.changeAmplitude *= SIN45;
+ }
+ else if (name == "image")
+ {
+ std::string image = XML::getProperty(
+ propertyNode, "value", "");
+ // Don't leak when multiple images are defined
+ if (!image.empty() && !mParticleImage)
+ {
+ ResourceManager *resman = ResourceManager::getInstance();
+ mParticleImage = resman->getImage(image);
+ }
+ }
+ else if (name == "horizontal-angle")
+ {
+ mParticleAngleHorizontal =
+ readParticleEmitterProp(propertyNode, 0.0f);
+ mParticleAngleHorizontal.minVal
+ += static_cast<float>(rotation);
+ mParticleAngleHorizontal.minVal *= DEG_RAD_FACTOR;
+ mParticleAngleHorizontal.maxVal
+ += static_cast<float>(rotation);
+ mParticleAngleHorizontal.maxVal *= DEG_RAD_FACTOR;
+ mParticleAngleHorizontal.changeAmplitude *= DEG_RAD_FACTOR;
+ }
+ else if (name == "vertical-angle")
+ {
+ mParticleAngleVertical =
+ readParticleEmitterProp(propertyNode, 0.0f);
+ mParticleAngleVertical.minVal *= DEG_RAD_FACTOR;
+ mParticleAngleVertical.maxVal *= DEG_RAD_FACTOR;
+ mParticleAngleVertical.changeAmplitude *= DEG_RAD_FACTOR;
+ }
+ else if (name == "power")
+ {
+ mParticlePower = readParticleEmitterProp(propertyNode, 0.0f);
+ }
+ else if (name == "gravity")
+ {
+ mParticleGravity = readParticleEmitterProp(propertyNode, 0.0f);
+ }
+ else if (name == "randomnes" || name == "randomness") // legacy bug
+ {
+ mParticleRandomness = readParticleEmitterProp(propertyNode, 0);
+ }
+ else if (name == "bounce")
+ {
+ mParticleBounce = readParticleEmitterProp(propertyNode, 0.0f);
+ }
+ else if (name == "lifetime")
+ {
+ mParticleLifetime = readParticleEmitterProp(propertyNode, 0);
+ mParticleLifetime.minVal += 1;
+ }
+ else if (name == "output")
+ {
+ mOutput = readParticleEmitterProp(propertyNode, 0);
+ mOutput.maxVal += 1;
+ }
+ else if (name == "output-pause")
+ {
+ mOutputPause = readParticleEmitterProp(propertyNode, 0);
+ mOutputPauseLeft = mOutputPause.value(0);
+ }
+ else if (name == "acceleration")
+ {
+ mParticleAcceleration = readParticleEmitterProp(
+ propertyNode, 0.0f);
+ }
+ else if (name == "die-distance")
+ {
+ mParticleDieDistance = readParticleEmitterProp(
+ propertyNode, 0.0f);
+ }
+ else if (name == "momentum")
+ {
+ mParticleMomentum = readParticleEmitterProp(
+ propertyNode, 1.0f);
+ }
+ else if (name == "fade-out")
+ {
+ mParticleFadeOut = readParticleEmitterProp(propertyNode, 0);
+ }
+ else if (name == "fade-in")
+ {
+ mParticleFadeIn = readParticleEmitterProp(propertyNode, 0);
+ }
+ else if (name == "alpha")
+ {
+ mParticleAlpha = readParticleEmitterProp(propertyNode, 1.0f);
+ }
+ else if (name == "follow-parent")
+ {
+ mParticleFollow = true;
+ }
+ else
+ {
+ logger->log("Particle Engine: Warning, "
+ "unknown emitter property \"%s\"",
+ name.c_str());
+ }
+ }
+ else if (xmlStrEqual(propertyNode->name, BAD_CAST "emitter"))
+ {
+ ParticleEmitter newEmitter(propertyNode, mParticleTarget, map);
+ mParticleChildEmitters.push_back(newEmitter);
+ }
+ else if (xmlStrEqual(propertyNode->name, BAD_CAST "rotation"))
+ {
+ ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
+ XML::getProperty(propertyNode, "imageset", ""),
+ XML::getProperty(propertyNode, "width", 0),
+ XML::getProperty(propertyNode, "height", 0)
+ );
+
+ if (!imageset)
+ {
+ logger->log1("Error: no valid imageset");
+ continue;
+ }
+
+ // Get animation frames
+ for_each_xml_child_node(frameNode, propertyNode)
+ {
+ int delay = XML::getProperty(frameNode, "delay", 0);
+ int offsetX = XML::getProperty(frameNode, "offsetX", 0);
+ int offsetY = XML::getProperty(frameNode, "offsetY", 0);
+ if (!imageset)
+ {
+ logger->log1("Error: no valid imageset");
+ continue;
+ }
+
+ offsetY -= imageset->getHeight() - 32;
+ offsetX -= imageset->getWidth() / 2 - 16;
+
+ if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
+ {
+ int index = XML::getProperty(frameNode, "index", -1);
+
+ if (index < 0)
+ {
+ logger->log1("No valid value for 'index'");
+ continue;
+ }
+
+ Image *img = imageset->get(index);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", index);
+ continue;
+ }
+
+ mParticleRotation.addFrame(img, delay, offsetX, offsetY);
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
+ {
+ int start = XML::getProperty(frameNode, "start", -1);
+ int end = XML::getProperty(frameNode, "end", -1);
+
+ if (start < 0 || end < 0)
+ {
+ logger->log1("No valid value for 'start' or 'end'");
+ continue;
+ }
+
+ while (end >= start)
+ {
+ Image *img = imageset->get(start);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", start);
+ continue;
+ }
+
+ mParticleRotation.addFrame(img, delay,
+ offsetX, offsetY);
+ start++;
+ }
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "end"))
+ {
+ mParticleRotation.addTerminator();
+ }
+ } // for frameNode
+ }
+ else if (xmlStrEqual(propertyNode->name, BAD_CAST "animation"))
+ {
+ ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
+ XML::getProperty(propertyNode, "imageset", ""),
+ XML::getProperty(propertyNode, "width", 0),
+ XML::getProperty(propertyNode, "height", 0)
+ );
+
+ if (!imageset)
+ {
+ logger->log1("Error: no valid imageset");
+ continue;
+ }
+
+ // Get animation frames
+ for_each_xml_child_node(frameNode, propertyNode)
+ {
+ int delay = XML::getProperty(frameNode, "delay", 0);
+ int offsetX = XML::getProperty(frameNode, "offsetX", 0);
+ int offsetY = XML::getProperty(frameNode, "offsetY", 0);
+ offsetY -= imageset->getHeight() - 32;
+ offsetX -= imageset->getWidth() / 2 - 16;
+
+ if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
+ {
+ int index = XML::getProperty(frameNode, "index", -1);
+
+ if (index < 0)
+ {
+ logger->log1("No valid value for 'index'");
+ continue;
+ }
+
+ Image *img = imageset->get(index);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", index);
+ continue;
+ }
+
+ mParticleAnimation.addFrame(img, delay, offsetX, offsetY);
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
+ {
+ int start = XML::getProperty(frameNode, "start", -1);
+ int end = XML::getProperty(frameNode, "end", -1);
+
+ if (start < 0 || end < 0)
+ {
+ logger->log1("No valid value for 'start' or 'end'");
+ continue;
+ }
+
+ while (end >= start)
+ {
+ Image *img = imageset->get(start);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", start);
+ continue;
+ }
+
+ mParticleAnimation.addFrame(img, delay,
+ offsetX, offsetY);
+ start++;
+ }
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "end"))
+ {
+ mParticleAnimation.addTerminator();
+ }
+ } // for frameNode
+ }
+ else if (xmlStrEqual(propertyNode->name, BAD_CAST "deatheffect"))
+ {
+ mDeathEffect = (const char*)propertyNode->xmlChildrenNode->content;
+ mDeathEffectConditions = 0x00;
+ if (XML::getBoolProperty(propertyNode, "on-floor", true))
+ mDeathEffectConditions += Particle::DEAD_FLOOR;
+ if (XML::getBoolProperty(propertyNode, "on-sky", true))
+ mDeathEffectConditions += Particle::DEAD_SKY;
+ if (XML::getBoolProperty(propertyNode, "on-other", false))
+ mDeathEffectConditions += Particle::DEAD_OTHER;
+ if (XML::getBoolProperty(propertyNode, "on-impact", true))
+ mDeathEffectConditions += Particle::DEAD_IMPACT;
+ if (XML::getBoolProperty(propertyNode, "on-timeout", true))
+ mDeathEffectConditions += Particle::DEAD_TIMEOUT;
+ }
+ }
+}
+
+ParticleEmitter::ParticleEmitter(const ParticleEmitter &o)
+{
+ *this = o;
+}
+
+ParticleEmitter & ParticleEmitter::operator=(const ParticleEmitter &o)
+{
+ mParticlePosX = o.mParticlePosX;
+ mParticlePosY = o.mParticlePosY;
+ mParticlePosZ = o.mParticlePosZ;
+ mParticleAngleHorizontal = o.mParticleAngleHorizontal;
+ mParticleAngleVertical = o.mParticleAngleVertical;
+ mParticlePower = o.mParticlePower;
+ mParticleGravity = o.mParticleGravity;
+ mParticleRandomness = o.mParticleRandomness;
+ mParticleBounce = o.mParticleBounce;
+ mParticleFollow = o.mParticleFollow;
+ mParticleTarget = o.mParticleTarget;
+ mParticleAcceleration = o.mParticleAcceleration;
+ mParticleDieDistance = o.mParticleDieDistance;
+ mParticleMomentum = o.mParticleMomentum;
+ mParticleLifetime = o.mParticleLifetime;
+ mParticleFadeOut = o.mParticleFadeOut;
+ mParticleFadeIn = o.mParticleFadeIn;
+ mParticleAlpha = o.mParticleAlpha;
+ mMap = o.mMap;
+ mOutput = o.mOutput;
+ mOutputPause = o.mOutputPause;
+ mParticleImage = o.mParticleImage;
+ mParticleAnimation = o.mParticleAnimation;
+ mParticleRotation = o.mParticleRotation;
+ mParticleChildEmitters = o.mParticleChildEmitters;
+ mDeathEffectConditions = o.mDeathEffectConditions;
+
+ mOutputPauseLeft = 0;
+
+ if (mParticleImage)
+ mParticleImage->incRef();
+
+ return *this;
+}
+
+
+ParticleEmitter::~ParticleEmitter()
+{
+ if (mParticleImage)
+ mParticleImage->decRef();
+}
+
+
+template <typename T> ParticleEmitterProp<T>
+ParticleEmitter::readParticleEmitterProp(xmlNodePtr propertyNode, T def)
+{
+ ParticleEmitterProp<T> retval;
+
+ def = (T) XML::getFloatProperty(propertyNode, "value", (double) def);
+ retval.set((T) XML::getFloatProperty(propertyNode, "min", (double) def),
+ (T) XML::getFloatProperty(propertyNode, "max", (double) def));
+
+ std::string change = XML::getProperty(propertyNode, "change-func", "none");
+ T amplitude = (T) XML::getFloatProperty(propertyNode,
+ "change-amplitude", 0.0);
+ int period = XML::getProperty(propertyNode, "change-period", 0);
+ int phase = XML::getProperty(propertyNode, "change-phase", 0);
+ if (change == "saw" || change == "sawtooth")
+ retval.setFunction(FUNC_SAW, amplitude, period, phase);
+ else if (change == "sine" || change == "sinewave")
+ retval.setFunction(FUNC_SINE, amplitude, period, phase);
+ else if (change == "triangle")
+ retval.setFunction(FUNC_TRIANGLE, amplitude, period, phase);
+ else if (change == "square")
+ retval.setFunction(FUNC_SQUARE, amplitude, period, phase);
+
+ return retval;
+}
+
+
+std::list<Particle *> ParticleEmitter::createParticles(int tick)
+{
+ std::list<Particle *> newParticles;
+
+ if (mOutputPauseLeft > 0)
+ {
+ mOutputPauseLeft--;
+ return newParticles;
+ }
+ mOutputPauseLeft = mOutputPause.value(tick);
+
+ for (int i = mOutput.value(tick); i > 0; i--)
+ {
+ // Limit maximum particles
+ if (Particle::particleCount > Particle::maxCount)
+ break;
+
+ Particle *newParticle;
+ if (mParticleImage)
+ {
+ std::string name = mParticleImage->getIdPath();
+ if (ImageParticle::imageParticleCountByName.find(name) ==
+ ImageParticle::imageParticleCountByName.end())
+ {
+ ImageParticle::imageParticleCountByName[name] = 0;
+ }
+
+ if (ImageParticle::imageParticleCountByName[name] > 200)
+ break;
+
+ newParticle = new ImageParticle(mMap, mParticleImage);
+ }
+ else if (mParticleRotation.getLength() > 0)
+ {
+ Animation *newAnimation = new Animation(mParticleRotation);
+ newParticle = new RotationalParticle(mMap, newAnimation);
+ }
+ else if (mParticleAnimation.getLength() > 0)
+ {
+ Animation *newAnimation = new Animation(mParticleAnimation);
+ newParticle = new AnimationParticle(mMap, newAnimation);
+ }
+ else
+ {
+ newParticle = new Particle(mMap);
+ }
+
+ Vector position(mParticlePosX.value(tick),
+ mParticlePosY.value(tick),
+ mParticlePosZ.value(tick));
+ newParticle->moveTo(position);
+
+ float angleH = mParticleAngleHorizontal.value(tick);
+ float angleV = mParticleAngleVertical.value(tick);
+ float power = mParticlePower.value(tick);
+ newParticle->setVelocity(
+ static_cast<float>(cos(angleH) * cos(angleV) * power),
+ static_cast<float>(sin(angleH) * cos(angleV) * power),
+ static_cast<float>(sin(angleV) * power));
+
+ newParticle->setRandomness(mParticleRandomness.value(tick));
+ newParticle->setGravity(mParticleGravity.value(tick));
+ newParticle->setBounce(mParticleBounce.value(tick));
+ newParticle->setFollow(mParticleFollow);
+
+ newParticle->setDestination(mParticleTarget,
+ mParticleAcceleration.value(tick),
+ mParticleMomentum.value(tick)
+ );
+ newParticle->setDieDistance(mParticleDieDistance.value(tick));
+
+ newParticle->setLifetime(mParticleLifetime.value(tick));
+ newParticle->setFadeOut(mParticleFadeOut.value(tick));
+ newParticle->setFadeIn(mParticleFadeIn.value(tick));
+ newParticle->setAlpha(mParticleAlpha.value(tick));
+
+ for (std::list<ParticleEmitter>::iterator
+ i = mParticleChildEmitters.begin();
+ i != mParticleChildEmitters.end(); i++)
+ {
+ newParticle->addEmitter(new ParticleEmitter(*i));
+ }
+
+ if (!mDeathEffect.empty())
+ {
+ newParticle->setDeathEffect(mDeathEffect, mDeathEffectConditions);
+ }
+
+ newParticles.push_back(newParticle);
+ }
+
+ return newParticles;
+}
+
+void ParticleEmitter::adjustSize(int w, int h)
+{
+ if (w == 0 || h == 0)
+ return; // new dimensions are illegal
+
+ // calculate the old rectangle
+ int oldWidth = static_cast<int>(mParticlePosX.maxVal
+ - mParticlePosX.minVal);
+ int oldHeight = static_cast<int>(mParticlePosX.maxVal
+ - mParticlePosY.minVal);
+ int oldArea = oldWidth * oldHeight;
+ if (oldArea == 0)
+ {
+ //when the effect has no dimension it is
+ //not designed to be resizeable
+ return;
+ }
+
+ // set the new dimensions
+ mParticlePosX.set(0, static_cast<float>(w));
+ mParticlePosY.set(0, static_cast<float>(h));
+ int newArea = w * h;
+ // adjust the output so that the particle density stays the same
+ float outputFactor = (float)newArea / (float)oldArea;
+ mOutput.minVal *= static_cast<float>(outputFactor);
+ mOutput.maxVal *= static_cast<float>(outputFactor);
+}
diff --git a/src/particleemitter.h b/src/particleemitter.h
new file mode 100644
index 000000000..dd67ca62f
--- /dev/null
+++ b/src/particleemitter.h
@@ -0,0 +1,153 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PARTICLEEMITTER_H
+#define PARTICLEEMITTER_H
+
+#include "particleemitterprop.h"
+
+#include "resources/animation.h"
+
+#include "utils/xml.h"
+
+#include <list>
+
+class Image;
+class Map;
+class Particle;
+
+/**
+ * Every Particle can have one or more particle emitters that create new
+ * particles when they are updated
+ */
+class ParticleEmitter
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ParticleEmitter(xmlNodePtr emitterNode, Particle *target,
+ Map *map, int rotation = 0);
+
+ /**
+ * Copy Constructor (necessary for reference counting of particle images)
+ */
+ ParticleEmitter(const ParticleEmitter &o);
+
+ /**
+ * Assignment operator that calls the copy constructor
+ */
+ ParticleEmitter & operator=(const ParticleEmitter &o);
+
+ /**
+ * Destructor.
+ */
+ ~ParticleEmitter();
+
+ /**
+ * Spawns new particles
+ * @return: a list of created particles
+ */
+ std::list<Particle *> createParticles(int tick);
+
+ /**
+ * Sets the target of the particles that are created
+ */
+ void setTarget(Particle *target)
+ { mParticleTarget = target; };
+
+ /**
+ * Changes the size of the emitter so that the effect fills a
+ * rectangle of this size
+ */
+ void adjustSize(int w, int h);
+
+ private:
+ template <typename T> ParticleEmitterProp<T>
+ readParticleEmitterProp(xmlNodePtr propertyNode, T def);
+
+ /**
+ * initial position of particles:
+ */
+ ParticleEmitterProp<float> mParticlePosX, mParticlePosY, mParticlePosZ;
+
+ /**
+ * initial vector of particles:
+ */
+ ParticleEmitterProp<float> mParticleAngleHorizontal,
+ mParticleAngleVertical;
+
+ /**
+ * Initial velocity of particles
+ */
+ ParticleEmitterProp<float> mParticlePower;
+
+ /*
+ * Vector changing of particles:
+ */
+ ParticleEmitterProp<float> mParticleGravity;
+ ParticleEmitterProp<int> mParticleRandomness;
+ ParticleEmitterProp<float> mParticleBounce;
+ bool mParticleFollow;
+
+ /*
+ * Properties of targeting particles:
+ */
+ Particle *mParticleTarget;
+ ParticleEmitterProp<float> mParticleAcceleration;
+ ParticleEmitterProp<float> mParticleDieDistance;
+ ParticleEmitterProp<float> mParticleMomentum;
+
+ /*
+ * Behavior over time of the particles:
+ */
+ ParticleEmitterProp<int> mParticleLifetime;
+ ParticleEmitterProp<int> mParticleFadeOut;
+ ParticleEmitterProp<int> mParticleFadeIn;
+
+ Map *mMap; /**< Map the particles are spawned on */
+
+ ParticleEmitterProp<int> mOutput; /**< Number of particles spawned
+ per update */
+ ParticleEmitterProp<int> mOutputPause; /**< Pause in frames between
+ two spawns */
+ int mOutputPauseLeft;
+
+ /*
+ * Graphical representation of the particles
+ */
+ Image *mParticleImage; /**< Particle image, if used */
+ Animation mParticleAnimation; /**< Filename of particle
+ animation file */
+ Animation mParticleRotation; /**< Filename of particle rotation file */
+ ParticleEmitterProp<float> mParticleAlpha; /**< Opacity of the
+ graphical representation of the particles */
+
+ /*
+ * Death effect of the particles
+ */
+ std::string mDeathEffect;
+ char mDeathEffectConditions;
+
+ /** List of emitters the spawned particles are equipped with */
+ std::list<ParticleEmitter> mParticleChildEmitters;
+};
+#endif
diff --git a/src/particleemitterprop.h b/src/particleemitterprop.h
new file mode 100644
index 000000000..a54bd0c2f
--- /dev/null
+++ b/src/particleemitterprop.h
@@ -0,0 +1,116 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <cmath>
+
+/**
+ * Returns a random numeric value that is larger than or equal min and smaller
+ * than max
+ */
+
+enum ChangeFunc
+{
+ FUNC_NONE = 0,
+ FUNC_SINE,
+ FUNC_SAW,
+ FUNC_TRIANGLE,
+ FUNC_SQUARE
+};
+
+template <typename T> struct ParticleEmitterProp
+{
+ ParticleEmitterProp():
+ minVal(0), maxVal(0), changeFunc(FUNC_NONE),
+ changeAmplitude(0), changePeriod(0), changePhase(0)
+ {
+ }
+
+ void set(T min, T max)
+ {
+ minVal = min;
+ maxVal = max;
+ }
+
+ void set(T val)
+ {
+ set(val, val);
+ }
+
+ void setFunction(ChangeFunc func, T amplitude, int period, int phase)
+ {
+ changeFunc = func;
+ changeAmplitude = amplitude;
+ changePeriod = period;
+ changePhase = phase;
+ }
+
+ T value(int tick)
+ {
+ tick += changePhase;
+ T val = (T) (minVal + (maxVal - minVal)
+ * (rand() / ((double) RAND_MAX + 1)));
+
+ switch (changeFunc)
+ {
+ case FUNC_SINE:
+ val += (T) std::sin(M_PI * 2 * ((double)(tick % changePeriod)
+ / (double)changePeriod)) * changeAmplitude;
+ break;
+ case FUNC_SAW:
+ val += (T) (changeAmplitude * ((double)(tick % changePeriod)
+ / (double)changePeriod)) * 2 - changeAmplitude;
+ break;
+ case FUNC_TRIANGLE:
+ if ((tick % changePeriod) * 2 < changePeriod)
+ {
+ val += changeAmplitude - (T)((tick % changePeriod)
+ / (double)changePeriod) * changeAmplitude * 4;
+ }
+ else
+ {
+ val += changeAmplitude * -3 + (T)((tick % changePeriod)
+ / (double)changePeriod) * changeAmplitude * 4;
+ // I have no idea why this works but it does
+ }
+ break;
+ case FUNC_SQUARE:
+ if ((tick % changePeriod) * 2 < changePeriod)
+ val += changeAmplitude;
+ else
+ val -= changeAmplitude;
+ break;
+ case FUNC_NONE:
+ default:
+ //nothing
+ break;
+ }
+
+ return val;
+ }
+
+ T minVal;
+ T maxVal;
+
+ ChangeFunc changeFunc;
+ T changeAmplitude;
+ int changePeriod;
+ int changePhase;
+};
diff --git a/src/party.cpp b/src/party.cpp
new file mode 100644
index 000000000..3ed7e08aa
--- /dev/null
+++ b/src/party.cpp
@@ -0,0 +1,258 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "party.h"
+
+#include "actorspritemanager.h"
+
+class SortPartyFunctor
+{
+ public:
+ bool operator() (PartyMember* p1, PartyMember* p2)
+ {
+ if (!p1 || !p2)
+ return false;
+ if (p1->getLeader())
+ return true;
+ if (p2->getLeader())
+ return false;
+
+ return p1->getName() < p2->getName();
+ }
+} partySorter;
+
+PartyMember::PartyMember(Party *party, int id, const std::string &name):
+ Avatar(name), mParty(party), mLeader(false)
+{
+ mId = id;
+}
+
+Party::PartyMap Party::parties;
+
+Party::Party(short id):
+ mCanInviteUsers(false)
+{
+ mId = id;
+ parties[id] = this;
+}
+
+Party::~Party()
+{
+ clearMembers();
+}
+
+PartyMember *Party::addMember(int id, const std::string &name)
+{
+ PartyMember *m;
+ if ((m = getMember(id)))
+ return m;
+
+ m = new PartyMember(this, id, name);
+
+ mMembers.push_back(m);
+
+ return m;
+}
+
+PartyMember *Party::getMember(int id) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == id)
+ return (*itr);
+ ++itr;
+ }
+
+ return NULL;
+}
+
+PartyMember *Party::getMember(const std::string &name) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->getName() == name)
+ return (*itr);
+
+ ++itr;
+ }
+
+ return NULL;
+}
+
+void Party::removeMember(PartyMember *member)
+{
+ if (!member)
+ return;
+
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == member->mId &&
+ (*itr)->getName() == member->getName())
+ {
+ PartyMember *member = (*itr);
+ mMembers.erase(itr);
+ delete member;
+ }
+ ++itr;
+ }
+}
+
+void Party::removeMember(int id)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == id)
+ {
+ PartyMember *member = (*itr);
+ mMembers.erase(itr);
+ delete member;
+ }
+ ++itr;
+ }
+}
+
+void Party::removeMember(const std::string &name)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->getName() == name)
+ {
+ PartyMember *member = (*itr);
+ mMembers.erase(itr);
+ delete member;
+ }
+ ++itr;
+ }
+}
+
+void Party::removeFromMembers()
+{
+ if (!actorSpriteManager)
+ return;
+
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ Being *b = actorSpriteManager->findBeing((*itr)->getID());
+ if (b)
+ b->setParty(0);
+ ++itr;
+ }
+}
+
+Avatar *Party::getAvatarAt(int index)
+{
+ return mMembers[index];
+}
+
+void Party::setRights(short rights)
+{
+ // to invite, rights must be greater than 0
+ if (rights > 0)
+ mCanInviteUsers = true;
+}
+
+bool Party::isMember(PartyMember *member) const
+{
+ if (!member)
+ return false;
+
+ if (member->mParty > 0 && member->mParty != this)
+ return false;
+
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == member->mId &&
+ (*itr)->getName() == member->getName())
+ {
+ return true;
+ }
+ ++itr;
+ }
+
+ return false;
+}
+
+bool Party::isMember(int id) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == id)
+ return true;
+ ++itr;
+ }
+
+ return false;
+}
+
+bool Party::isMember(const std::string &name) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->getName() == name)
+ return true;
+ ++itr;
+ }
+
+ return false;
+}
+
+void Party::getNames(std::vector<std::string> &names) const
+{
+ names.clear();
+ MemberList::const_iterator it = mMembers.begin(),
+ it_end = mMembers.end();
+ while (it != it_end)
+ {
+ names.push_back((*it)->getName());
+ ++it;
+ }
+}
+
+Party *Party::getParty(short id)
+{
+ PartyMap::iterator it = parties.find(id);
+ if (it != parties.end())
+ return it->second;
+
+ return new Party(id);
+}
+
+void Party::sort()
+{
+ std::sort(mMembers.begin(), mMembers.end(), partySorter);
+} \ No newline at end of file
diff --git a/src/party.h b/src/party.h
new file mode 100644
index 000000000..f5db617a0
--- /dev/null
+++ b/src/party.h
@@ -0,0 +1,168 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PARTY_H
+#define PARTY_H
+
+#include "avatar.h"
+
+#include "gui/widgets/avatarlistbox.h"
+
+#include "utils/dtor.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class Party;
+
+class PartyMember : public Avatar
+{
+public:
+ Party *getParty() const
+ { return mParty; }
+
+ bool getLeader() const
+ { return mLeader; }
+
+ void setLeader(bool leader)
+ { mLeader = leader; setDisplayBold(leader); }
+
+protected:
+ friend class Party;
+
+ PartyMember(Party *party, int id, const std::string &name);
+
+ Party *mParty;
+ bool mLeader;
+};
+
+class Party : public AvatarListModel
+{
+public:
+
+ /**
+ * Set the party's name.
+ */
+ void setName(const std::string &name)
+ { mName = name; }
+
+ /**
+ * Adds member to the list.
+ */
+ PartyMember *addMember(int id, const std::string &name);
+
+ /**
+ * Find a member by ID.
+ *
+ * @return the member with the given ID, or NULL if they don't exist.
+ */
+ PartyMember *getMember(int id) const;
+
+ /**
+ * Find a member by name.
+ *
+ * @return the member with the given name, or NULL if they don't exist.
+ */
+ PartyMember *getMember(const std::string &name) const;
+
+ /**
+ * Get the name of the party.
+ * @return returns name of the party
+ */
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Get the id of the party.
+ * @return Returns the id of the party
+ */
+ short getId() const
+ { return mId; }
+
+ /**
+ * Removes a member from the party.
+ */
+ void removeMember(PartyMember *member);
+
+ /**
+ * Removes a member from the party.
+ */
+ void removeMember(int id);
+
+ /**
+ * Removes a member from the party.
+ */
+ void removeMember(const std::string &name);
+
+ void clearMembers()
+ { delete_all(mMembers); mMembers.clear(); }
+
+ void removeFromMembers();
+
+ /**
+ * Get size of members list.
+ * @return Returns the number of members in the party.
+ */
+ int getNumberOfElements()
+ { return static_cast<int>(mMembers.size()); }
+
+ Avatar *getAvatarAt(int i);
+
+ /**
+ * Get whether user can invite users to this party.
+ * @return Returns true if user can invite users
+ */
+ bool getInviteRights() const
+ { return mCanInviteUsers; }
+
+ void setRights(short rights);
+
+ bool isMember(PartyMember *member) const;
+
+ bool isMember(int id) const;
+
+ bool isMember(const std::string &name) const;
+
+ void getNames(std::vector<std::string> &names) const;
+
+ void sort();
+
+ static Party *getParty(short id);
+
+private:
+ typedef std::map<int, Party*> PartyMap;
+ static PartyMap parties;
+
+ /**
+ * Constructor with party id passed to it.
+ */
+ Party(short id);
+
+ ~Party();
+
+ typedef std::vector<PartyMember*> MemberList;
+ MemberList mMembers;
+ std::string mName;
+ short mId;
+ bool mCanInviteUsers;
+};
+
+#endif // PARTY_H
diff --git a/src/playerinfo.cpp b/src/playerinfo.cpp
new file mode 100644
index 000000000..a9b8c1d28
--- /dev/null
+++ b/src/playerinfo.cpp
@@ -0,0 +1,330 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "playerinfo.h"
+
+#include "client.h"
+#include "equipment.h"
+#include "event.h"
+#include "inventory.h"
+#include "listener.h"
+#include "log.h"
+
+#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
+
+namespace PlayerInfo
+{
+
+class PlayerInfoListener;
+
+PlayerInfoListener *mListener = 0;
+
+PlayerInfoBackend mData;
+int mCharId = 0;
+
+Inventory *mInventory = 0;
+Equipment *mEquipment = 0;
+
+std::map<int, Special> mSpecials;
+char mSpecialRechargeUpdateNeeded = 0;
+
+bool mTrading = false;
+int mLevelProgress = 0;
+
+// --- Triggers ---------------------------------------------------------------
+
+void triggerAttr(int id, int old)
+{
+ Mana::Event event(EVENT_UPDATEATTRIBUTE);
+ event.setInt("id", id);
+ event.setInt("oldValue", old);
+ event.setInt("newValue", mData.mAttributes.find(id)->second);
+ Mana::Event::trigger(CHANNEL_ATTRIBUTES, event);
+}
+
+void triggerStat(int id, const std::string &changed, int old1, int old2)
+{
+ StatMap::iterator it = mData.mStats.find(id);
+ Mana::Event event(EVENT_UPDATESTAT);
+ event.setInt("id", id);
+ event.setInt("base", it->second.base);
+ event.setInt("mod", it->second.mod);
+ event.setInt("exp", it->second.exp);
+ event.setInt("expNeeded", it->second.expNeed);
+ event.setString("changed", changed);
+ event.setInt("oldValue1", old1);
+ event.setInt("oldValue2", old2);
+ Mana::Event::trigger(CHANNEL_ATTRIBUTES, event);
+}
+
+// --- Attributes -------------------------------------------------------------
+
+int getAttribute(int id)
+{
+ IntMap::const_iterator it = mData.mAttributes.find(id);
+ if (it != mData.mAttributes.end())
+ return it->second;
+ else
+ return 0;
+}
+
+void setAttribute(int id, int value, bool notify)
+{
+ int old = mData.mAttributes[id];
+ mData.mAttributes[id] = value;
+ if (notify)
+ triggerAttr(id, old);
+}
+
+// --- Stats ------------------------------------------------------------------
+
+int getStatBase(int id)
+{
+ StatMap::const_iterator it = mData.mStats.find(id);
+ if (it != mData.mStats.end())
+ return it->second.base;
+ else
+ return 0;
+}
+
+void setStatBase(int id, int value, bool notify)
+{
+ int old = mData.mStats[id].base;
+ mData.mStats[id].base = value;
+ if (notify)
+ triggerStat(id, "base", old);
+}
+
+int getStatMod(int id)
+{
+ StatMap::const_iterator it = mData.mStats.find(id);
+ if (it != mData.mStats.end())
+ return it->second.mod;
+ else
+ return 0;
+}
+
+void setStatMod(int id, int value, bool notify)
+{
+ int old = mData.mStats[id].mod;
+ mData.mStats[id].mod = value;
+ if (notify)
+ triggerStat(id, "mod", old);
+}
+
+int getStatEffective(int id)
+{
+ StatMap::const_iterator it = mData.mStats.find(id);
+ if (it != mData.mStats.end())
+ return it->second.base + it->second.mod;
+ else
+ return 0;
+}
+
+std::pair<int, int> getStatExperience(int id)
+{
+ StatMap::const_iterator it = mData.mStats.find(id);
+ int a, b;
+ if (it != mData.mStats.end())
+ {
+ a = it->second.exp;
+ b = it->second.expNeed;
+ }
+ else
+ {
+ a = 0;
+ b = 0;
+ }
+ return std::pair<int, int>(a, b);
+}
+
+void setStatExperience(int id, int have, int need, bool notify)
+{
+ int oldExp = mData.mStats[id].exp;
+ int oldExpNeed = mData.mStats[id].expNeed;
+ mData.mStats[id].exp = have;
+ mData.mStats[id].expNeed = need;
+ if (notify)
+ triggerStat(id, "exp", oldExp, oldExpNeed);
+}
+
+// --- Inventory / Equipment --------------------------------------------------
+
+Inventory *getInventory()
+{
+ return mInventory;
+}
+
+void clearInventory()
+{
+ if (mEquipment)
+ mEquipment->clear();
+ if (mInventory)
+ mInventory->clear();
+}
+
+void setInventoryItem(int index, int id, int amount, int refine)
+{
+ bool equipment = false;
+ int itemType = ItemDB::get(id).getType();
+ if (itemType != ITEM_UNUSABLE && itemType != ITEM_USABLE)
+ equipment = true;
+ if (mInventory)
+ mInventory->setItem(index, id, amount, refine, equipment);
+}
+
+Equipment *getEquipment()
+{
+ return mEquipment;
+}
+
+Item *getEquipment(unsigned int slot)
+{
+ if (mEquipment)
+ return mEquipment->getEquipment(slot);
+ else
+ return 0;
+}
+
+void setEquipmentBackend(Equipment::Backend *backend)
+{
+ if (mEquipment)
+ mEquipment->setBackend(backend);
+}
+
+// --- Specials ---------------------------------------------------------------
+
+void setSpecialStatus(int id, int current, int max, int recharge)
+{
+ logger->log("SpecialUpdate Skill #%d -- (%d/%d) -> %d", id, current, max,
+ recharge);
+ mSpecials[id].currentMana = current;
+ mSpecials[id].neededMana = max;
+ mSpecials[id].recharge = recharge;
+}
+
+const SpecialsMap &getSpecialStatus()
+{
+ return mSpecials;
+}
+
+// --- Misc -------------------------------------------------------------------
+
+void setBackend(const PlayerInfoBackend &backend)
+{
+ mData = backend;
+}
+
+void setCharId(int charId)
+{
+ mCharId = charId;
+}
+
+int getCharId()
+{
+ return mCharId;
+}
+
+void logic()
+{
+ if ((mSpecialRechargeUpdateNeeded % 11) == 0)
+ {
+ mSpecialRechargeUpdateNeeded = 0;
+ for (SpecialsMap::iterator it = mSpecials.begin(),
+ it_end = mSpecials.end(); it != it_end; it++)
+ {
+ it->second.currentMana += it->second.recharge;
+ if (it->second.currentMana > it->second.neededMana)
+ it->second.currentMana = it->second.neededMana;
+ }
+ }
+ mSpecialRechargeUpdateNeeded++;
+}
+
+bool isTrading()
+{
+ return mTrading;
+}
+
+void setTrading(bool trading)
+{
+ bool notify = mTrading != trading;
+ mTrading = trading;
+
+ if (notify)
+ {
+ Mana::Event event(EVENT_TRADING);
+ event.setInt("trading", trading);
+ Mana::Event::trigger(CHANNEL_STATUS, event);
+ }
+}
+
+class PlayerInfoListener : Mana::Listener
+{
+public:
+ PlayerInfoListener()
+ {
+ listen(CHANNEL_CLIENT);
+ listen(CHANNEL_GAME);
+ }
+
+ void event(Channels channel, const Mana::Event &event)
+ {
+ if (channel == CHANNEL_CLIENT)
+ {
+ if (event.getName() == EVENT_STATECHANGE)
+ {
+ int newState = event.getInt("newState");
+
+ if (newState == STATE_GAME)
+ {
+ if (mInventory == 0)
+ {
+ mInventory = new Inventory(Inventory::INVENTORY);
+ mEquipment = new Equipment();
+ }
+ }
+ }
+ }
+ else if (channel == CHANNEL_GAME)
+ {
+ if (event.getName() == EVENT_DESTRUCTED)
+ {
+ delete mInventory;
+ delete mEquipment;
+
+ mInventory = 0;
+ mEquipment = 0;
+ }
+ }
+ }
+};
+
+void init()
+{
+ if (mListener)
+ return;
+
+ // may be need remove it?
+ mListener = new PlayerInfoListener();
+}
+
+} // namespace PlayerInfo
diff --git a/src/playerinfo.h b/src/playerinfo.h
new file mode 100644
index 000000000..f91d85197
--- /dev/null
+++ b/src/playerinfo.h
@@ -0,0 +1,238 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PLAYERINFO_H
+#define PLAYERINFO_H
+
+#include "equipment.h"
+
+#include <map>
+#include <string>
+
+/**
+ * Standard attributes for players.
+ */
+enum Attribute
+{
+ LEVEL = 0,
+ HP,
+ MAX_HP,
+ MP,
+ MAX_MP,
+ EXP,
+ EXP_NEEDED,
+ MONEY,
+ TOTAL_WEIGHT,
+ MAX_WEIGHT,
+ SKILL_POINTS,
+ CHAR_POINTS,
+ CORR_POINTS,
+ ATTACK_SPEED = 100,
+ ATTACK_RANGE = 101,
+ WALK_SPEED = 102
+};
+
+/**
+ * Stat information storage structure.
+ */
+struct Stat
+{
+ int base;
+ int mod;
+ int exp;
+ int expNeed;
+};
+
+typedef std::map<int, int> IntMap;
+typedef std::map<int, Stat> StatMap;
+
+/**
+ * Backend for core player information.
+ */
+struct PlayerInfoBackend
+{
+ IntMap mAttributes;
+ StatMap mStats;
+};
+
+class Equipment;
+class Inventory;
+class Item;
+
+/**
+ * Special information storage structure.
+ */
+struct Special
+{
+ int currentMana;
+ int neededMana;
+ int recharge;
+};
+
+typedef std::map<int, Special> SpecialsMap;
+
+/**
+ * A database like namespace which holds global info about the localplayer
+ *
+ * NOTE: 'bool notify' is used to determine if a event is to be triggered.
+ */
+namespace PlayerInfo
+{
+
+// --- Attributes -------------------------------------------------------------
+
+ /**
+ * Returns the value of the given attribute.
+ */
+ int getAttribute(int id);
+
+ /**
+ * Changes the value of the given attribute.
+ */
+ void setAttribute(int id, int value, bool notify = true);
+
+// --- Stats ------------------------------------------------------------------
+
+ /**
+ * Returns the base value of the given stat.
+ */
+ int getStatBase(int id);
+
+ /**
+ * Changes the base value of the given stat.
+ */
+ void setStatBase(int id, int value, bool notify = true);
+
+ /**
+ * Returns the modifier for the given stat.
+ */
+ int getStatMod(int id);
+
+ /**
+ * Changes the modifier for the given stat.
+ */
+ void setStatMod(int id, int value, bool notify = true);
+
+ /**
+ * Returns the current effective value of the given stat. Effective is base
+ * + mod
+ */
+ int getStatEffective(int id);
+
+ /**
+ * Changes the level of the given stat.
+ */
+ void setStatLevel(int id, int value, bool notify = true);
+
+ /**
+ * Returns the experience of the given stat.
+ */
+ std::pair<int, int> getStatExperience(int id);
+
+ /**
+ * Changes the experience of the given stat.
+ */
+ void setStatExperience(int id, int have, int need, bool notify = true);
+
+// --- Inventory / Equipment --------------------------------------------------
+
+ /**
+ * Returns the player's inventory.
+ */
+ Inventory *getInventory();
+
+ /**
+ * Clears the player's inventory and equipment.
+ */
+ void clearInventory();
+
+ /**
+ * Changes the inventory item at the given slot.
+ */
+ void setInventoryItem(int index, int id, int amount, int refine);
+
+ /**
+ * Returns the player's equipment.
+ */
+ Equipment *getEquipment();
+
+ /**
+ * Returns the player's equipment at the given slot.
+ */
+ Item *getEquipment(unsigned int slot);
+
+// --- Specials ---------------------------------------------------------------
+
+ /**
+ * Changes the status of the given special.
+ */
+ void setSpecialStatus(int id, int current, int max, int recharge);
+
+ /**
+ * Returns the status of the given special.
+ */
+ const SpecialsMap &getSpecialStatus();
+
+// --- Misc -------------------------------------------------------------------
+
+ /**
+ * Changes the internal PlayerInfoBackend reference;
+ */
+ void setBackend(const PlayerInfoBackend &backend);
+
+ void setCharId(int charId);
+
+ int getCharId();
+
+ /**
+ * Does necessary updates every tick.
+ */
+ void logic();
+
+ /**
+ * Returns true if the player is involved in a trade at the moment, false
+ * otherwise.
+ */
+ bool isTrading();
+
+ /**
+ * Sets whether the player is currently involved in trade or not.
+ */
+ void setTrading(bool trading);
+
+ /**
+ * Initializes some internals.
+ */
+ void init();
+
+ void triggerAttr(int id);
+
+ void triggerAttr(int id, int old);
+
+ void triggerStat(int id);
+
+ void triggerStat(int id, const std::string &changed,
+ int old1, int old2 = 0);
+
+ void setEquipmentBackend(Equipment::Backend *backend);
+
+} // namespace PlayerInfo
+
+#endif
diff --git a/src/playerrelations.cpp b/src/playerrelations.cpp
new file mode 100644
index 000000000..740da61a6
--- /dev/null
+++ b/src/playerrelations.cpp
@@ -0,0 +1,496 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <algorithm>
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "playerrelations.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+
+#define PLAYER_IGNORE_STRATEGY_NOP "nop"
+#define PLAYER_IGNORE_STRATEGY_EMOTE0 "emote0"
+#define DEFAULT_IGNORE_STRATEGY PLAYER_IGNORE_STRATEGY_EMOTE0
+
+#define NAME "name" // constant for xml serialisation
+#define RELATION "relation" // constant for xml serialisation
+
+#define IGNORE_EMOTE_TIME 100
+
+// (De)serialisation class
+class PlayerConfSerialiser :
+ public ConfigurationListManager<std::pair<std::string, PlayerRelation *>,
+ std::map<std::string, PlayerRelation *> *>
+{
+ virtual ConfigurationObject *writeConfigItem(
+ std::pair<std::string, PlayerRelation *> value,
+ ConfigurationObject *cobj)
+ {
+ if (!value.second)
+ return NULL;
+ cobj->setValue(NAME, value.first);
+ cobj->setValue(RELATION, toString(
+ static_cast<int>(value.second->mRelation)));
+
+ return cobj;
+ }
+
+ virtual std::map<std::string, PlayerRelation *> *
+ readConfigItem(ConfigurationObject *cobj,
+ std::map<std::string, PlayerRelation *> *container)
+ {
+ std::string name = cobj->getValue(NAME, "");
+ if (name.empty())
+ return container;
+
+ if (!(*container)[name])
+ {
+ int v = cobj->getValueInt(RELATION,
+ static_cast<int>(PlayerRelation::NEUTRAL));
+
+ (*container)[name] = new PlayerRelation(
+ static_cast<PlayerRelation::Relation>(v));
+ }
+ // otherwise ignore the duplicate entry
+
+ return container;
+ }
+};
+
+static PlayerConfSerialiser player_conf_serialiser; // stateless singleton
+
+const unsigned int PlayerRelation::RELATION_PERMISSIONS[RELATIONS_NR] = {
+ /* NEUTRAL */ 0, // we always fall back to the defaults anyway
+ /* FRIEND */ EMOTE | SPEECH_FLOAT | SPEECH_LOG | WHISPER | TRADE,
+ /* DISREGARDED*/ EMOTE | SPEECH_FLOAT,
+ /* IGNORED */ 0,
+ /* ERASED */ INVISIBLE
+};
+
+PlayerRelation::PlayerRelation(Relation relation)
+{
+ mRelation = relation;
+}
+
+PlayerRelationsManager::PlayerRelationsManager() :
+ mPersistIgnores(false),
+ mDefaultPermissions(PlayerRelation::DEFAULT),
+ mIgnoreStrategy(0)
+{
+}
+
+PlayerRelationsManager::~PlayerRelationsManager()
+{
+ delete_all(mIgnoreStrategies);
+
+ for (std::map<std::string,
+ PlayerRelation *>::const_iterator it = mRelations.begin();
+ it != mRelations.end(); it++)
+ {
+ delete it->second;
+ }
+}
+
+void PlayerRelationsManager::clear()
+{
+ std::vector<std::string> *names = getPlayers();
+ for (std::vector<std::string>::const_iterator
+ it = names->begin(); it != names->end(); it++)
+ {
+ removePlayer(*it);
+ }
+ delete names;
+ names = 0;
+}
+
+#define PERSIST_IGNORE_LIST "persistent-player-list"
+#define PLAYER_IGNORE_STRATEGY "player-ignore-strategy"
+#define DEFAULT_PERMISSIONS "default-player-permissions"
+
+int PlayerRelationsManager::getPlayerIgnoreStrategyIndex(
+ const std::string &name)
+{
+ std::vector<PlayerIgnoreStrategy *> *strategies
+ = getPlayerIgnoreStrategies();
+
+ for (unsigned int i = 0; i < strategies->size(); i++)
+ {
+ if ((*strategies)[i]->mShortName == name)
+ return i;
+ }
+
+ return -1;
+}
+
+void PlayerRelationsManager::load(bool oldConfig)
+{
+ Configuration *cfg;
+ if (oldConfig)
+ cfg = &config;
+ else
+ cfg = &serverConfig;
+ clear();
+
+ mPersistIgnores = cfg->getValue(PERSIST_IGNORE_LIST, 1);
+ mDefaultPermissions = (int) cfg->getValue(DEFAULT_PERMISSIONS,
+ mDefaultPermissions);
+
+ std::string ignore_strategy_name = cfg->getValue(PLAYER_IGNORE_STRATEGY,
+ DEFAULT_IGNORE_STRATEGY);
+ int ignore_strategy_index = getPlayerIgnoreStrategyIndex(
+ ignore_strategy_name);
+
+ if (ignore_strategy_index >= 0)
+ {
+ setPlayerIgnoreStrategy((*getPlayerIgnoreStrategies())
+ [ignore_strategy_index]);
+ }
+
+ cfg->getList<std::pair<std::string, PlayerRelation *>,
+ std::map<std::string, PlayerRelation *> *>
+ ("player", &(mRelations), &player_conf_serialiser);
+}
+
+
+void PlayerRelationsManager::init()
+{
+ load();
+
+ if (!mPersistIgnores)
+ {
+ clear(); // Yes, we still keep them around in the config file
+ // until the next update.
+ }
+
+ for (std::list<PlayerRelationsListener *>::const_iterator
+ it = mListeners.begin(); it != mListeners.end(); it++)
+ {
+ (*it)->updateAll();
+ }
+}
+
+void PlayerRelationsManager::store()
+{
+ serverConfig.setList<std::map<std::string,
+ PlayerRelation *>::const_iterator,
+ std::pair<std::string, PlayerRelation *>,
+ std::map<std::string, PlayerRelation *> *>
+ ("player",
+ mRelations.begin(), mRelations.end(),
+ &player_conf_serialiser);
+
+ serverConfig.setValue(DEFAULT_PERMISSIONS, mDefaultPermissions);
+ serverConfig.setValue(PERSIST_IGNORE_LIST, mPersistIgnores);
+ serverConfig.setValue(PLAYER_IGNORE_STRATEGY,
+ mIgnoreStrategy ? mIgnoreStrategy->mShortName
+ : DEFAULT_IGNORE_STRATEGY);
+
+ serverConfig.write();
+}
+
+void PlayerRelationsManager::signalUpdate(const std::string &name)
+{
+// store();
+
+ for (std::list<PlayerRelationsListener *>::const_iterator
+ it = mListeners.begin(); it != mListeners.end(); it++)
+ {
+ (*it)->updatedPlayer(name);
+ }
+
+ if (actorSpriteManager)
+ {
+ Being* being = actorSpriteManager->findBeingByName(
+ name, Being::PLAYER);
+
+ if (being && being->getType() == Being::PLAYER)
+ being->updateColors();
+ }
+}
+
+unsigned int PlayerRelationsManager::checkPermissionSilently(
+ const std::string &player_name, unsigned int flags)
+{
+ PlayerRelation *r = mRelations[player_name];
+ if (!r)
+ {
+ logger->log("checkPermissionSilently1: "
+ + toString(mDefaultPermissions & flags));
+ return mDefaultPermissions & flags;
+ }
+ else
+ {
+ unsigned int permissions =
+ PlayerRelation::RELATION_PERMISSIONS[r->mRelation];
+
+ logger->log("r->mRelation: "
+ + toString(static_cast<signed>(r->mRelation)));
+ logger->log("permissions: " + toString(permissions));
+ switch (r->mRelation)
+ {
+ case PlayerRelation::NEUTRAL:
+ permissions = mDefaultPermissions;
+ break;
+
+ case PlayerRelation::FRIEND:
+ permissions |= mDefaultPermissions; // widen
+ break;
+
+ default:
+ permissions &= mDefaultPermissions; // narrow
+ }
+
+ logger->log("checkPermissionSilently2: "
+ + toString(permissions & flags));
+ return permissions & flags;
+ }
+}
+
+bool PlayerRelationsManager::hasPermission(Being *being, unsigned int flags)
+{
+ if (!being)
+ return false;
+
+ if (being->getType() == ActorSprite::PLAYER)
+ return hasPermission(being->getName(), flags) == flags;
+ return true;
+}
+
+bool PlayerRelationsManager::hasPermission(const std::string &name,
+ unsigned int flags)
+{
+ if (!actorSpriteManager)
+ return false;
+
+ unsigned int rejections = flags & ~checkPermissionSilently(name, flags);
+ logger->log1("PlayerRelationsManager::hasPermission");
+ logger->log("name: " + name);
+ logger->log("flags: " + toString(flags));
+ logger->log("rejections: " + toString(rejections));
+ bool permitted = (rejections == 0);
+
+ if (!permitted)
+ {
+ // execute `ignore' strategy, if possible
+ if (mIgnoreStrategy)
+ {
+ Being *b = actorSpriteManager->findBeingByName(
+ name, ActorSprite::PLAYER);
+
+ if (b && b->getType() == ActorSprite::PLAYER)
+ mIgnoreStrategy->ignore(b, rejections);
+ }
+ }
+
+ return permitted;
+}
+
+void PlayerRelationsManager::setRelation(const std::string &player_name,
+ PlayerRelation::Relation relation)
+{
+ PlayerRelation *r = mRelations[player_name];
+ if (r == NULL)
+ mRelations[player_name] = new PlayerRelation(relation);
+ else
+ r->mRelation = relation;
+
+ signalUpdate(player_name);
+}
+
+std::vector<std::string> * PlayerRelationsManager::getPlayers()
+{
+ std::vector<std::string> *retval = new std::vector<std::string>();
+
+ for (std::map<std::string,
+ PlayerRelation *>::const_iterator it = mRelations.begin();
+ it != mRelations.end(); it++)
+ {
+ if (it->second)
+ retval->push_back(it->first);
+ }
+
+ sort(retval->begin(), retval->end());
+
+ return retval;
+}
+
+void PlayerRelationsManager::removePlayer(const std::string &name)
+{
+ if (mRelations[name])
+ delete mRelations[name];
+
+ mRelations.erase(name);
+
+ signalUpdate(name);
+}
+
+
+PlayerRelation::Relation PlayerRelationsManager::getRelation(
+ const std::string &name)
+{
+ if (mRelations[name])
+ return mRelations[name]->mRelation;
+
+ return PlayerRelation::NEUTRAL;
+}
+
+////////////////////////////////////////
+// defaults
+
+unsigned int PlayerRelationsManager::getDefault() const
+{
+ return mDefaultPermissions;
+}
+
+void PlayerRelationsManager::setDefault(unsigned int permissions)
+{
+ mDefaultPermissions = permissions;
+
+ store();
+ signalUpdate("");
+}
+
+void PlayerRelationsManager::ignoreTrade(std::string name)
+{
+ if (name.empty())
+ return;
+
+ PlayerRelation::Relation relation = getRelation(name);
+
+ if (relation == PlayerRelation::IGNORED
+ || relation == PlayerRelation::DISREGARDED
+ || relation == PlayerRelation::ERASED)
+ {
+ return;
+ }
+ else
+ {
+ player_relations.setRelation(name, PlayerRelation::DISREGARDED);
+ }
+}
+
+
+////////////////////////////////////////
+// ignore strategies
+
+
+class PIS_nothing : public PlayerIgnoreStrategy
+{
+public:
+ PIS_nothing()
+ {
+ mDescription = _("Completely ignore");
+ mShortName = PLAYER_IGNORE_STRATEGY_NOP;
+ }
+
+ virtual void ignore(Being *being _UNUSED_, unsigned int flags _UNUSED_)
+ {
+ }
+};
+
+class PIS_dotdotdot : public PlayerIgnoreStrategy
+{
+public:
+ PIS_dotdotdot()
+ {
+ mDescription = _("Print '...'");
+ mShortName = "dotdotdot";
+ }
+
+ virtual void ignore(Being *being, unsigned int flags _UNUSED_)
+ {
+ if (!being)
+ return;
+
+ logger->log("ignoring: " + being->getName());
+ being->setSpeech("...", 500);
+ }
+};
+
+
+class PIS_blinkname : public PlayerIgnoreStrategy
+{
+public:
+ PIS_blinkname()
+ {
+ mDescription = _("Blink name");
+ mShortName = "blinkname";
+ }
+
+ virtual void ignore(Being *being, unsigned int flags _UNUSED_)
+ {
+ if (!being)
+ return;
+
+ logger->log("ignoring: " + being->getName());
+ being->flashName(200);
+ }
+};
+
+class PIS_emote : public PlayerIgnoreStrategy
+{
+public:
+ PIS_emote(Uint8 emote_nr, const std::string &description,
+ const std::string &shortname) :
+ mEmotion(emote_nr)
+ {
+ mDescription = description;
+ mShortName = shortname;
+ }
+
+ virtual void ignore(Being *being, unsigned int flags _UNUSED_)
+ {
+ if (!being)
+ return;
+
+ logger->log("ignoring: " + being->getName());
+ being->setEmote(mEmotion, IGNORE_EMOTE_TIME);
+ }
+ Uint8 mEmotion;
+};
+
+
+
+std::vector<PlayerIgnoreStrategy *> *
+PlayerRelationsManager::getPlayerIgnoreStrategies()
+{
+ if (mIgnoreStrategies.size() == 0)
+ {
+ // not initialised yet?
+ mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE,
+ _("Floating '...' bubble"),
+ PLAYER_IGNORE_STRATEGY_EMOTE0));
+ mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE + 1,
+ _("Floating bubble"),
+ "emote1"));
+ mIgnoreStrategies.push_back(new PIS_nothing());
+ mIgnoreStrategies.push_back(new PIS_dotdotdot());
+ mIgnoreStrategies.push_back(new PIS_blinkname());
+ }
+ return &mIgnoreStrategies;
+}
+
+
+PlayerRelationsManager player_relations;
diff --git a/src/playerrelations.h b/src/playerrelations.h
new file mode 100644
index 000000000..1c7864580
--- /dev/null
+++ b/src/playerrelations.h
@@ -0,0 +1,251 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PLAYER_RELATIONS_H
+#define PLAYER_RELATIONS_H
+
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Being;
+
+struct PlayerRelation
+{
+ static const unsigned int EMOTE = (1 << 0);
+ static const unsigned int SPEECH_FLOAT = (1 << 1);
+ static const unsigned int SPEECH_LOG = (1 << 2);
+ static const unsigned int WHISPER = (1 << 3);
+ static const unsigned int TRADE = (1 << 4);
+ static const unsigned int INVISIBLE = (1 << 5);
+
+ static const unsigned int RELATIONS_NR = 5;
+ static const unsigned int RELATION_PERMISSIONS[RELATIONS_NR];
+
+ static const unsigned int DEFAULT = EMOTE
+ | SPEECH_FLOAT
+ | SPEECH_LOG
+ | WHISPER
+ | TRADE;
+ enum Relation
+ {
+ NEUTRAL = 0,
+ FRIEND = 1,
+ DISREGARDED = 2,
+ IGNORED = 3,
+ ERASED = 4
+ };
+
+ PlayerRelation(Relation relation);
+
+ Relation mRelation; // bitmask for all of the above
+};
+
+
+/**
+ * Ignore strategy: describes how we should handle ignores.
+ */
+class PlayerIgnoreStrategy
+{
+ public:
+ std::string mDescription;
+ std::string mShortName;
+
+ virtual ~PlayerIgnoreStrategy()
+ { }
+
+ /**
+ * Handle the ignoring of the indicated action by the indicated player.
+ */
+ virtual void ignore(Being *being, unsigned int flags) = 0;
+};
+
+class PlayerRelationsListener
+{
+ public:
+ PlayerRelationsListener()
+ { }
+
+ virtual ~PlayerRelationsListener()
+ { }
+
+ virtual void updatedPlayer(const std::string &name) = 0;
+ virtual void updateAll() = 0;
+};
+
+/**
+ * Player relations class, represents any particular relations and/or
+ * preferences the user of the local client has wrt other players (identified
+ * by std::string).
+ */
+class PlayerRelationsManager
+{
+ public:
+ PlayerRelationsManager();
+ ~PlayerRelationsManager();
+
+ /**
+ * Initialise player relations manager (load config file etc.)
+ */
+ void init();
+
+ /**
+ * Load configuration from our config file, or substitute defaults.
+ */
+ void load(bool oldConfig = false);
+
+ /**
+ * Save configuration to our config file.
+ */
+ void store();
+
+ /**
+ * Determines whether the player in question is being ignored, filtered by
+ * the specified flags.
+ */
+ unsigned int checkPermissionSilently(const std::string &player_name,
+ unsigned int flags);
+
+ /**
+ * Tests whether the player in question is being ignored for any of the
+ * actions in the specified flags. If so, trigger appropriate side effects
+ * if requested by the player.
+ */
+ bool hasPermission(Being *being, unsigned int flags);
+
+ bool hasPermission(const std::string &being, unsigned int flags);
+
+ /**
+ * Updates the relationship with this player.
+ */
+ void setRelation(const std::string &name,
+ PlayerRelation::Relation relation);
+
+ /**
+ * Updates the relationship with this player.
+ */
+ PlayerRelation::Relation getRelation(const std::string &name);
+
+ /**
+ * Deletes the information recorded for a player.
+ */
+ void removePlayer(const std::string &name);
+
+ /**
+ * Retrieves the default permissions.
+ */
+ unsigned int getDefault() const;
+
+ /**
+ * Sets the default permissions.
+ */
+ void setDefault(unsigned int permissions);
+
+ /**
+ * Retrieves all known player ignore strategies.
+ *
+ * The player ignore strategies are allocated statically and must
+ * not be deleted.
+ */
+ std::vector<PlayerIgnoreStrategy *> *getPlayerIgnoreStrategies();
+
+ /**
+ * Return the current player ignore strategy.
+ *
+ * \return A player ignore strategy, or NULL
+ */
+ PlayerIgnoreStrategy *getPlayerIgnoreStrategy() const
+ { return mIgnoreStrategy; }
+
+ /**
+ * Sets the strategy to call when ignoring players.
+ */
+ void setPlayerIgnoreStrategy(PlayerIgnoreStrategy *strategy)
+ { mIgnoreStrategy = strategy; }
+
+ /**
+ * For a given ignore strategy short name, find the appropriate index
+ * in the ignore strategies vector.
+ *
+ * \param The short name of the ignore strategy to look up
+ * \return The appropriate index, or -1
+ */
+ int getPlayerIgnoreStrategyIndex(const std::string &shortname);
+
+ /**
+ * Retrieves a sorted vector of all players for which we have any
+ * relations recorded.
+ */
+ std::vector<std::string> *getPlayers();
+
+ /**
+ * Removes all recorded player info.
+ */
+ void clear();
+
+ /**
+ * Do we persist our `ignore' setup?
+ */
+ bool getPersistIgnores() const
+ { return mPersistIgnores; }
+
+ void ignoreTrade(std::string name);
+
+ /**
+ * Change the `ignore persist' flag.
+ *
+ * @param value Whether to persist ignores
+ */
+ void setPersistIgnores(bool value)
+ { mPersistIgnores = value; }
+
+ void addListener(PlayerRelationsListener *listener)
+ { mListeners.push_back(listener); }
+
+ void removeListener(PlayerRelationsListener *listener)
+ { mListeners.remove(listener); }
+
+ private:
+ void signalUpdate(const std::string &name);
+
+ bool mPersistIgnores; // If NOT set, we delete the
+ // ignored data upon reloading
+ unsigned int mDefaultPermissions;
+
+ PlayerIgnoreStrategy *mIgnoreStrategy;
+ std::map<std::string, PlayerRelation *> mRelations;
+ std::list<PlayerRelationsListener *> mListeners;
+ std::vector<PlayerIgnoreStrategy *> mIgnoreStrategies;
+};
+
+
+extern PlayerRelationsManager player_relations; // singleton representation
+ // of player relations
+
+
+#endif // PLAYER_RELATIONS_H
diff --git a/src/position.cpp b/src/position.cpp
new file mode 100644
index 000000000..6b215b22c
--- /dev/null
+++ b/src/position.cpp
@@ -0,0 +1,45 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "position.h"
+
+std::ostream& operator <<(std::ostream &os, const Position &p)
+{
+ os << "(" << p.x << ", " << p.y << ")";
+ return os;
+}
+
+std::ostream& operator <<(std::ostream &os, const Path &path)
+{
+ Path::const_iterator i = path.begin(), i_end = path.end();
+
+ os << "(";
+ while (i != i_end)
+ {
+ os << *i;
+ ++i;
+ if (i != i_end)
+ os << ", ";
+ }
+ os << ")";
+
+ return os;
+}
diff --git a/src/position.h b/src/position.h
new file mode 100644
index 000000000..454709c08
--- /dev/null
+++ b/src/position.h
@@ -0,0 +1,55 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef POSITION_H
+#define POSITION_H
+
+#include <iostream>
+#include <list>
+
+/**
+ * A position along a being's path.
+ */
+struct Position
+{
+ Position(int x, int y):
+ x(x), y(y)
+ { }
+
+ int x;
+ int y;
+};
+
+typedef std::list<Position> Path;
+typedef Path::iterator PathIterator;
+
+/**
+ * Appends a string representation of a position to the output stream.
+ */
+std::ostream& operator <<(std::ostream &os, const Position &p);
+
+/**
+ * Appends a string representation of a path (sequence of positions) to the
+ * output stream.
+ */
+std::ostream& operator <<(std::ostream &os, const Path &path);
+
+#endif // POSITION_H
diff --git a/src/properties.h b/src/properties.h
new file mode 100644
index 000000000..adec31d70
--- /dev/null
+++ b/src/properties.h
@@ -0,0 +1,126 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef PROPERTIES_H
+#define PROPERTIES_H
+
+#include "log.h"
+#include <map>
+#include <sstream>
+#include <string>
+
+/**
+ * A class holding a set of properties.
+ */
+class Properties
+{
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~Properties()
+ { }
+
+ /**
+ * Get a map property.
+ *
+ * @param name The name of the property.
+ * @param def Default value, empty string by default.
+ * @return the value of the given property or the given default when it
+ * doesn't exist.
+ */
+ const std::string getProperty(const std::string &name,
+ const std::string &def = "") const
+ {
+ PropertyMap::const_iterator i = mProperties.find(name);
+ return (i != mProperties.end()) ? i->second : def;
+ }
+
+ /**
+ * Gets a map property as a float.
+ *
+ * @param name The name of the property.
+ * @param def Default value, 0.0f by default.
+ * @return the value of the given property or the given default when it
+ * doesn't exist.
+ */
+ float getFloatProperty(const std::string &name, float def = 0.0f) const
+ {
+ PropertyMap::const_iterator i = mProperties.find(name);
+ float ret = def;
+ if (i != mProperties.end())
+ {
+ std::stringstream ss;
+ ss.str(i->second);
+ ss >> ret;
+ }
+ return ret;
+ }
+
+ /**
+ * Gets a map property as a boolean.
+ *
+ * @param name The name of the property.
+ * @param def Default value, false by default.
+ * @return the value of the given property or the given default when it
+ * doesn't exist.
+ */
+ bool getBoolProperty(const std::string &name, bool def = false) const
+ {
+ PropertyMap::const_iterator i = mProperties.find(name);
+ bool ret = def;
+ if (i != mProperties.end())
+ {
+ if (i->second == "true")
+ ret = true;
+ if (i->second == "false")
+ ret = false;
+ }
+ return ret;
+ }
+
+ /**
+ * Returns whether a certain property is available.
+ *
+ * @param name The name of the property.
+ * @return <code>true</code> when a property is defined,
+ * <code>false</code> otherwise.
+ */
+ bool hasProperty(const std::string &name) const
+ { return (mProperties.find(name) != mProperties.end()); }
+
+ /**
+ * Set a map property.
+ *
+ * @param name The name of the property.
+ * @param value The value of the property.
+ */
+ void setProperty(const std::string &name, const std::string &value)
+ { mProperties[name] = value; }
+
+
+ private:
+ typedef std::map<std::string, std::string> PropertyMap;
+ PropertyMap mProperties;
+
+};
+
+#endif
diff --git a/src/resources/action.cpp b/src/resources/action.cpp
new file mode 100644
index 000000000..923aa72c9
--- /dev/null
+++ b/src/resources/action.cpp
@@ -0,0 +1,52 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/action.h"
+
+#include "resources/animation.h"
+
+#include "utils/dtor.h"
+
+Action::Action()
+{
+}
+
+Action::~Action()
+{
+ delete_all(mAnimations);
+}
+
+Animation *Action::getAnimation(int direction) const
+{
+ Animations::const_iterator i = mAnimations.find(direction);
+
+ // When the given direction is not available, return the first one.
+ // (either DEFAULT, or more usually DOWN).
+ if (i == mAnimations.end())
+ i = mAnimations.begin();
+
+ return (i == mAnimations.end()) ? NULL : i->second;
+}
+
+void Action::setAnimation(int direction, Animation *animation)
+{
+ mAnimations[direction] = animation;
+}
diff --git a/src/resources/action.h b/src/resources/action.h
new file mode 100644
index 000000000..3bd7b75aa
--- /dev/null
+++ b/src/resources/action.h
@@ -0,0 +1,51 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ACTION_H
+#define ACTION_H
+
+#include <libxml/tree.h>
+
+#include <map>
+
+class Animation;
+
+/**
+ * An action consists of several animations, one for each direction.
+ */
+class Action
+{
+ public:
+ Action();
+
+ ~Action();
+
+ void setAnimation(int direction, Animation *animation);
+
+ Animation *getAnimation(int direction) const;
+
+ protected:
+ typedef std::map<int, Animation*> Animations;
+ typedef Animations::iterator AnimationIterator;
+ Animations mAnimations;
+};
+
+#endif
diff --git a/src/resources/ambientlayer.cpp b/src/resources/ambientlayer.cpp
new file mode 100644
index 000000000..d80f380dd
--- /dev/null
+++ b/src/resources/ambientlayer.cpp
@@ -0,0 +1,126 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/ambientlayer.h"
+
+#include "graphics.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+AmbientLayer::AmbientLayer(Image *img, float parallax,
+ float speedX, float speedY, bool keepRatio):
+ mImage(img), mParallax(parallax),
+ mPosX(0), mPosY(0),
+ mSpeedX(speedX), mSpeedY(speedY),
+ mKeepRatio(keepRatio)
+{
+ if (!mImage)
+ return;
+
+ if (keepRatio && !mImage->useOpenGL()
+ /*&& defaultScreenWidth != 0
+ && defaultScreenHeight != 0*/
+ && graphics->getWidth() != defaultScreenWidth
+ && graphics->getHeight() != defaultScreenHeight)
+ {
+ // Rescale the overlay to keep the ratio as if we were on
+ // the default resolution...
+ Image *rescaledOverlay = mImage->SDLgetScaledImage(
+ static_cast<int>(mImage->getWidth()) / defaultScreenWidth
+ * graphics->getWidth(), static_cast<int>(mImage->getHeight())
+ / defaultScreenHeight * graphics->getHeight());
+
+ if (rescaledOverlay)
+ {
+ // Replace the resource with the new one...
+ std::string idPath = mImage->getIdPath() + "_rescaled";
+ ResourceManager::getInstance()->addResource(
+ idPath, rescaledOverlay);
+ mImage = rescaledOverlay;
+ rescaledOverlay->incRef();
+ }
+ else
+ {
+ mImage->incRef();
+ }
+ }
+ else
+ {
+ mImage->incRef();
+ }
+}
+
+AmbientLayer::~AmbientLayer()
+{
+ if (mImage)
+ mImage->decRef();
+}
+
+void AmbientLayer::update(int timePassed, float dx, float dy)
+{
+ if (!mImage)
+ return;
+
+ // Self scrolling of the overlay
+ mPosX -= mSpeedX * static_cast<float>(timePassed) / 10;
+ mPosY -= mSpeedY * static_cast<float>(timePassed) / 10;
+
+ // Parallax scrolling
+ mPosX += dx * mParallax;
+ mPosY += dy * mParallax;
+
+ int imgW = mImage->getWidth();
+ int imgH = mImage->getHeight();
+
+ // Wrap values
+ while (mPosX > imgW)
+ mPosX -= static_cast<float>(imgW);
+ while (mPosX < 0)
+ mPosX += static_cast<float>(imgW);
+
+ while (mPosY > imgH)
+ mPosY -= static_cast<float>(imgH);
+ while (mPosY < 0)
+ mPosY += static_cast<float>(imgH);
+}
+
+void AmbientLayer::draw(Graphics *graphics, int x, int y)
+{
+ if (!mImage)
+ return;
+
+ if (!mImage->useOpenGL() || !mKeepRatio)
+ {
+ graphics->drawImagePattern(mImage, static_cast<int>(-mPosX),
+ static_cast<int>(-mPosY), x + static_cast<int>(mPosX),
+ y + static_cast<int>(mPosY));
+ }
+ else
+ {
+ graphics->drawRescaledImagePattern(mImage, static_cast<int>(-mPosX),
+ static_cast<int>(-mPosY), x + static_cast<int>(mPosX),
+ y + static_cast<int>(mPosY),
+ static_cast<int>(mImage->getWidth())
+ / defaultScreenWidth * graphics->getWidth(),
+ static_cast<int>(mImage->getHeight()) / defaultScreenHeight
+ * graphics->getHeight());
+ }
+}
diff --git a/src/resources/ambientlayer.h b/src/resources/ambientlayer.h
new file mode 100644
index 000000000..928a568d2
--- /dev/null
+++ b/src/resources/ambientlayer.h
@@ -0,0 +1,59 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef RESOURCES_AMBIENTOVERLAY_H
+#define RESOURCES_AMBIENTOVERLAY_H
+
+class Graphics;
+class Image;
+
+class AmbientLayer
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param img the image this overlay displays
+ * @param parallax scroll factor based on camera position
+ * @param speedX scrolling speed in x-direction
+ * @param speedY scrolling speed in y-direction
+ * @param keepRatio rescale the image to keep
+ * the same ratio than in 800x600 resolution mode.
+ */
+ AmbientLayer(Image *img, float parallax,
+ float speedX, float speedY, bool keepRatio = false);
+
+ ~AmbientLayer();
+
+ void update(int timePassed, float dx, float dy);
+
+ void draw(Graphics *graphics, int x, int y);
+
+ private:
+ Image *mImage;
+ float mParallax;
+ float mPosX; /**< Current layer X position. */
+ float mPosY; /**< Current layer Y position. */
+ float mSpeedX; /**< Scrolling speed in X direction. */
+ float mSpeedY; /**< Scrolling speed in Y direction. */
+ bool mKeepRatio; /**< Keep overlay ratio on every resolution */
+};
+
+#endif
diff --git a/src/resources/ambientoverlay.cpp b/src/resources/ambientoverlay.cpp
new file mode 100644
index 000000000..8f579c8c7
--- /dev/null
+++ b/src/resources/ambientoverlay.cpp
@@ -0,0 +1,126 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/ambientoverlay.h"
+
+#include "graphics.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+AmbientOverlay::AmbientOverlay(Image *img, float parallax,
+ float speedX, float speedY, bool keepRatio):
+ mImage(img), mParallax(parallax),
+ mPosX(0), mPosY(0),
+ mSpeedX(speedX), mSpeedY(speedY),
+ mKeepRatio(keepRatio)
+{
+ if (!mImage)
+ return;
+
+ if (mImage && keepRatio && !mImage->useOpenGL()
+ /*&& defaultScreenWidth != 0
+ && defaultScreenHeight != 0*/
+ && graphics->getWidth() != defaultScreenWidth
+ && graphics->getHeight() != defaultScreenHeight)
+ {
+ // Rescale the overlay to keep the ratio as if we were on
+ // the default resolution...
+ Image *rescaledOverlay = mImage->SDLgetScaledImage(
+ static_cast<int>(mImage->getWidth()) / defaultScreenWidth
+ * graphics->getWidth(), static_cast<int>(mImage->getHeight())
+ / defaultScreenHeight * graphics->getHeight());
+
+ if (rescaledOverlay)
+ {
+ // Replace the resource with the new one...
+ std::string idPath = mImage->getIdPath() + "_rescaled";
+ ResourceManager::getInstance()->addResource(
+ idPath, rescaledOverlay);
+ mImage = rescaledOverlay;
+ }
+ else
+ {
+ mImage->incRef();
+ }
+ }
+ else
+ {
+ mImage->incRef();
+ }
+}
+
+AmbientOverlay::~AmbientOverlay()
+{
+ if (mImage)
+ mImage->decRef();
+}
+
+void AmbientOverlay::update(int timePassed, float dx, float dy)
+{
+ if (!mImage)
+ return;
+
+ // Self scrolling of the overlay
+ mPosX -= mSpeedX * static_cast<float>(timePassed) / 10;
+ mPosY -= mSpeedY * static_cast<float>(timePassed) / 10;
+
+ // Parallax scrolling
+ mPosX += dx * mParallax;
+ mPosY += dy * mParallax;
+
+ int imgW = mImage->getWidth();
+ int imgH = mImage->getHeight();
+
+ // Wrap values
+ while (mPosX > imgW)
+ mPosX -= static_cast<float>(imgW);
+ while (mPosX < 0)
+ mPosX += static_cast<float>(imgW);
+
+ while (mPosY > imgH)
+ mPosY -= static_cast<float>(imgH);
+ while (mPosY < 0)
+ mPosY += static_cast<float>(imgH);
+}
+
+void AmbientOverlay::draw(Graphics *graphics, int x, int y)
+{
+ if (!mImage)
+ return;
+
+ if (!mImage->useOpenGL() || !mKeepRatio)
+ {
+ graphics->drawImagePattern(mImage, static_cast<int>(-mPosX),
+ static_cast<int>(-mPosY), x + static_cast<int>(mPosX),
+ y + static_cast<int>(mPosY));
+ }
+ else
+ {
+ graphics->drawRescaledImagePattern(mImage, static_cast<int>(-mPosX),
+ static_cast<int>(-mPosY), x + static_cast<int>(mPosX),
+ y + static_cast<int>(mPosY),
+ static_cast<int>(mImage->getWidth()) / defaultScreenWidth
+ * graphics->getWidth(),
+ static_cast<int>(mImage->getHeight()) / defaultScreenHeight
+ * graphics->getHeight());
+ }
+}
diff --git a/src/resources/ambientoverlay.h b/src/resources/ambientoverlay.h
new file mode 100644
index 000000000..483ee98ed
--- /dev/null
+++ b/src/resources/ambientoverlay.h
@@ -0,0 +1,60 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef RESOURCES_AMBIENTOVERLAY_H
+#define RESOURCES_AMBIENTOVERLAY_H
+
+class Graphics;
+class Image;
+
+class AmbientOverlay
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param img the image this overlay displays
+ * @param parallax scroll factor based on camera position
+ * @param speedX scrolling speed in x-direction
+ * @param speedY scrolling speed in y-direction
+ * @param keepRatio rescale the image to keep
+ * the same ratio than in 800x600 resolution mode.
+ */
+ AmbientOverlay(Image *img, float parallax,
+ float speedX, float speedY, bool keepRatio = false);
+
+ ~AmbientOverlay();
+
+ void update(int timePassed, float dx, float dy);
+
+ void draw(Graphics *graphics, int x, int y);
+
+ private:
+ Image *mImage;
+ float mParallax;
+ float mPosX; /**< Current layer X position. */
+ float mPosY; /**< Current layer Y position. */
+ float mSpeedX; /**< Scrolling speed in X direction. */
+ float mSpeedY; /**< Scrolling speed in Y direction. */
+ bool mKeepRatio; /**< Keep overlay ratio on every resolution */
+};
+
+#endif
diff --git a/src/resources/animation.cpp b/src/resources/animation.cpp
new file mode 100644
index 000000000..f6ececba0
--- /dev/null
+++ b/src/resources/animation.cpp
@@ -0,0 +1,46 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/animation.h"
+
+#include "utils/dtor.h"
+
+Animation::Animation():
+ mDuration(0)
+{
+}
+
+void Animation::addFrame(Image *image, int delay, int offsetX, int offsetY)
+{
+ Frame frame = { image, delay, offsetX, offsetY };
+ mFrames.push_back(frame);
+ mDuration += delay;
+}
+
+void Animation::addTerminator()
+{
+ addFrame(NULL, 0, 0, 0);
+}
+
+bool Animation::isTerminator(const Frame &candidate)
+{
+ return (candidate.image == NULL);
+}
diff --git a/src/resources/animation.h b/src/resources/animation.h
new file mode 100644
index 000000000..e472adc40
--- /dev/null
+++ b/src/resources/animation.h
@@ -0,0 +1,90 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ANIMATION_H
+#define ANIMATION_H
+
+#include <libxml/tree.h>
+
+#include <vector>
+
+class Image;
+
+/**
+ * A single frame in an animation, with a delay and an offset.
+ */
+struct Frame
+{
+ Image *image;
+ int delay;
+ int offsetX;
+ int offsetY;
+};
+
+/**
+ * An animation consists of several frames, each with their own delay and
+ * offset.
+ */
+class Animation
+{
+ public:
+ Animation();
+
+ /**
+ * Appends a new animation at the end of the sequence.
+ */
+ void addFrame(Image *image, int delay, int offsetX, int offsetY);
+
+ /**
+ * Appends an animation terminator that states that the animation
+ * should not loop.
+ */
+ void addTerminator();
+
+ /**
+ * Returns the frame at the specified index.
+ */
+ Frame *getFrame(int index)
+ { return &(mFrames[index]); }
+
+ /**
+ * Returns the length of this animation in frames.
+ */
+ unsigned int getLength() const
+ { return static_cast<unsigned>(mFrames.size()); }
+
+ /**
+ * Returns the duration of this animation.
+ */
+ int getDuration() const
+ { return mDuration; }
+
+ /**
+ * Determines whether the given animation frame is a terminator.
+ */
+ static bool isTerminator(const Frame &phase);
+
+ protected:
+ std::vector<Frame> mFrames;
+ int mDuration;
+};
+
+#endif
diff --git a/src/resources/beinginfo.cpp b/src/resources/beinginfo.cpp
new file mode 100644
index 000000000..1b2ed3be1
--- /dev/null
+++ b/src/resources/beinginfo.cpp
@@ -0,0 +1,115 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/beinginfo.h"
+
+#include "log.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+
+BeingInfo *BeingInfo::Unknown = new BeingInfo;
+
+BeingInfo::BeingInfo():
+ mName(_("unnamed")),
+ mTargetCursorSize(ActorSprite::TC_MEDIUM),
+ mWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER
+ | Map::BLOCKMASK_MONSTER),
+ mBlockType(Map::BLOCKTYPE_CHARACTER),
+ mTargetOffsetX(0), mTargetOffsetY(0),
+ mMaxHP(0), mStaticMaxHP(false)
+{
+ SpriteDisplay display;
+ display.sprites.push_back(SpriteReference::Empty);
+
+ setDisplay(display);
+}
+
+BeingInfo::~BeingInfo()
+{
+ delete_all(mSounds);
+ delete_all(mAttacks);
+ mSounds.clear();
+}
+
+void BeingInfo::setDisplay(SpriteDisplay display)
+{
+ mDisplay = display;
+}
+
+void BeingInfo::setTargetCursorSize(const std::string &size)
+{
+ if (size == "small")
+ {
+ setTargetCursorSize(ActorSprite::TC_SMALL);
+ }
+ else if (size == "medium")
+ {
+ setTargetCursorSize(ActorSprite::TC_MEDIUM);
+ }
+ else if (size == "large")
+ {
+ setTargetCursorSize(ActorSprite::TC_LARGE);
+ }
+ else
+ {
+ logger->log("Unknown target cursor type \"%s\" for %s - using medium "
+ "sized one", size.c_str(), getName().c_str());
+ setTargetCursorSize(ActorSprite::TC_MEDIUM);
+ }
+}
+
+void BeingInfo::addSound(SoundEvent event, const std::string &filename)
+{
+ if (mSounds.find(event) == mSounds.end())
+ mSounds[event] = new std::vector<std::string>;
+
+ if (mSounds[event])
+ mSounds[event]->push_back("sfx/" + filename);
+}
+
+const std::string &BeingInfo::getSound(SoundEvent event) const
+{
+ static std::string empty("");
+
+ SoundEvents::const_iterator i = mSounds.find(event);
+ return (i == mSounds.end()) ? empty :
+ i->second->at(rand() % i->second->size());
+}
+
+const Attack *BeingInfo::getAttack(int type) const
+{
+ // need remove in destructor?
+ static Attack *empty = new Attack(SpriteAction::ATTACK, "", "");
+
+ Attacks::const_iterator i = mAttacks.find(type);
+ return (i == mAttacks.end()) ? empty : (*i).second;
+}
+
+void BeingInfo::addAttack(int id, std::string action,
+ const std::string &particleEffect,
+ const std::string &missileParticle)
+{
+ if (mAttacks[id])
+ delete mAttacks[id];
+
+ mAttacks[id] = new Attack(action, particleEffect, missileParticle);
+}
diff --git a/src/resources/beinginfo.h b/src/resources/beinginfo.h
new file mode 100644
index 000000000..08fa1443e
--- /dev/null
+++ b/src/resources/beinginfo.h
@@ -0,0 +1,161 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef BEINGINFO_H
+#define BEINGINFO_H
+
+#include "actorsprite.h"
+
+#include "resources/spritedef.h"
+
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+struct Attack
+{
+ std::string action;
+ std::string particleEffect;
+ std::string missileParticle;
+
+ Attack(std::string action, std::string particleEffect,
+ std::string missileParticle)
+ {
+ this->action = action;
+ this->particleEffect = particleEffect;
+ this->missileParticle = missileParticle;
+ }
+};
+
+typedef std::map<int, Attack*> Attacks;
+
+enum SoundEvent
+{
+ SOUND_EVENT_HIT = 0,
+ SOUND_EVENT_MISS,
+ SOUND_EVENT_HURT,
+ SOUND_EVENT_DIE
+};
+
+typedef std::map<SoundEvent, std::vector<std::string>* > SoundEvents;
+
+/**
+ * Holds information about a certain type of monster. This includes the name
+ * of the monster, the sprite to display and the sounds the monster makes.
+ *
+ * @see MonsterDB
+ * @see NPCDB
+ */
+class BeingInfo
+{
+ public:
+ static BeingInfo *Unknown;
+
+ BeingInfo();
+
+ ~BeingInfo();
+
+ void setName(const std::string &name) { mName = name; }
+
+ const std::string &getName() const
+ { return mName; }
+
+ void setDisplay(SpriteDisplay display);
+
+ const SpriteDisplay &getDisplay() const
+ { return mDisplay; }
+
+ void setTargetCursorSize(const std::string &size);
+
+ void setTargetCursorSize(ActorSprite::TargetCursorSize targetSize)
+ { mTargetCursorSize = targetSize; }
+
+ ActorSprite::TargetCursorSize getTargetCursorSize() const
+ { return mTargetCursorSize; }
+
+ void addSound(SoundEvent event, const std::string &filename);
+
+ const std::string &getSound(SoundEvent event) const;
+
+ void addAttack(int id, std::string action,
+ const std::string &particleEffect,
+ const std::string &missileParticle);
+
+ const Attack *getAttack(int type) const;
+
+ void setWalkMask(unsigned char mask)
+ { mWalkMask = mask; }
+
+ /**
+ * Gets the way the being is blocked by other objects
+ */
+ unsigned char getWalkMask() const
+ { return mWalkMask; }
+
+ void setBlockType(Map::BlockType blockType)
+ { mBlockType = blockType; }
+
+ Map::BlockType getBlockType() const
+ { return mBlockType; }
+
+ void setTargetOffsetX(int n)
+ { mTargetOffsetX = n; }
+
+ int getTargetOffsetX() const
+ { return mTargetOffsetX; }
+
+ void setTargetOffsetY(int n)
+ { mTargetOffsetY = n; }
+
+ int getTargetOffsetY() const
+ { return mTargetOffsetY; }
+
+ void setMaxHP(int n)
+ { mMaxHP = n; }
+
+ int getMaxHP() const
+ { return mMaxHP; }
+
+ bool isStaticMaxHP() const
+ { return mStaticMaxHP; }
+
+ void setStaticMaxHP(bool n)
+ { mStaticMaxHP = n; }
+
+ private:
+ SpriteDisplay mDisplay;
+ std::string mName;
+ ActorSprite::TargetCursorSize mTargetCursorSize;
+ SoundEvents mSounds;
+ Attacks mAttacks;
+ unsigned char mWalkMask;
+ Map::BlockType mBlockType;
+ int mTargetOffsetX;
+ int mTargetOffsetY;
+ int mMaxHP;
+ bool mStaticMaxHP;
+};
+
+typedef std::map<int, BeingInfo*> BeingInfos;
+typedef BeingInfos::iterator BeingInfoIterator;
+
+#endif // BEINGINFO_H
diff --git a/src/resources/colordb.cpp b/src/resources/colordb.cpp
new file mode 100644
index 000000000..97842b02d
--- /dev/null
+++ b/src/resources/colordb.cpp
@@ -0,0 +1,115 @@
+/*
+ * Color database
+ * Copyright (C) 2008 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/colordb.h"
+
+#include "log.h"
+
+#include "utils/xml.h"
+
+#include <libxml/tree.h>
+
+namespace
+{
+ ColorDB::Colors mColors;
+ bool mLoaded = false;
+ std::string mFail = "#ffffff";
+}
+
+void ColorDB::load()
+{
+ if (mLoaded)
+ unload();
+
+ XML::Document *doc = new XML::Document("hair.xml");
+ xmlNodePtr root = doc->rootNode();
+ bool hairXml = true;
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
+ {
+ logger->log1("Trying to fall back on colors.xml");
+
+ hairXml = false;
+
+ delete doc;
+ doc = new XML::Document("colors.xml");
+ root = doc->rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
+ {
+ logger->log1("ColorDB: Failed to find any color files.");
+ mColors[0] = mFail;
+ mLoaded = true;
+
+ delete doc;
+
+ return;
+ }
+ }
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "color"))
+ {
+ int id = XML::getProperty(node, "id", 0);
+
+ if (mColors.find(id) != mColors.end())
+ logger->log("ColorDB: Redefinition of dye ID %d", id);
+
+ mColors[id] = hairXml ?
+ XML::getProperty(node, "value", "#FFFFFF") :
+ XML::getProperty(node, "dye", "#FFFFFF");
+ }
+ }
+
+ delete doc;
+
+ mLoaded = true;
+}
+
+void ColorDB::unload()
+{
+ logger->log1("Unloading color database...");
+
+ mColors.clear();
+ mLoaded = false;
+}
+
+std::string &ColorDB::get(int id)
+{
+ if (!mLoaded)
+ load();
+
+ ColorIterator i = mColors.find(id);
+
+ if (i == mColors.end())
+ {
+ logger->log("ColorDB: Error, unknown dye ID# %d", id);
+ return mFail;
+ }
+ else
+ {
+ return i->second;
+ }
+}
+
+int ColorDB::size()
+{
+ return static_cast<int>(mColors.size());
+}
diff --git a/src/resources/colordb.h b/src/resources/colordb.h
new file mode 100644
index 000000000..57b523882
--- /dev/null
+++ b/src/resources/colordb.h
@@ -0,0 +1,51 @@
+/*
+ * Color database
+ * Copyright (C) 2008 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef COLOR_MANAGER_H
+#define COLOR_MANAGER_H
+
+#include <map>
+#include <string>
+
+/**
+ * Color information database.
+ */
+namespace ColorDB
+{
+ /**
+ * Loads the color data from <code>colors.xml</code>.
+ */
+ void load();
+
+ /**
+ * Clear the color data
+ */
+ void unload();
+
+ std::string &get(int id);
+
+ int size();
+
+ // Color DB
+ typedef std::map<int, std::string> Colors;
+ typedef Colors::iterator ColorIterator;
+}
+
+#endif
diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp
new file mode 100644
index 000000000..6f9609453
--- /dev/null
+++ b/src/resources/dye.cpp
@@ -0,0 +1,320 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/dye.h"
+
+#include "log.h"
+
+#include <math.h>
+#include <sstream>
+
+DyePalette::DyePalette(const std::string &description)
+{
+ int size = static_cast<int>(description.length());
+ if (size == 0)
+ return;
+ if (description[0] != '#')
+ {
+ // TODO: load palette from file.
+ return;
+ }
+
+ int pos = 1;
+ for ( ; ; )
+ {
+ if (pos + 6 > size)
+ break;
+
+ int v = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ char c = description[pos + i];
+ int n;
+
+ if ('0' <= c && c <= '9')
+ n = c - '0';
+ else if ('A' <= c && c <= 'F')
+ n = c - 'A' + 10;
+ else if ('a' <= c && c <= 'f')
+ n = c - 'a' + 10;
+ else
+ goto error;
+
+ v = (v << 4) | n;
+ }
+ Color c =
+ {
+ {
+ static_cast<unsigned char>(v >> 16),
+ static_cast<unsigned char>(v >> 8),
+ static_cast<unsigned char>(v)
+ }
+ };
+ mColors.push_back(c);
+ pos += 6;
+
+ if (pos == size)
+ return;
+ if (description[pos] != ',')
+ break;
+
+ ++pos;
+ }
+
+ error:
+ logger->log("Error, invalid embedded palette: %s", description.c_str());
+}
+
+/*
+void DyePalette::addFirstColor(const int color[3])
+{
+ Color c = { {color[0], color[1], color[2]} };
+ mColors.insert(mColors.begin(), c);
+}
+
+void DyePalette::addLastColor(const int color[3])
+{
+ Color c = { {color[0], color[1], color[2]} };
+ mColors.push_back(c);
+}
+*/
+
+void DyePalette::getColor(int intensity, int color[3]) const
+{
+ if (intensity == 0)
+ {
+ color[0] = 0;
+ color[1] = 0;
+ color[2] = 0;
+ return;
+ }
+
+ int last = static_cast<int>(mColors.size());
+ if (last == 0) return;
+
+ int i = intensity * last / 255;
+ int t = intensity * last % 255;
+
+ int j = t != 0 ? i : i - 1;
+
+ if (j >= last)
+ j = 0;
+
+ // Get the exact color if any, the next color otherwise.
+ int r2 = mColors[j].value[0],
+ g2 = mColors[j].value[1],
+ b2 = mColors[j].value[2];
+
+ if (t == 0)
+ {
+ // Exact color.
+ color[0] = r2;
+ color[1] = g2;
+ color[2] = b2;
+ return;
+ }
+
+ // Get the previous color. First color is implicitly black.
+ int r1 = 0, g1 = 0, b1 = 0;
+ if (i > 0)
+ {
+ r1 = mColors[i - 1].value[0];
+ g1 = mColors[i - 1].value[1];
+ b1 = mColors[i - 1].value[2];
+ }
+
+ // Perform a linear interpolation.
+ color[0] = ((255 - t) * r1 + t * r2) / 255;
+ color[1] = ((255 - t) * g1 + t * g2) / 255;
+ color[2] = ((255 - t) * b1 + t * b2) / 255;
+}
+
+void DyePalette::getColor(double intensity, int color[3]) const
+{
+ // Nothing to do here
+ if (mColors.size() == 0)
+ return;
+
+ // Force range
+ if (intensity > 1.0)
+ intensity = 1.0;
+ else if (intensity < 0.0)
+ intensity = 0.0;
+
+ // Scale up
+ intensity = intensity * static_cast<double>(mColors.size() - 1);
+
+ // Color indices
+ int i = static_cast<int>(floor(intensity));
+ int j = static_cast<int>(ceil(intensity));
+
+ if (i == j)
+ {
+ // Exact color.
+ color[0] = mColors[i].value[0];
+ color[1] = mColors[i].value[1];
+ color[2] = mColors[i].value[2];
+ return;
+ }
+
+ intensity -= i;
+ double rest = 1 - intensity;
+
+ // Get the colors
+ int r1 = mColors[i].value[0],
+ g1 = mColors[i].value[1],
+ b1 = mColors[i].value[2],
+ r2 = mColors[j].value[0],
+ g2 = mColors[j].value[1],
+ b2 = mColors[j].value[2];
+
+ // Perform the interpolation.
+ color[0] = static_cast<int>(rest * r1 + intensity * r2);
+ color[1] = static_cast<int>(rest * g1 + intensity * g2);
+ color[2] = static_cast<int>(rest * b1 + intensity * b2);
+}
+
+Dye::Dye(const std::string &description)
+{
+ for (int i = 0; i < 7; ++i)
+ mDyePalettes[i] = 0;
+
+ if (description.empty())
+ return;
+
+ std::string::size_type next_pos = 0, length = description.length();
+ do
+ {
+ std::string::size_type pos = next_pos;
+ next_pos = description.find(';', pos);
+
+ if (next_pos == std::string::npos)
+ next_pos = length;
+
+ if (next_pos <= pos + 3 || description[pos + 1] != ':')
+ {
+ logger->log("Error, invalid dye: %s", description.c_str());
+ return;
+ }
+
+ int i = 0;
+
+ switch (description[pos])
+ {
+ case 'R': i = 0; break;
+ case 'G': i = 1; break;
+ case 'Y': i = 2; break;
+ case 'B': i = 3; break;
+ case 'M': i = 4; break;
+ case 'C': i = 5; break;
+ case 'W': i = 6; break;
+ default:
+ logger->log("Error, invalid dye: %s", description.c_str());
+ return;
+ }
+ mDyePalettes[i] = new DyePalette(description.substr(
+ pos + 2, next_pos - pos - 2));
+ ++next_pos;
+ }
+ while (next_pos < length);
+}
+
+Dye::~Dye()
+{
+ for (int i = 0; i < 7; ++i)
+ {
+ delete mDyePalettes[i];
+ mDyePalettes[i] = 0;
+ }
+}
+
+void Dye::update(int color[3]) const
+{
+ int cmax = std::max(color[0], std::max(color[1], color[2]));
+ if (cmax == 0)
+ return;
+
+ int cmin = std::min(color[0], std::min(color[1], color[2]));
+ int intensity = color[0] + color[1] + color[2];
+
+ if (cmin != cmax &&
+ (cmin != 0 || (intensity != cmax && intensity != 2 * cmax)))
+ {
+ // not pure
+ return;
+ }
+
+ int i = (color[0] != 0) | ((color[1] != 0) << 1) | ((color[2] != 0) << 2);
+
+ if (mDyePalettes[i - 1])
+ mDyePalettes[i - 1]->getColor(cmax, color);
+}
+
+void Dye::instantiate(std::string &target, const std::string &palettes)
+{
+ std::string::size_type next_pos = target.find('|');
+
+ if (next_pos == std::string::npos || palettes.empty())
+ return;
+
+ ++next_pos;
+
+ std::ostringstream s;
+ s << target.substr(0, next_pos);
+ std::string::size_type last_pos = target.length(), pal_pos = 0;
+ do
+ {
+ std::string::size_type pos = next_pos;
+ next_pos = target.find(';', pos);
+
+ if (next_pos == std::string::npos)
+ next_pos = last_pos;
+
+ if (next_pos == pos + 1 && pal_pos != std::string::npos)
+ {
+ std::string::size_type pal_next_pos = palettes.find(';', pal_pos);
+ s << target[pos] << ':';
+ if (pal_next_pos == std::string::npos)
+ {
+ s << palettes.substr(pal_pos);
+ s << target.substr(next_pos);
+ pal_pos = std::string::npos;
+ break;
+ }
+ s << palettes.substr(pal_pos, pal_next_pos - pal_pos);
+ pal_pos = pal_next_pos + 1;
+ }
+ else if (next_pos > pos + 2)
+ {
+ s << target.substr(pos, next_pos - pos);
+ }
+ else
+ {
+ logger->log("Error, invalid dye placeholder: %s", target.c_str());
+ return;
+ }
+ s << target[next_pos];
+ ++next_pos;
+ }
+ while (next_pos < last_pos);
+
+ target = s.str();
+}
diff --git a/src/resources/dye.h b/src/resources/dye.h
new file mode 100644
index 000000000..b2f62547a
--- /dev/null
+++ b/src/resources/dye.h
@@ -0,0 +1,107 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef DYE_H
+#define DYE_H
+
+#include <string>
+#include <vector>
+
+/**
+ * Class for performing a linear interpolation between colors.
+ */
+class DyePalette
+{
+ public:
+
+ /**
+ * Creates a palette based on the given string.
+ * The string is either a file name or a sequence of hexadecimal RGB
+ * values separated by ',' and starting with '#'.
+ */
+ DyePalette(const std::string &pallete);
+
+/*
+ void addFirstColor(const int color[3]);
+
+ void addLastColor(const int color[3]);
+*/
+
+ /**
+ * Gets a pixel color depending on its intensity. First color is
+ * implicitly black (0, 0, 0).
+ */
+ void getColor(int intensity, int color[3]) const;
+
+ /**
+ * Gets a pixel color depending on its intensity.
+ */
+ void getColor(double intensity, int color[3]) const;
+
+ private:
+
+ struct Color { unsigned char value[3]; };
+
+ std::vector< Color > mColors;
+};
+
+/**
+ * Class for dispatching pixel-recoloring amongst several palettes.
+ */
+class Dye
+{
+ public:
+
+ /**
+ * Creates a set of palettes based on the given string.
+ *
+ * The parts of string are separated by semi-colons. Each part starts
+ * by an uppercase letter, followed by a colon and then a palette name.
+ */
+ Dye(const std::string &dye);
+
+ /**
+ * Destroys the associated palettes.
+ */
+ ~Dye();
+
+ /**
+ * Modifies a pixel color.
+ */
+ void update(int color[3]) const;
+
+ /**
+ * Fills the blank in a dye placeholder with some palette names.
+ */
+ static void instantiate(std::string &target,
+ const std::string &palettes);
+
+ private:
+
+ /**
+ * The order of the palettes, as well as their uppercase letter, is:
+ *
+ * Red, Green, Yellow, Blue, Magenta, White (or rather gray).
+ */
+ DyePalette *mDyePalettes[7];
+};
+
+#endif
diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp
new file mode 100644
index 000000000..4d0ba34b4
--- /dev/null
+++ b/src/resources/emotedb.cpp
@@ -0,0 +1,222 @@
+/*
+ * Emote database
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/emotedb.h"
+
+#include "animatedsprite.h"
+#include "log.h"
+
+#include "utils/xml.h"
+#include "configuration.h"
+
+namespace
+{
+ EmoteInfos mEmoteInfos;
+ EmoteInfo mUnknown;
+ bool mLoaded = false;
+ int mLastEmote = 0;
+}
+
+void EmoteDB::load()
+{
+ if (mLoaded)
+ unload();
+
+ mLastEmote = 0;
+
+ EmoteSprite *unknownSprite = new EmoteSprite;
+ unknownSprite->sprite = AnimatedSprite::load(
+ paths.getStringValue("spriteErrorFile"));
+ unknownSprite->name = "unknown";
+ mUnknown.sprites.push_back(unknownSprite);
+
+ logger->log1("Initializing emote database...");
+
+ XML::Document doc("emotes.xml");
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "emotes"))
+ {
+ logger->log1("Emote Database: Error while loading emotes.xml!");
+ return;
+ }
+
+ //iterate <emote>s
+ for_each_xml_child_node(emoteNode, rootNode)
+ {
+ if (!xmlStrEqual(emoteNode->name, BAD_CAST "emote"))
+ continue;
+
+ int id = XML::getProperty(emoteNode, "id", -1);
+ if (id == -1)
+ {
+ logger->log1("Emote Database: Emote with missing ID in "
+ "emotes.xml!");
+ continue;
+ }
+
+ EmoteInfo *currentInfo = new EmoteInfo;
+
+ for_each_xml_child_node(spriteNode, emoteNode)
+ {
+ if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
+ {
+ EmoteSprite *currentSprite = new EmoteSprite;
+ std::string file = paths.getStringValue("sprites")
+ + (std::string) (const char*)
+ spriteNode->xmlChildrenNode->content;
+ currentSprite->sprite = AnimatedSprite::load(file,
+ XML::getProperty(spriteNode, "variant", 0));
+ currentSprite->name = XML::getProperty(spriteNode, "name", "");
+ currentInfo->sprites.push_back(currentSprite);
+ }
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
+ {
+ std::string particlefx = (const char*)(
+ spriteNode->xmlChildrenNode->content);
+ currentInfo->particles.push_back(particlefx);
+ }
+ }
+ mEmoteInfos[id] = currentInfo;
+ if (id > mLastEmote)
+ mLastEmote = id;
+ }
+
+
+ XML::Document doc2("graphics/sprites/manaplus_emotes.xml");
+ rootNode = doc2.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "emotes"))
+ {
+ logger->log1("Emote Database: Error while loading"
+ " manaplus_emotes.xml!");
+ return;
+ }
+
+ //iterate <emote>s
+ for_each_xml_child_node(emoteNode, rootNode)
+ {
+ if (!xmlStrEqual(emoteNode->name, BAD_CAST "emote"))
+ continue;
+
+ int id = XML::getProperty(emoteNode, "id", -1);
+ if (id == -1)
+ {
+ logger->log1("Emote Database: Emote with missing ID in "
+ "manaplus_emotes.xml!");
+ continue;
+ }
+
+ EmoteInfo *currentInfo = new EmoteInfo;
+
+ for_each_xml_child_node(spriteNode, emoteNode)
+ {
+ if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
+ {
+ EmoteSprite *currentSprite = new EmoteSprite;
+ std::string file = paths.getStringValue("sprites")
+ + (std::string) (const char*)
+ spriteNode->xmlChildrenNode->content;
+ currentSprite->sprite = AnimatedSprite::load(file,
+ XML::getProperty(spriteNode, "variant", 0));
+ currentSprite->name = XML::getProperty(spriteNode, "name", "");
+ currentInfo->sprites.push_back(currentSprite);
+ }
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
+ {
+ std::string particlefx = (const char*)(
+ spriteNode->xmlChildrenNode->content);
+ currentInfo->particles.push_back(particlefx);
+ }
+ }
+ mEmoteInfos[id] = currentInfo;
+ if (id > mLastEmote)
+ mLastEmote = id;
+ }
+
+ mLoaded = true;
+}
+
+void EmoteDB::unload()
+{
+ for (EmoteInfos::const_iterator i = mEmoteInfos.begin();
+ i != mEmoteInfos.end();
+ i++)
+ {
+ while (!i->second->sprites.empty())
+ {
+ delete i->second->sprites.front()->sprite;
+ delete i->second->sprites.front();
+ i->second->sprites.pop_front();
+ }
+ delete i->second;
+ }
+
+ mEmoteInfos.clear();
+
+ while (!mUnknown.sprites.empty())
+ {
+ delete mUnknown.sprites.front()->sprite;
+ delete mUnknown.sprites.front();
+ mUnknown.sprites.pop_front();
+ }
+
+ mLoaded = false;
+}
+
+const EmoteInfo *EmoteDB::get(int id, bool allowNull)
+{
+ EmoteInfos::const_iterator i = mEmoteInfos.find(id);
+
+ if (i == mEmoteInfos.end())
+ {
+ if (allowNull)
+ return NULL;
+ logger->log("EmoteDB: Warning, unknown emote ID %d requested", id);
+ return &mUnknown;
+ }
+ else
+ {
+ return i->second;
+ }
+}
+
+const AnimatedSprite *EmoteDB::getAnimation(int id, bool allowNull)
+{
+ const EmoteInfo *info = get(id, allowNull);
+ if (!info)
+ return NULL;
+
+ return info->sprites.front()->sprite;
+}
+
+const EmoteSprite *EmoteDB::getSprite(int id, bool allowNull)
+{
+ const EmoteInfo *info = get(id, allowNull);
+ if (!info)
+ return NULL;
+
+ return info->sprites.front();
+}
+
+const int &EmoteDB::getLast()
+{
+ return mLastEmote;
+}
diff --git a/src/resources/emotedb.h b/src/resources/emotedb.h
new file mode 100644
index 000000000..f9a4b8f9f
--- /dev/null
+++ b/src/resources/emotedb.h
@@ -0,0 +1,64 @@
+/*
+ * Emote database
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef EMOTE_DB_H
+#define EMOTE_DB_H
+
+#include <list>
+#include <map>
+#include <string>
+
+class AnimatedSprite;
+
+struct EmoteSprite
+{
+ const AnimatedSprite *sprite;
+ std::string name;
+};
+
+struct EmoteInfo
+{
+ std::list<EmoteSprite*> sprites;
+ std::list<std::string> particles;
+};
+
+typedef std::map<int, EmoteInfo*> EmoteInfos;
+
+/**
+ * Emote information database.
+ */
+namespace EmoteDB
+{
+ void load();
+
+ void unload();
+
+ const EmoteInfo *get(int id, bool allowNull = false);
+
+ const AnimatedSprite *getAnimation(int id, bool allowNull = false);
+
+ const EmoteSprite *getSprite(int id, bool allowNull = false);
+
+ const int &getLast();
+
+ typedef EmoteInfos::iterator EmoteInfosIterator;
+}
+
+#endif
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
new file mode 100644
index 000000000..78cec909b
--- /dev/null
+++ b/src/resources/image.cpp
@@ -0,0 +1,797 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/image.h"
+
+#include "resources/dye.h"
+#include "resources/resourcemanager.h"
+
+#ifdef USE_OPENGL
+#include "openglgraphics.h"
+#include "opengl1graphics.h"
+#endif
+
+#include "log.h"
+#include "main.h"
+
+#include "utils/stringutils.h"
+
+#include <SDL_image.h>
+#include <SDL_rotozoom.h>
+
+#ifdef USE_OPENGL
+int Image::mUseOpenGL = 0;
+int Image::mTextureType = 0;
+int Image::mTextureSize = 0;
+#endif
+bool Image::mEnableAlphaCache = false;
+bool Image::mEnableAlpha = true;
+
+Image::Image(SDL_Surface *image, bool hasAlphaChannel, Uint8 *alphaChannel):
+ mAlpha(1.0f),
+ mHasAlphaChannel(hasAlphaChannel),
+ mSDLSurface(image),
+ mAlphaChannel(alphaChannel)
+{
+#ifdef USE_OPENGL
+ mGLImage = 0;
+#endif
+
+ mUseAlphaCache = Image::mEnableAlphaCache;
+
+ mBounds.x = 0;
+ mBounds.y = 0;
+
+ mLoaded = false;
+
+ if (mSDLSurface)
+ {
+ mBounds.w = static_cast<Uint16>(mSDLSurface->w);
+ mBounds.h = static_cast<Uint16>(mSDLSurface->h);
+
+ mLoaded = true;
+ }
+ else
+ {
+ logger->log(
+ "Image::Image(SDL_Surface*): Couldn't load invalid Surface!");
+ }
+}
+
+#ifdef USE_OPENGL
+Image::Image(GLuint glimage, int width, int height,
+ int texWidth, int texHeight):
+ mAlpha(1.0f),
+ mHasAlphaChannel(true),
+ mSDLSurface(0),
+ mAlphaChannel(0),
+ mUseAlphaCache(false),
+ mGLImage(glimage),
+ mTexWidth(texWidth),
+ mTexHeight(texHeight)
+{
+ mBounds.x = 0;
+ mBounds.y = 0;
+ mBounds.w = static_cast<Uint16>(width);
+ mBounds.h = static_cast<Uint16>(height);
+
+ if (mGLImage)
+ {
+ mLoaded = true;
+ }
+ else
+ {
+ logger->log(
+ "Image::Image(GLuint*, ...): Couldn't load invalid Surface!");
+ mLoaded = false;
+ }
+}
+#endif
+
+Image::~Image()
+{
+ unload();
+}
+
+Resource *Image::load(void *buffer, unsigned bufferSize)
+{
+ // Load the raw file data from the buffer in an RWops structure
+ SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
+ SDL_Surface *tmpImage = IMG_Load_RW(rw, 1);
+
+ if (!tmpImage)
+ {
+ logger->log("Error, image load failed: %s", IMG_GetError());
+ return NULL;
+ }
+
+ Image *image = load(tmpImage);
+
+ SDL_FreeSurface(tmpImage);
+ return image;
+}
+
+Resource *Image::load(void *buffer, unsigned bufferSize, Dye const &dye)
+{
+ SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
+ SDL_Surface *tmpImage = IMG_Load_RW(rw, 1);
+
+ if (!tmpImage)
+ {
+ logger->log("Error, image load failed: %s", IMG_GetError());
+ return NULL;
+ }
+
+ SDL_PixelFormat rgba;
+ rgba.palette = NULL;
+ rgba.BitsPerPixel = 32;
+ rgba.BytesPerPixel = 4;
+ rgba.Rmask = 0xFF000000; rgba.Rloss = 0; rgba.Rshift = 24;
+ rgba.Gmask = 0x00FF0000; rgba.Gloss = 0; rgba.Gshift = 16;
+ rgba.Bmask = 0x0000FF00; rgba.Bloss = 0; rgba.Bshift = 8;
+ rgba.Amask = 0x000000FF; rgba.Aloss = 0; rgba.Ashift = 0;
+ rgba.colorkey = 0;
+ rgba.alpha = 255;
+
+ SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE);
+ SDL_FreeSurface(tmpImage);
+
+ Uint32 *pixels = static_cast< Uint32 * >(surf->pixels);
+ for (Uint32 *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
+ {
+ int alpha = *pixels & 255;
+ if (!alpha) continue;
+ int v[3];
+ v[0] = (*pixels >> 24) & 255;
+ v[1] = (*pixels >> 16) & 255;
+ v[2] = (*pixels >> 8 ) & 255;
+ dye.update(v);
+ *pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha;
+ }
+
+ Image *image = load(surf);
+ SDL_FreeSurface(surf);
+ return image;
+}
+
+Image *Image::load(SDL_Surface *tmpImage)
+{
+#ifdef USE_OPENGL
+ if (mUseOpenGL)
+ return _GLload(tmpImage);
+#endif
+ return _SDLload(tmpImage);
+}
+
+void Image::SDLCleanCache()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ for (std::map<float, SDL_Surface*>::iterator
+ i = mAlphaCache.begin(), i_end = mAlphaCache.end();
+ i != i_end; ++i)
+ {
+ if (mSDLSurface != i->second)
+ resman->scheduleDelete(i->second);
+ i->second = 0;
+ }
+ mAlphaCache.clear();
+}
+
+void Image::unload()
+{
+ mLoaded = false;
+
+ if (mSDLSurface)
+ {
+ SDLCleanCache();
+ // Free the image surface.
+ SDL_FreeSurface(mSDLSurface);
+ mSDLSurface = NULL;
+
+ delete[] mAlphaChannel;
+ mAlphaChannel = NULL;
+ }
+
+#ifdef USE_OPENGL
+ if (mGLImage)
+ {
+ glDeleteTextures(1, &mGLImage);
+ mGLImage = 0;
+ }
+#endif
+}
+
+int Image::useOpenGL() const
+{
+#ifdef USE_OPENGL
+ return mUseOpenGL;
+#else
+ return 0;
+#endif
+}
+
+bool Image::hasAlphaChannel()
+{
+ if (mLoaded)
+ return mHasAlphaChannel;
+
+#ifdef USE_OPENGL
+ if (mUseOpenGL)
+ return true;
+#endif
+
+ return false;
+}
+
+SDL_Surface *Image::getByAlpha(float alpha)
+{
+ std::map<float, SDL_Surface*>::iterator it = mAlphaCache.find(alpha);
+ if (it != mAlphaCache.end())
+ return (*it).second;
+ return 0;
+}
+
+void Image::setAlpha(float alpha)
+{
+ if (mAlpha == alpha || !mEnableAlpha)
+ return;
+
+ if (alpha < 0.0f || alpha > 1.0f)
+ return;
+
+ if (mSDLSurface)
+ {
+ if (mUseAlphaCache)
+ {
+ SDL_Surface *surface = getByAlpha(mAlpha);
+ if (!surface)
+ {
+ if (mAlphaCache.size() > 100)
+ {
+#ifdef DEBUG_ALPHA_CACHE
+ logger->log("cleanCache");
+ for (std::map<float, SDL_Surface*>::iterator
+ i = mAlphaCache.begin(), i_end = mAlphaCache.end();
+ i != i_end; ++i)
+ {
+ logger->log("alpha: " + toString(i->first));
+ }
+#endif
+ SDLCleanCache();
+ }
+ surface = mSDLSurface;
+ if (surface)
+ mAlphaCache[mAlpha] = surface;
+ }
+ else
+ {
+ logger->log("cache bug");
+ }
+
+ surface = getByAlpha(alpha);
+ if (surface)
+ {
+// logger->log("hit");
+ if (mSDLSurface == surface)
+ logger->log("bug");
+// else
+// SDL_FreeSurface(mSDLSurface);
+ mAlphaCache.erase(alpha);
+ mSDLSurface = surface;
+ mAlpha = alpha;
+ return;
+ }
+ else
+ {
+ mSDLSurface = Image::SDLDuplicateSurface(mSDLSurface);
+ }
+ // logger->log("miss");
+ }
+
+ mAlpha = alpha;
+
+ if (!hasAlphaChannel())
+ {
+ // Set the alpha value this image is drawn at
+ SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA,
+ static_cast<unsigned char>(255 * mAlpha));
+ }
+ else
+ {
+ if (SDL_MUSTLOCK(mSDLSurface))
+ SDL_LockSurface(mSDLSurface);
+
+ // Precompute as much as possible
+ int maxHeight = std::min((mBounds.y + mBounds.h), mSDLSurface->h);
+ int maxWidth = std::min((mBounds.x + mBounds.w), mSDLSurface->w);
+ int i = 0;
+
+ for (int y = mBounds.y; y < maxHeight; y++)
+ {
+ for (int x = mBounds.x; x < maxWidth; x++)
+ {
+ i = y * mSDLSurface->w + x;
+ // Only change the pixel if it was visible at load time...
+ Uint8 sourceAlpha = mAlphaChannel[i];
+ if (sourceAlpha > 0)
+ {
+ Uint8 r, g, b, a;
+ SDL_GetRGBA((static_cast<Uint32*>
+ (mSDLSurface->pixels))[i],
+ mSDLSurface->format,
+ &r, &g, &b, &a);
+
+ a = (Uint8) (static_cast<float>(sourceAlpha) * mAlpha);
+
+ // Here is the pixel we want to set
+ (static_cast<Uint32 *>(mSDLSurface->pixels))[i] =
+ SDL_MapRGBA(mSDLSurface->format, r, g, b, a);
+ }
+ }
+ }
+
+ if (SDL_MUSTLOCK(mSDLSurface))
+ SDL_UnlockSurface(mSDLSurface);
+ }
+ }
+ else
+ {
+ mAlpha = alpha;
+ }
+}
+
+Image* Image::SDLmerge(Image *image, int x, int y)
+{
+ if (!mSDLSurface || !image || !image->mSDLSurface)
+ return NULL;
+
+ SDL_Surface* surface = new SDL_Surface(*(image->mSDLSurface));
+
+ Uint32 surface_pix, cur_pix;
+ Uint8 r, g, b, a, p_r, p_g, p_b, p_a;
+ double f_a, f_ca, f_pa;
+ SDL_PixelFormat *current_fmt = mSDLSurface->format;
+ SDL_PixelFormat *surface_fmt = surface->format;
+ int current_offset, surface_offset;
+ int offset_x, offset_y;
+
+ SDL_LockSurface(surface);
+ SDL_LockSurface(mSDLSurface);
+ // for each pixel lines of a source image
+ for (offset_x = (x > 0 ? 0 : -x); offset_x < image->getWidth() &&
+ x + offset_x < getWidth(); offset_x++)
+ {
+ for (offset_y = (y > 0 ? 0 : -y); offset_y < image->getHeight()
+ && y + offset_y < getHeight(); offset_y++)
+ {
+ // Computing offset on both images
+ current_offset = (y + offset_y) * getWidth() + x + offset_x;
+ surface_offset = offset_y * surface->w + offset_x;
+
+ // Retrieving a pixel to merge
+ surface_pix = ((Uint32*) surface->pixels)[surface_offset];
+ cur_pix = ((Uint32*) mSDLSurface->pixels)[current_offset];
+
+ // Retreiving each channel of the pixel using pixel format
+ r = (Uint8)(((surface_pix & surface_fmt->Rmask) >>
+ surface_fmt->Rshift) << surface_fmt->Rloss);
+ g = (Uint8)(((surface_pix & surface_fmt->Gmask) >>
+ surface_fmt->Gshift) << surface_fmt->Gloss);
+ b = (Uint8)(((surface_pix & surface_fmt->Bmask) >>
+ surface_fmt->Bshift) << surface_fmt->Bloss);
+ a = (Uint8)(((surface_pix & surface_fmt->Amask) >>
+ surface_fmt->Ashift) << surface_fmt->Aloss);
+
+ // Retreiving previous alpha value
+ p_a = (Uint8)(((cur_pix & current_fmt->Amask) >>
+ current_fmt->Ashift) << current_fmt->Aloss);
+
+ // new pixel with no alpha or nothing on previous pixel
+ if (a == SDL_ALPHA_OPAQUE || (p_a == 0 && a > 0))
+ ((Uint32 *)(surface->pixels))[current_offset] =
+ SDL_MapRGBA(current_fmt, r, g, b, a);
+ else if (a > 0)
+ { // alpha is lower => merge color with previous value
+ f_a = static_cast<double>(a) / 255.0;
+ f_ca = 1.0 - f_a;
+ f_pa = static_cast<double>(p_a) / 255.0;
+ p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >>
+ current_fmt->Rshift) << current_fmt->Rloss);
+ p_g = (Uint8)(((cur_pix & current_fmt->Gmask) >>
+ current_fmt->Gshift) << current_fmt->Gloss);
+ p_b = (Uint8)(((cur_pix & current_fmt->Bmask) >>
+ current_fmt->Bshift) << current_fmt->Bloss);
+ r = (Uint8)((double) p_r * f_ca * f_pa + (double)r * f_a);
+ g = (Uint8)((double) p_g * f_ca * f_pa + (double)g * f_a);
+ b = (Uint8)((double) p_b * f_ca * f_pa + (double)b * f_a);
+ a = (a > p_a ? a : p_a);
+ ((Uint32 *)(surface->pixels))[current_offset] =
+ SDL_MapRGBA(current_fmt, r, g, b, a);
+ }
+ }
+ }
+ SDL_UnlockSurface(surface);
+ SDL_UnlockSurface(mSDLSurface);
+
+ Image *newImage = new Image(surface);
+
+ return newImage;
+}
+
+Image* Image::SDLgetScaledImage(int width, int height)
+{
+ // No scaling on incorrect new values.
+ if (width == 0 || height == 0)
+ return NULL;
+
+ // No scaling when there is ... no different given size ...
+ if (width == getWidth() && height == getHeight())
+ return NULL;
+
+ Image* scaledImage = NULL;
+ SDL_Surface* scaledSurface = NULL;
+
+ if (mSDLSurface)
+ {
+ scaledSurface = zoomSurface(mSDLSurface,
+ (double) width / getWidth(),
+ (double) height / getHeight(),
+ 1);
+
+ // The load function takes care of the SDL<->OpenGL implementation
+ // and about freeing the given SDL_surface*.
+ if (scaledSurface)
+ scaledImage = load(scaledSurface);
+ }
+ return scaledImage;
+}
+
+SDL_Surface* Image::convertTo32Bit(SDL_Surface* tmpImage)
+{
+ if (!tmpImage)
+ return NULL;
+ SDL_PixelFormat RGBAFormat;
+ RGBAFormat.palette = 0;
+ RGBAFormat.colorkey = 0;
+ RGBAFormat.alpha = 0;
+ RGBAFormat.BitsPerPixel = 32;
+ RGBAFormat.BytesPerPixel = 4;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ RGBAFormat.Rmask = 0xFF000000;
+ RGBAFormat.Rshift = 0;
+ RGBAFormat.Rloss = 0;
+ RGBAFormat.Gmask = 0x00FF0000;
+ RGBAFormat.Gshift = 8;
+ RGBAFormat.Gloss = 0;
+ RGBAFormat.Bmask = 0x0000FF00;
+ RGBAFormat.Bshift = 16;
+ RGBAFormat.Bloss = 0;
+ RGBAFormat.Amask = 0x000000FF;
+ RGBAFormat.Ashift = 24;
+ RGBAFormat.Aloss = 0;
+#else
+ RGBAFormat.Rmask = 0x000000FF;
+ RGBAFormat.Rshift = 24;
+ RGBAFormat.Rloss = 0;
+ RGBAFormat.Gmask = 0x0000FF00;
+ RGBAFormat.Gshift = 16;
+ RGBAFormat.Gloss = 0;
+ RGBAFormat.Bmask = 0x00FF0000;
+ RGBAFormat.Bshift = 8;
+ RGBAFormat.Bloss = 0;
+ RGBAFormat.Amask = 0xFF000000;
+ RGBAFormat.Ashift = 0;
+ RGBAFormat.Aloss = 0;
+#endif
+ return SDL_ConvertSurface(tmpImage, &RGBAFormat, SDL_SWSURFACE);
+}
+
+SDL_Surface* Image::SDLDuplicateSurface(SDL_Surface* tmpImage)
+{
+ if (!tmpImage || !tmpImage->format)
+ return NULL;
+
+ return SDL_ConvertSurface(tmpImage, tmpImage->format, SDL_SWSURFACE);
+}
+
+Image *Image::_SDLload(SDL_Surface *tmpImage)
+{
+ if (!tmpImage)
+ return NULL;
+
+ bool hasAlpha = false;
+ bool converted = false;
+
+ // The alpha channel to be filled with alpha values
+ Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h];
+
+ if (tmpImage->format->BitsPerPixel != 32)
+ {
+ tmpImage = convertTo32Bit(tmpImage);
+
+ if (!tmpImage)
+ {
+ delete[] alphaChannel;
+ return NULL;
+ }
+ converted = true;
+ }
+
+ // Figure out whether the image uses its alpha layer
+ for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
+ {
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(((Uint32*) tmpImage->pixels)[i],
+ tmpImage->format, &r, &g, &b, &a);
+
+ if (a != 255)
+ hasAlpha = true;
+
+ alphaChannel[i] = a;
+ }
+
+ SDL_Surface *image;
+
+ // Convert the surface to the current display format
+ if (hasAlpha)
+ {
+ image = SDL_DisplayFormatAlpha(tmpImage);
+ }
+ else
+ {
+ image = SDL_DisplayFormat(tmpImage);
+
+ // We also delete the alpha channel since
+ // it's not used.
+ delete[] alphaChannel;
+ alphaChannel = 0;
+ }
+
+ if (!image)
+ {
+ logger->log1("Error: Image convert failed.");
+ delete[] alphaChannel;
+ return 0;
+ }
+
+ if (converted)
+ SDL_FreeSurface(tmpImage);
+
+ return new Image(image, hasAlpha, alphaChannel);
+}
+
+#ifdef USE_OPENGL
+Image *Image::_GLload(SDL_Surface *tmpImage)
+{
+ if (!tmpImage)
+ return NULL;
+
+ // Flush current error flag.
+ glGetError();
+
+ int width = tmpImage->w;
+ int height = tmpImage->h;
+ int realWidth = powerOfTwo(width);
+ int realHeight = powerOfTwo(height);
+
+ if (realWidth < width || realHeight < height)
+ {
+ logger->log("Warning: image too large, cropping to %dx%d texture!",
+ tmpImage->w, tmpImage->h);
+ }
+
+ // Make sure the alpha channel is not used, but copied to destination
+ SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE);
+
+ // Determine 32-bit masks based on byte order
+ Uint32 rmask, gmask, bmask, amask;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0xff000000;
+ gmask = 0x00ff0000;
+ bmask = 0x0000ff00;
+ amask = 0x000000ff;
+#else
+ rmask = 0x000000ff;
+ gmask = 0x0000ff00;
+ bmask = 0x00ff0000;
+ amask = 0xff000000;
+#endif
+
+ SDL_Surface *oldImage = tmpImage;
+ tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
+ 32, rmask, gmask, bmask, amask);
+
+ if (!tmpImage)
+ {
+ logger->log("Error, image convert failed: out of memory");
+ return NULL;
+ }
+
+ SDL_BlitSurface(oldImage, NULL, tmpImage, NULL);
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+ if (mUseOpenGL == 1)
+ OpenGLGraphics::bindTexture(mTextureType, texture);
+ else if (mUseOpenGL == 2)
+// glBindTexture(mTextureType, texture);
+ OpenGL1Graphics::bindTexture(mTextureType, texture);
+
+ if (SDL_MUSTLOCK(tmpImage))
+ SDL_LockSurface(tmpImage);
+
+ glTexImage2D(mTextureType, 0, 4, tmpImage->w, tmpImage->h,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ if (SDL_MUSTLOCK(tmpImage))
+ SDL_UnlockSurface(tmpImage);
+
+ SDL_FreeSurface(tmpImage);
+
+ GLenum error = glGetError();
+ if (error)
+ {
+ std::string errmsg = "Unknown error";
+ switch (error)
+ {
+ case GL_INVALID_ENUM:
+ errmsg = "GL_INVALID_ENUM";
+ break;
+ case GL_INVALID_VALUE:
+ errmsg = "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_OPERATION:
+ errmsg = "GL_INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ errmsg = "GL_STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ errmsg = "GL_STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ errmsg = "GL_OUT_OF_MEMORY";
+ break;
+ default:
+ break;
+ }
+ logger->log("Error: Image GL import failed: %s", errmsg.c_str());
+ return NULL;
+ }
+
+ return new Image(texture, width, height, realWidth, realHeight);
+}
+
+void Image::setLoadAsOpenGL(int useOpenGL)
+{
+ Image::mUseOpenGL = useOpenGL;
+}
+
+int Image::powerOfTwo(int input)
+{
+ int value;
+ if (mTextureType == GL_TEXTURE_2D)
+ {
+ value = 1;
+ while (value < input && value < mTextureSize)
+ value <<= 1;
+ }
+ else
+ {
+ value = input;
+ }
+ return value >= mTextureSize ? mTextureSize : value;
+}
+#endif
+
+Image *Image::getSubImage(int x, int y, int width, int height)
+{
+ // Create a new clipped sub-image
+#ifdef USE_OPENGL
+ if (mUseOpenGL)
+ {
+ return new SubImage(this, mGLImage, x, y, width, height,
+ mTexWidth, mTexHeight);
+ }
+#endif
+
+ return new SubImage(this, mSDLSurface, x, y, width, height);
+}
+
+void Image::SDLTerminateAlphaCache()
+{
+ SDLCleanCache();
+ mUseAlphaCache = false;
+}
+
+//============================================================================
+// SubImage Class
+//============================================================================
+
+SubImage::SubImage(Image *parent, SDL_Surface *image,
+ int x, int y, int width, int height):
+ Image(image),
+ mParent(parent)
+{
+ if (mParent)
+ {
+ mParent->incRef();
+ mParent->SDLTerminateAlphaCache();
+ mHasAlphaChannel = mParent->hasAlphaChannel();
+ mAlphaChannel = mParent->SDLgetAlphaChannel();
+ }
+ else
+ {
+ mHasAlphaChannel = false;
+ mAlphaChannel = 0;
+ }
+
+ // Set up the rectangle.
+ mBounds.x = static_cast<short>(x);
+ mBounds.y = static_cast<short>(y);
+ mBounds.w = static_cast<Uint16>(width);
+ mBounds.h = static_cast<Uint16>(height);
+ mUseAlphaCache = false;
+}
+
+#ifdef USE_OPENGL
+SubImage::SubImage(Image *parent, GLuint image,
+ int x, int y, int width, int height,
+ int texWidth, int texHeight):
+ Image(image, width, height, texWidth, texHeight),
+ mParent(parent)
+{
+ if (mParent)
+ mParent->incRef();
+
+ // Set up the rectangle.
+ mBounds.x = static_cast<short>(x);
+ mBounds.y = static_cast<short>(y);
+ mBounds.w = static_cast<Uint16>(width);
+ mBounds.h = static_cast<Uint16>(height);
+}
+#endif
+
+SubImage::~SubImage()
+{
+ // Avoid destruction of the image
+ mSDLSurface = 0;
+ // Avoid possible destruction of its alpha channel
+ mAlphaChannel = 0;
+#ifdef USE_OPENGL
+ mGLImage = 0;
+#endif
+ if (mParent)
+ mParent->decRef();
+}
+
+Image *SubImage::getSubImage(int x, int y, int w, int h)
+{
+ if (mParent)
+ return mParent->getSubImage(mBounds.x + x, mBounds.y + y, w, h);
+ else
+ return NULL;
+}
diff --git a/src/resources/image.h b/src/resources/image.h
new file mode 100644
index 000000000..7145b9d48
--- /dev/null
+++ b/src/resources/image.h
@@ -0,0 +1,308 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include "main.h"
+
+#include "resources/resource.h"
+
+#include <SDL.h>
+
+#ifdef USE_OPENGL
+
+/* The definition of OpenGL extensions by SDL is giving problems with recent
+ * gl.h headers, since they also include these definitions. As we're not using
+ * extensions anyway it's safe to just disable the SDL version.
+ */
+#define NO_SDL_GLEXT
+
+#include <SDL_opengl.h>
+#endif
+
+#include <map>
+
+class Dye;
+class Position;
+
+/**
+ * Defines a class for loading and storing images.
+ */
+class Image : public Resource
+{
+ friend class CompoundSprite;
+ friend class Graphics;
+#ifdef USE_OPENGL
+ friend class OpenGLGraphics;
+ friend class OpenGL1Graphics;
+#endif
+
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~Image();
+
+ /**
+ * Loads an image from a buffer in memory.
+ *
+ * @param buffer The memory buffer containing the image data.
+ * @param bufferSize The size of the memory buffer in bytes.
+ *
+ * @return <code>NULL</code> if an error occurred, a valid pointer
+ * otherwise.
+ */
+ static Resource *load(void *buffer, unsigned bufferSize);
+
+ /**
+ * Loads an image from a buffer in memory and recolors it.
+ *
+ * @param buffer The memory buffer containing the image data.
+ * @param bufferSize The size of the memory buffer in bytes.
+ * @param dye The dye used to recolor the image.
+ *
+ * @return <code>NULL</code> if an error occurred, a valid pointer
+ * otherwise.
+ */
+ static Resource *load(void *buffer, unsigned bufferSize,
+ Dye const &dye);
+
+ /**
+ * Loads an image from an SDL surface.
+ */
+ static Image *load(SDL_Surface *);
+
+ static SDL_Surface* convertTo32Bit(SDL_Surface* tmpImage);
+
+ /**
+ * Frees the resources created by SDL.
+ */
+ virtual void unload();
+
+ /**
+ * Tells is the image is loaded
+ */
+ bool isLoaded()
+ { return mLoaded; }
+
+ /**
+ * Returns the width of the image.
+ */
+ inline int getWidth() const // was virtual
+ { return mBounds.w; }
+
+ /**
+ * Returns the height of the image.
+ */
+ inline int getHeight() const // was virtual
+ { return mBounds.h; }
+
+ /**
+ * Tells if the image was loaded using OpenGL or SDL
+ * @return true if OpenGL, false if SDL.
+ */
+ int useOpenGL() const;
+
+ /**
+ * Tells if the image has got an alpha channel
+ * @return true if it's true, false otherwise.
+ */
+ bool hasAlphaChannel();
+
+ /**
+ * Sets the alpha value of this image.
+ */
+ virtual void setAlpha(float alpha);
+
+ /**
+ * Returns the alpha value of this image.
+ */
+ float getAlpha() const
+ { return mAlpha; }
+
+ /**
+ * Creates a new image with the desired clipping rectangle.
+ *
+ * @return <code>NULL</code> if creation failed and a valid
+ * object otherwise.
+ */
+ virtual Image *getSubImage(int x, int y, int width, int height);
+
+
+ // SDL only public functions
+
+ /**
+ * Gets an scaled instance of an image.
+ *
+ * @param width The desired width of the scaled image.
+ * @param height The desired height of the scaled image.
+ *
+ * @return A new Image* object.
+ */
+ Image* SDLgetScaledImage(int width, int height);
+
+ /**
+ * Merges two image SDL_Surfaces together. This is for SDL use only, as
+ * reducing the number of surfaces that SDL has to render can cut down
+ * on the number of blit operations necessary, which in turn can help
+ * improve overall framerates. Don't use unless you are using it to
+ * reduce the number of overall layers that need to be drawn through SDL.
+ */
+ Image *SDLmerge(Image *image, int x, int y);
+
+ /**
+ * Get the alpha Channel of a SDL surface.
+ */
+ Uint8 *SDLgetAlphaChannel() const
+ { return mAlphaChannel; }
+
+ SDL_Surface* SDLDuplicateSurface(SDL_Surface* tmpImage);
+
+ void SDLCleanCache();
+
+ void SDLTerminateAlphaCache();
+
+ static void SDLSetEnableAlphaCache(bool n)
+ { mEnableAlphaCache = n; }
+
+ static void setEnableAlpha(bool n)
+ { mEnableAlpha = n; }
+
+#ifdef USE_OPENGL
+
+ // OpenGL only public functions
+
+ /**
+ * Sets the target image format. Use <code>false</code> for SDL and
+ * <code>true</code> for OpenGL.
+ */
+ static void setLoadAsOpenGL(int useOpenGL);
+
+ static int getLoadAsOpenGL()
+ { return mUseOpenGL; }
+
+ int getTextureWidth() const
+ { return mTexWidth; }
+
+ int getTextureHeight() const
+ { return mTexHeight; }
+
+ static int getTextureType()
+ { return mTextureType; }
+#endif
+
+ protected:
+
+ // -----------------------
+ // Generic protected members
+ // -----------------------
+
+ SDL_Rect mBounds;
+ bool mLoaded;
+ float mAlpha;
+ bool mHasAlphaChannel;
+
+ // -----------------------
+ // SDL protected members
+ // -----------------------
+
+ /** SDL Constructor */
+ Image(SDL_Surface *image, bool hasAlphaChannel = false,
+ Uint8 *alphaChannel = NULL);
+
+ /** SDL_Surface to SDL_Surface Image loader */
+ static Image *_SDLload(SDL_Surface *tmpImage);
+
+ SDL_Surface *getByAlpha(float alpha);
+
+ SDL_Surface *mSDLSurface;
+
+ /** Alpha Channel pointer used for 32bit based SDL surfaces */
+ Uint8 *mAlphaChannel;
+
+ std::map<float, SDL_Surface*> mAlphaCache;
+
+ bool mUseAlphaCache;
+
+ static bool mEnableAlphaCache;
+ static bool mEnableAlpha;
+
+ // -----------------------
+ // OpenGL protected members
+ // -----------------------
+#ifdef USE_OPENGL
+ /**
+ * OpenGL Constructor.
+ */
+ Image(GLuint glimage, int width, int height,
+ int texWidth, int texHeight);
+
+ /**
+ * Returns the first power of two equal or bigger than the input.
+ */
+ static int powerOfTwo(int input);
+
+ static Image *_GLload(SDL_Surface *tmpImage);
+
+ GLuint mGLImage;
+ int mTexWidth, mTexHeight;
+
+ static int mUseOpenGL;
+ static int mTextureType;
+ static int mTextureSize;
+#endif
+};
+
+/**
+ * A clipped version of a larger image.
+ */
+class SubImage : public Image
+{
+ public:
+ /**
+ * Constructor.
+ */
+ SubImage(Image *parent, SDL_Surface *image,
+ int x, int y, int width, int height);
+#ifdef USE_OPENGL
+ SubImage(Image *parent, GLuint image, int x, int y,
+ int width, int height, int texWidth, int textHeight);
+#endif
+
+ /**
+ * Destructor.
+ */
+ ~SubImage();
+
+ /**
+ * Creates a new image with the desired clipping rectangle.
+ *
+ * @return <code>NULL</code> if creation failed and a valid
+ * image otherwise.
+ */
+ Image *getSubImage(int x, int y, int width, int height);
+
+ private:
+ Image *mParent;
+};
+
+#endif
diff --git a/src/resources/imageloader.cpp b/src/resources/imageloader.cpp
new file mode 100644
index 000000000..97c7a0146
--- /dev/null
+++ b/src/resources/imageloader.cpp
@@ -0,0 +1,114 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/imageloader.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include <guichan/color.hpp>
+
+#include <guichan/sdl/sdlpixel.hpp>
+
+#include <cassert>
+
+ProxyImage::ProxyImage(SDL_Surface *s):
+ mImage(NULL), mSDLImage(s)
+{
+}
+
+ProxyImage::~ProxyImage()
+{
+ free();
+}
+
+void ProxyImage::free()
+{
+ if (mSDLImage)
+ {
+ SDL_FreeSurface(mSDLImage);
+ mSDLImage = 0;
+ }
+ else
+ {
+ delete mImage;
+ mImage = 0;
+ }
+}
+
+int ProxyImage::getWidth() const
+{
+ if (mSDLImage)
+ return mSDLImage->w;
+ else if (mImage)
+ return mImage->getWidth();
+ else
+ return 0;
+// return mSDLImage ? mSDLImage->w : mImage->getWidth();
+}
+
+int ProxyImage::getHeight() const
+{
+ if (mSDLImage)
+ return mSDLImage->h;
+ else if (mImage)
+ return mImage->getHeight();
+ else
+ return 0;
+// return mSDLImage ? mSDLImage->h : mImage->getHeight();
+}
+
+gcn::Color ProxyImage::getPixel(int x, int y)
+{
+ assert(mSDLImage);
+ return gcn::SDLgetPixel(mSDLImage, x, y);
+}
+
+void ProxyImage::putPixel(int x, int y, gcn::Color const &color)
+{
+ if (!mSDLImage)
+ return;
+ gcn::SDLputPixel(mSDLImage, x, y, color);
+}
+
+void ProxyImage::convertToDisplayFormat()
+{
+ if (!mSDLImage)
+ return;
+
+ /* The picture is most probably full of the pink pixels Guichan uses for
+ transparency, as this function will only be called when setting an image
+ font. Get rid of them. */
+ SDL_SetColorKey(mSDLImage, SDL_SRCCOLORKEY,
+ SDL_MapRGB(mSDLImage->format, 255, 0, 255));
+ mImage = ::Image::load(mSDLImage);
+ SDL_FreeSurface(mSDLImage);
+ mSDLImage = NULL;
+}
+
+gcn::Image *ImageLoader::load(const std::string &filename, bool convert)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ ProxyImage *i = new ProxyImage(resman->loadSDLSurface(filename));
+ if (convert)
+ i->convertToDisplayFormat();
+ return i;
+}
diff --git a/src/resources/imageloader.h b/src/resources/imageloader.h
new file mode 100644
index 000000000..7f53ff240
--- /dev/null
+++ b/src/resources/imageloader.h
@@ -0,0 +1,69 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef IMAGELOADER_H
+#define IMAGELOADER_H
+
+#include <guichan/image.hpp>
+#include <guichan/imageloader.hpp>
+
+#include <string>
+
+class Image;
+struct SDL_Surface;
+
+class ProxyImage : public gcn::Image
+{
+ public:
+ ProxyImage(SDL_Surface *);
+ ~ProxyImage();
+
+ void free();
+ int getWidth() const;
+ int getHeight() const;
+ gcn::Color getPixel(int x, int y);
+ void putPixel(int x, int y, gcn::Color const &color);
+ void convertToDisplayFormat();
+
+ /**
+ * Gets the image handled by this proxy.
+ */
+ ::Image *getImage() const
+ { return mImage; }
+
+ private:
+ ::Image *mImage; /**< The real image. */
+
+ /**
+ * An SDL surface kept around until Guichan is done reading pixels from
+ * an OpenGL texture.
+ */
+ SDL_Surface *mSDLImage;
+};
+
+class ImageLoader : public gcn::ImageLoader
+{
+ public:
+ gcn::Image *load(const std::string &filename,
+ bool convertToDisplayFormat);
+};
+
+#endif
diff --git a/src/resources/imageset.cpp b/src/resources/imageset.cpp
new file mode 100644
index 000000000..93d3138aa
--- /dev/null
+++ b/src/resources/imageset.cpp
@@ -0,0 +1,64 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/imageset.h"
+
+#include "log.h"
+
+#include "resources/image.h"
+
+#include "utils/dtor.h"
+
+ImageSet::ImageSet(Image *img, int width, int height, int margin, int spacing)
+{
+ if (img)
+ {
+ for (int y = margin; y + height <= img->getHeight() - margin;
+ y += height + spacing)
+ {
+ for (int x = margin; x + width <= img->getWidth() - margin;
+ x += width + spacing)
+ {
+ mImages.push_back(img->getSubImage(x, y, width, height));
+ }
+ }
+ }
+ mWidth = width;
+ mHeight = height;
+}
+
+ImageSet::~ImageSet()
+{
+ delete_all(mImages);
+}
+
+Image* ImageSet::get(size_type i) const
+{
+ if (i >= mImages.size())
+ {
+ logger->log("Warning: No sprite %d in this image set", (int) i);
+ return NULL;
+ }
+ else
+ {
+ return mImages[i];
+ }
+}
diff --git a/src/resources/imageset.h b/src/resources/imageset.h
new file mode 100644
index 000000000..bfb834128
--- /dev/null
+++ b/src/resources/imageset.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef IMAGESET_H
+#define IMAGESET_H
+
+#include "resources/resource.h"
+
+#include <vector>
+
+class Image;
+
+/**
+ * Stores a set of subimages originating from a single image.
+ */
+class ImageSet : public Resource
+{
+ public:
+ /**
+ * Cuts the passed image in a grid of sub images.
+ */
+ ImageSet(Image *img, int w, int h, int margin = 0, int spacing = 0);
+
+ /**
+ * Destructor.
+ */
+ ~ImageSet();
+
+ /**
+ * Returns the width of the images in the image set.
+ */
+ int getWidth() const
+ { return mWidth; }
+
+ /**
+ * Returns the height of the images in the image set.
+ */
+ int getHeight() const
+ { return mHeight; }
+
+ typedef std::vector<Image*>::size_type size_type;
+ Image* get(size_type i) const;
+
+ size_type size() const
+ { return mImages.size(); }
+
+ private:
+ std::vector<Image*> mImages;
+
+ int mHeight; /**< Height of the images in the image set. */
+ int mWidth; /**< Width of the images in the image set. */
+};
+
+#endif
diff --git a/src/resources/imagewriter.cpp b/src/resources/imagewriter.cpp
new file mode 100644
index 000000000..f3f4be2b4
--- /dev/null
+++ b/src/resources/imagewriter.cpp
@@ -0,0 +1,111 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/imagewriter.h"
+
+#include "log.h"
+
+#include <png.h>
+#include <SDL.h>
+#include <string>
+
+bool ImageWriter::writePNG(SDL_Surface *surface, const std::string &filename)
+{
+ // TODO Maybe someone can make this look nice?
+
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_bytep *row_pointers;
+ int colortype;
+
+ if (SDL_MUSTLOCK(surface))
+ SDL_LockSurface(surface);
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!png_ptr)
+ {
+ logger->log1("Had trouble creating png_structp");
+ return false;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ logger->log1("Could not create png_info");
+ return false;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ logger->log("problem writing to %s", filename.c_str());
+ return false;
+ }
+
+ FILE *fp = fopen(filename.c_str(), "wb");
+ if (!fp)
+ {
+ logger->log("could not open file %s for writing", filename.c_str());
+ return false;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ colortype = (surface->format->BitsPerPixel == 24) ?
+ PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
+
+ png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8, colortype,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ png_write_info(png_ptr, info_ptr);
+
+ png_set_packing(png_ptr);
+
+ row_pointers = new png_bytep[surface->h];
+ if (!row_pointers)
+ {
+ logger->log1("Had trouble converting surface to row pointers");
+ fclose(fp);
+ return false;
+ }
+
+ for (int i = 0; i < surface->h; i++)
+ {
+ row_pointers[i] = (png_bytep)(Uint8 *)surface->pixels
+ + i * surface->pitch;
+ }
+
+ png_write_image(png_ptr, row_pointers);
+ png_write_end(png_ptr, info_ptr);
+
+ fclose(fp);
+
+ delete [] row_pointers;
+
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+
+ if (SDL_MUSTLOCK(surface))
+ SDL_UnlockSurface(surface);
+
+ return true;
+}
diff --git a/src/resources/imagewriter.h b/src/resources/imagewriter.h
new file mode 100644
index 000000000..ac07320a6
--- /dev/null
+++ b/src/resources/imagewriter.h
@@ -0,0 +1,31 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <iosfwd>
+
+struct SDL_Surface;
+
+class ImageWriter
+{
+ public:
+ static bool writePNG(SDL_Surface *surface,
+ const std::string &filename);
+};
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
new file mode 100644
index 000000000..cc70e33b7
--- /dev/null
+++ b/src/resources/itemdb.cpp
@@ -0,0 +1,463 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/itemdb.h"
+
+#include "log.h"
+
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+#include "configuration.h"
+
+#include <libxml/tree.h>
+
+#include <cassert>
+
+namespace
+{
+ ItemDB::ItemInfos mItemInfos;
+ ItemDB::NamedItemInfos mNamedItemInfos;
+ ItemInfo *mUnknown;
+ bool mLoaded = false;
+}
+
+// Forward declarations
+static void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node);
+static void loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node);
+static void loadFloorSprite(SpriteDisplay *display, xmlNodePtr node);
+static int parseSpriteName(std::string &name);
+
+static char const *const fields[][2] =
+{
+ { "attack", N_("Attack %+d") },
+ { "defense", N_("Defense %+d") },
+ { "hp", N_("HP %+d") },
+ { "mp", N_("MP %+d") }
+};
+
+static std::list<ItemDB::Stat> extraStats;
+
+void ItemDB::setStatsList(const std::list<ItemDB::Stat> &stats)
+{
+ extraStats = stats;
+}
+
+static ItemType itemTypeFromString(const std::string &name)
+{
+ if (name == "generic")
+ {
+ return ITEM_UNUSABLE;
+ }
+ else if (name == "usable")
+ {
+ return ITEM_USABLE;
+ }
+ else if (name == "equip-1hand")
+ {
+ return ITEM_EQUIPMENT_ONE_HAND_WEAPON;
+ }
+ else if (name == "equip-2hand")
+ {
+ return ITEM_EQUIPMENT_TWO_HANDS_WEAPON;
+ }
+ else if (name == "equip-torso")
+ {
+ return ITEM_EQUIPMENT_TORSO;
+ }
+ else if (name == "equip-arms")
+ {
+ return ITEM_EQUIPMENT_ARMS;
+ }
+ else if (name == "equip-head")
+ {
+ return ITEM_EQUIPMENT_HEAD;
+ }
+ else if (name == "equip-legs")
+ {
+ return ITEM_EQUIPMENT_LEGS;
+ }
+ else if (name == "equip-shield")
+ {
+ return ITEM_EQUIPMENT_SHIELD;
+ }
+ else if (name == "equip-ring")
+ {
+ return ITEM_EQUIPMENT_RING;
+ }
+ else if (name == "equip-charm")
+ {
+ return ITEM_EQUIPMENT_CHARM;
+ }
+ else if (name == "equip-necklace" || name == "equip-neck")
+ {
+ return ITEM_EQUIPMENT_NECKLACE;
+ }
+ else if (name == "equip-feet")
+ {
+ return ITEM_EQUIPMENT_FEET;
+ }
+ else if (name == "equip-ammo")
+ {
+ return ITEM_EQUIPMENT_AMMO;
+ }
+ else if (name == "racesprite")
+ {
+ return ITEM_SPRITE_RACE;
+ }
+ else if (name == "hairsprite")
+ {
+ return ITEM_SPRITE_HAIR;
+ }
+ else
+ {
+ logger->log("Unknown item type: " + name);
+ return ITEM_UNUSABLE;
+ }
+}
+
+static std::string normalized(const std::string &name)
+{
+ std::string normalized = name;
+ return toLower(trim(normalized));
+}
+
+void ItemDB::load()
+{
+ if (mLoaded)
+ unload();
+
+ logger->log1("Initializing item database...");
+
+ mUnknown = new ItemInfo;
+ mUnknown->setName(_("Unknown item"));
+ mUnknown->setDisplay(SpriteDisplay());
+ std::string errFile = paths.getStringValue("spriteErrorFile");
+ mUnknown->setSprite(errFile, GENDER_MALE);
+ mUnknown->setSprite(errFile, GENDER_FEMALE);
+
+ XML::Document doc("items.xml");
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items"))
+ {
+ logger->log("ItemDB: Error while loading items.xml!");
+ mLoaded = true;
+ return;
+ }
+
+ for_each_xml_child_node(node, rootNode)
+ {
+ if (!xmlStrEqual(node->name, BAD_CAST "item"))
+ continue;
+
+ int id = XML::getProperty(node, "id", 0);
+
+ if (id == 0)
+ {
+ logger->log1("ItemDB: Invalid or missing item ID in items.xml!");
+ continue;
+ }
+ else if (mItemInfos.find(id) != mItemInfos.end())
+ {
+ logger->log("ItemDB: Redefinition of item ID %d", id);
+ }
+
+ std::string typeStr = XML::getProperty(node, "type", "other");
+ int weight = XML::getProperty(node, "weight", 0);
+ int view = XML::getProperty(node, "view", 0);
+
+ std::string name = XML::getProperty(node, "name", "");
+ std::string image = XML::getProperty(node, "image", "");
+ std::string description = XML::getProperty(node, "description", "");
+ std::string attackAction = XML::getProperty(node, "attack-action", "");
+ std::string drawBefore = XML::getProperty(node, "drawBefore", "");
+ std::string drawAfter = XML::getProperty(node, "drawAfter", "");
+
+ int drawPriority = XML::getProperty(node, "drawPriority", 0);
+
+ int attackRange = XML::getProperty(node, "attack-range", 0);
+ std::string missileParticle = XML::getProperty(
+ node, "missile-particle", "");
+
+ SpriteDisplay display;
+ display.image = image;
+
+ ItemInfo *itemInfo = new ItemInfo;
+ itemInfo->setId(id);
+ itemInfo->setName(name.empty() ? _("unnamed") : name);
+ itemInfo->setDescription(description);
+ itemInfo->setType(itemTypeFromString(typeStr));
+ itemInfo->setView(view);
+ itemInfo->setWeight(weight);
+ itemInfo->setAttackAction(attackAction);
+ itemInfo->setAttackRange(attackRange);
+ itemInfo->setMissileParticle(missileParticle);
+ itemInfo->setDrawBefore(parseSpriteName(drawBefore));
+ itemInfo->setDrawAfter(parseSpriteName(drawAfter));
+ itemInfo->setDrawPriority(drawPriority);
+
+ std::string effect;
+ for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i)
+ {
+ int value = XML::getProperty(node, fields[i][0], 0);
+ if (!value)
+ continue;
+ if (!effect.empty())
+ effect += " / ";
+ effect += strprintf(gettext(fields[i][1]), value);
+ }
+ for (std::list<Stat>::iterator it = extraStats.begin();
+ it != extraStats.end(); it++)
+ {
+ int value = XML::getProperty(node, it->tag.c_str(), 0);
+ if (!value)
+ continue;
+ if (!effect.empty())
+ effect += " / ";
+ effect += strprintf(it->format.c_str(), value);
+ }
+ std::string temp = XML::getProperty(node, "effect", "");
+ if (!effect.empty() && !temp.empty())
+ effect += " / ";
+ effect += temp;
+ itemInfo->setEffect(effect);
+
+ for_each_xml_child_node(itemChild, node)
+ {
+ if (xmlStrEqual(itemChild->name, BAD_CAST "sprite"))
+ {
+ std::string attackParticle = XML::getProperty(
+ itemChild, "particle-effect", "");
+ itemInfo->setParticleEffect(attackParticle);
+
+ loadSpriteRef(itemInfo, itemChild);
+ }
+ else if (xmlStrEqual(itemChild->name, BAD_CAST "sound"))
+ {
+ loadSoundRef(itemInfo, itemChild);
+ }
+ else if (xmlStrEqual(itemChild->name, BAD_CAST "floor"))
+ {
+ loadFloorSprite(&display, itemChild);
+ }
+ }
+
+ itemInfo->setDisplay(display);
+
+ mItemInfos[id] = itemInfo;
+ if (!name.empty())
+ {
+ std::string temp = normalized(name);
+
+ NamedItemInfos::const_iterator itr = mNamedItemInfos.find(temp);
+ if (itr == mNamedItemInfos.end())
+ {
+ mNamedItemInfos[temp] = itemInfo;
+ }
+ else
+ {
+ logger->log("ItemDB: Duplicate name of item found item %d",
+ id);
+ }
+ }
+
+ if (!attackAction.empty())
+ {
+ if (attackRange == 0)
+ {
+ logger->log("ItemDB: Missing attack range from weapon %i!",
+ id);
+ }
+ }
+
+#define CHECK_PARAM(param, error_value) \
+ if (param == error_value) \
+ logger->log("ItemDB: Missing " #param " attribute for item %i!", \
+ id)
+
+ if (id >= 0)
+ {
+ CHECK_PARAM(name, "");
+ CHECK_PARAM(description, "");
+ CHECK_PARAM(image, "");
+ }
+ // CHECK_PARAM(effect, "");
+ // CHECK_PARAM(type, 0);
+ // CHECK_PARAM(weight, 0);
+ // CHECK_PARAM(slot, 0);
+
+#undef CHECK_PARAM
+ }
+
+ mLoaded = true;
+}
+
+void ItemDB::unload()
+{
+ logger->log1("Unloading item database...");
+
+ delete mUnknown;
+ mUnknown = 0;
+
+ delete_all(mItemInfos);
+ mItemInfos.clear();
+ mNamedItemInfos.clear();
+ mLoaded = false;
+}
+
+bool ItemDB::exists(int id)
+{
+ assert(mLoaded);
+
+ ItemInfos::const_iterator i = mItemInfos.find(id);
+
+ return i != mItemInfos.end();
+}
+
+const ItemInfo &ItemDB::get(int id)
+{
+ assert(mLoaded);
+
+ ItemInfos::const_iterator i = mItemInfos.find(id);
+
+ if (i == mItemInfos.end())
+ {
+ logger->log("ItemDB: Warning, unknown item ID# %d", id);
+ return *mUnknown;
+ }
+
+ return *(i->second);
+}
+
+const ItemInfo &ItemDB::get(const std::string &name)
+{
+ assert(mLoaded);
+
+ NamedItemInfos::const_iterator i = mNamedItemInfos.find(normalized(name));
+
+ if (i == mNamedItemInfos.end())
+ {
+ if (!name.empty())
+ {
+ logger->log("ItemDB: Warning, unknown item name \"%s\"",
+ name.c_str());
+ }
+ return *mUnknown;
+ }
+
+ return *(i->second);
+}
+
+const std::map<int, ItemInfo*> &ItemDB::getItemInfos()
+{
+ return mItemInfos;
+}
+
+int parseSpriteName(std::string &name)
+{
+ int id = -1;
+ if (name == "shoes")
+ id = 1;
+ else if (name == "bottomclothes" || name == "bottom" || name == "pants")
+ id = 2;
+ else if (name == "topclothes" || name == "top" || name == "torso")
+ id = 3;
+ else if (name == "misc1")
+ id = 4;
+ else if (name == "misc2")
+ id = 5;
+ else if (name == "hair")
+ id = 6;
+ else if (name == "hat")
+ id = 7;
+ else if (name == "cap")
+ id = 8;
+ else if (name == "gloves")
+ id = 9;
+ else if (name == "weapon")
+ id = 10;
+ else if (name == "shield")
+ id = 11;
+
+ return id;
+}
+
+void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node)
+{
+ std::string gender = XML::getProperty(node, "gender", "unisex");
+ std::string filename = (const char*) node->xmlChildrenNode->content;
+
+ if (gender == "male" || gender == "unisex")
+ {
+ itemInfo->setSprite(filename, GENDER_MALE);
+ }
+ if (gender == "female" || gender == "unisex")
+ {
+ itemInfo->setSprite(filename, GENDER_FEMALE);
+ }
+}
+
+void loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node)
+{
+ std::string event = XML::getProperty(node, "event", "");
+ std::string filename = (const char*) node->xmlChildrenNode->content;
+
+ if (event == "hit")
+ {
+ itemInfo->addSound(EQUIP_EVENT_HIT, filename);
+ }
+ else if (event == "strike")
+ {
+ itemInfo->addSound(EQUIP_EVENT_STRIKE, filename);
+ }
+ else
+ {
+ logger->log("ItemDB: Ignoring unknown sound event '%s'",
+ event.c_str());
+ }
+}
+
+void loadFloorSprite(SpriteDisplay *display, xmlNodePtr floorNode)
+{
+ for_each_xml_child_node(spriteNode, floorNode)
+ {
+ if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
+ {
+ SpriteReference *currentSprite = new SpriteReference;
+ currentSprite->sprite
+ = (const char*)spriteNode->xmlChildrenNode->content;
+ currentSprite->variant
+ = XML::getProperty(spriteNode, "variant", 0);
+ display->sprites.push_back(currentSprite);
+ }
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
+ {
+ std::string particlefx
+ = (const char*)spriteNode->xmlChildrenNode->content;
+ display->particles.push_back(particlefx);
+ }
+ }
+}
diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h
new file mode 100644
index 000000000..76e646c0f
--- /dev/null
+++ b/src/resources/itemdb.h
@@ -0,0 +1,79 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEM_MANAGER_H
+#define ITEM_MANAGER_H
+
+#include <list>
+#include <map>
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class ItemInfo;
+
+/**
+ * Item information database.
+ */
+namespace ItemDB
+{
+ /**
+ * Loads the item data from <code>items.xml</code>.
+ */
+ void load();
+
+ /**
+ * Frees item data.
+ */
+ void unload();
+
+ bool exists(int id);
+
+ const ItemInfo &get(int id);
+ const ItemInfo &get(const std::string &name);
+
+ // Items database
+ typedef std::map<int, ItemInfo*> ItemInfos;
+ typedef std::map<std::string, ItemInfo*> NamedItemInfos;
+
+ const std::map<int, ItemInfo*> &getItemInfos();
+
+ struct Stat
+ {
+ Stat(const std::string &tag,
+ const std::string &format):
+ tag(tag),
+ format(format)
+ {}
+
+ std::string tag;
+ std::string format;
+ };
+
+ void setStatsList(const std::list<Stat> &stats);
+
+}
+
+#endif
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
new file mode 100644
index 000000000..300c6bd26
--- /dev/null
+++ b/src/resources/iteminfo.cpp
@@ -0,0 +1,66 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/iteminfo.h"
+
+#include "resources/itemdb.h"
+#include "configuration.h"
+
+const std::string &ItemInfo::getSprite(Gender gender) const
+{
+ if (mView)
+ {
+ // Forward the request to the item defining how to view this item
+ return ItemDB::get(mView).getSprite(gender);
+ }
+ else
+ {
+ static const std::string empty = "";
+ std::map<int, std::string>::const_iterator i =
+ mAnimationFiles.find(gender);
+
+ return (i != mAnimationFiles.end()) ? i->second : empty;
+ }
+}
+
+void ItemInfo::setAttackAction(std::string attackAction)
+{
+ if (attackAction.empty())
+ mAttackAction = SpriteAction::ATTACK; // (Equal to unarmed animation)
+ else
+ mAttackAction = attackAction;
+}
+
+void ItemInfo::addSound(EquipmentSoundEvent event, const std::string &filename)
+{
+ mSounds[event].push_back(paths.getStringValue("sfx") + filename);
+}
+
+const std::string &ItemInfo::getSound(EquipmentSoundEvent event) const
+{
+ static const std::string empty;
+ std::map< EquipmentSoundEvent,
+ std::vector<std::string> >::const_iterator i;
+
+ i = mSounds.find(event);
+
+ return i == mSounds.end() ? empty : i->second[rand() % i->second.size()];
+}
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
new file mode 100644
index 000000000..bb84193bb
--- /dev/null
+++ b/src/resources/iteminfo.h
@@ -0,0 +1,242 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ITEMINFO_H
+#define ITEMINFO_H
+
+#include "being.h"
+
+#include "resources/spritedef.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+enum EquipmentSoundEvent
+{
+ EQUIP_EVENT_STRIKE = 0,
+ EQUIP_EVENT_HIT
+};
+
+enum EquipmentSlot
+{
+ // Equipment rules:
+ // 1 Brest equipment
+ EQUIP_TORSO_SLOT = 0,
+ // 1 arms equipment
+ EQUIP_ARMS_SLOT = 1,
+ // 1 head equipment
+ EQUIP_HEAD_SLOT = 2,
+ // 1 legs equipment
+ EQUIP_LEGS_SLOT = 3,
+ // 1 feet equipment
+ EQUIP_FEET_SLOT = 4,
+ // 2 rings
+ EQUIP_RING1_SLOT = 5,
+ EQUIP_RING2_SLOT = 6,
+ // 1 necklace
+ EQUIP_NECKLACE_SLOT = 7,
+ // Fight:
+ // 2 one-handed weapons
+ // or 1 two-handed weapon
+ // or 1 one-handed weapon + 1 shield.
+ EQUIP_FIGHT1_SLOT = 8,
+ EQUIP_FIGHT2_SLOT = 9,
+ // Projectile:
+ // this item does not amount to one, it only indicates the chosen projectile.
+ EQUIP_PROJECTILE_SLOT = 10
+};
+
+
+/**
+ * Enumeration of available Item types.
+ */
+enum ItemType
+{
+ ITEM_UNUSABLE = 0,
+ ITEM_USABLE,
+ ITEM_EQUIPMENT_ONE_HAND_WEAPON,
+ ITEM_EQUIPMENT_TWO_HANDS_WEAPON,
+ ITEM_EQUIPMENT_TORSO,
+ ITEM_EQUIPMENT_ARMS, // 5
+ ITEM_EQUIPMENT_HEAD,
+ ITEM_EQUIPMENT_LEGS,
+ ITEM_EQUIPMENT_SHIELD,
+ ITEM_EQUIPMENT_RING,
+ ITEM_EQUIPMENT_NECKLACE, // 10
+ ITEM_EQUIPMENT_FEET,
+ ITEM_EQUIPMENT_AMMO,
+ ITEM_EQUIPMENT_CHARM,
+ ITEM_SPRITE_RACE,
+ ITEM_SPRITE_HAIR // 15
+};
+
+/**
+ * Defines a class for storing item infos. This includes information used when
+ * the item is equipped.
+ */
+class ItemInfo
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ItemInfo():
+ mType(ITEM_UNUSABLE),
+ mWeight(0),
+ mView(0),
+ mId(0),
+ mDrawBefore(-1),
+ mDrawAfter(-1),
+ mDrawPriority(0),
+ mAttackAction(SpriteAction::INVALID),
+ mAttackRange(0)
+ {
+ }
+
+ void setId(int id)
+ { mId = id; }
+
+ int getId() const
+ { return mId; }
+
+ void setName(const std::string &name)
+ { mName = name; }
+
+ const std::string &getName() const
+ { return mName; }
+
+ void setParticleEffect(const std::string &particleEffect)
+ { mParticle = particleEffect; }
+
+ std::string getParticleEffect() const { return mParticle; }
+
+ void setDisplay(SpriteDisplay display)
+ { mDisplay = display; }
+
+ const SpriteDisplay &getDisplay() const
+ { return mDisplay; }
+
+ void setDescription(const std::string &description)
+ { mDescription = description; }
+
+ const std::string &getDescription() const
+ { return mDescription; }
+
+ void setEffect(const std::string &effect)
+ { mEffect = effect; }
+
+ const std::string &getEffect() const { return mEffect; }
+
+ void setType(ItemType type)
+ { mType = type; }
+
+ ItemType getType() const
+ { return mType; }
+
+ void setWeight(int weight)
+ { mWeight = weight; }
+
+ int getWeight() const
+ { return mWeight; }
+
+ int getView() const
+ { return mView; }
+
+ void setView(int view)
+ { mView = view; }
+
+ void setSprite(const std::string &animationFile, Gender gender)
+ { mAnimationFiles[gender] = animationFile; }
+
+ const std::string &getSprite(Gender gender) const;
+
+ void setAttackAction(std::string attackAction);
+
+ // Handlers for seting and getting the string used for particles when attacking
+ void setMissileParticle(std::string s) { mMissileParticle = s; }
+
+ std::string getMissileParticle() const { return mMissileParticle; }
+
+ std::string getAttackAction() const
+ { return mAttackAction; }
+
+ int getAttackRange() const
+ { return mAttackRange; }
+
+ void setAttackRange(int r)
+ { mAttackRange = r; }
+
+ void addSound(EquipmentSoundEvent event, const std::string &filename);
+
+ const std::string &getSound(EquipmentSoundEvent event) const;
+
+ int getDrawBefore() const
+ { return mDrawBefore; }
+
+ void setDrawBefore(int n)
+ { mDrawBefore = n; }
+
+ int getDrawAfter() const
+ { return mDrawAfter; }
+
+ void setDrawAfter(int n)
+ { mDrawAfter = n; }
+
+ int getDrawPriority() const
+ { return mDrawPriority; }
+
+ void setDrawPriority(int n)
+ { mDrawPriority = n; }
+
+ protected:
+ SpriteDisplay mDisplay; /**< Display info (like icon) */
+ std::string mName;
+ std::string mDescription; /**< Short description. */
+ std::string mEffect; /**< Description of effects. */
+ ItemType mType; /**< Item type. */
+ std::string mParticle; /**< Particle effect used with this item */
+ int mWeight; /**< Weight in grams. */
+ int mView; /**< Item ID of how this item looks. */
+ int mId; /**< Item ID */
+ int mDrawBefore;
+ int mDrawAfter;
+ int mDrawPriority;
+
+ // Equipment related members.
+ /** Attack type, in case of weapon.
+ * See SpriteAction in spritedef.h for more info.
+ * Attack action sub-types (bow, sword, ...) are defined in items.xml.
+ */
+ std::string mAttackAction;
+ int mAttackRange; /**< Attack range, will be zero if non weapon. */
+
+ // Particle to be shown when weapon attacks
+ std::string mMissileParticle;
+
+ /** Maps gender to sprite filenames. */
+ std::map<int, std::string> mAnimationFiles;
+
+ /** Stores the names of sounds to be played at certain event. */
+ std::map< EquipmentSoundEvent, std::vector<std::string> > mSounds;
+};
+
+#endif
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
new file mode 100644
index 000000000..cf26830f2
--- /dev/null
+++ b/src/resources/mapreader.cpp
@@ -0,0 +1,723 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/mapreader.h"
+
+#include "configuration.h"
+#include "log.h"
+#include "map.h"
+#include "tileset.h"
+
+#include "resources/animation.h"
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/base64.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <cassert>
+#include <iostream>
+#include <zlib.h>
+
+int inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out, unsigned int &outLength);
+
+int inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out);
+
+static std::string resolveRelativePath(std::string base, std::string relative)
+{
+ // Remove trailing "/", if present
+ size_t i = base.length();
+ if (base.at(i - 1) == '/')
+ base.erase(i - 1, i);
+
+ while (relative.substr(0, 3) == "../")
+ {
+ relative.erase(0, 3); // Remove "../"
+ if (!base.empty()) // If base is already empty, we can't trim anymore
+ {
+ i = base.find_last_of('/');
+ if (i == std::string::npos)
+ i = 0;
+ base.erase(i, base.length()); // Remove deepest folder in base
+ }
+ }
+
+ // Re-add trailing slash, if needed
+ if (!base.empty() && base[base.length() - 1] != '/')
+ base += '/';
+
+ return base + relative;
+}
+
+/**
+ * Inflates either zlib or gzip deflated memory. The inflated memory is
+ * expected to be freed by the caller.
+ */
+int inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out, unsigned int &outLength)
+{
+ int bufferSize = 256 * 1024;
+ int ret;
+ z_stream strm;
+
+ out = (unsigned char*) malloc(bufferSize);
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.next_in = in;
+ strm.avail_in = inLength;
+ strm.next_out = out;
+ strm.avail_out = bufferSize;
+
+ ret = inflateInit2(&strm, 15 + 32);
+
+ if (ret != Z_OK)
+ return ret;
+
+ do
+ {
+ if (strm.next_out == NULL)
+ {
+ inflateEnd(&strm);
+ return Z_MEM_ERROR;
+ }
+
+ ret = inflate(&strm, Z_NO_FLUSH);
+ assert(ret != Z_STREAM_ERROR);
+
+ switch (ret)
+ {
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ (void) inflateEnd(&strm);
+ return ret;
+ default:
+ break;
+ }
+
+ if (ret != Z_STREAM_END)
+ {
+ out = (unsigned char*) realloc(out, bufferSize * 2);
+
+ if (out == NULL)
+ {
+ inflateEnd(&strm);
+ return Z_MEM_ERROR;
+ }
+
+ strm.next_out = out + bufferSize;
+ strm.avail_out = bufferSize;
+ bufferSize *= 2;
+ }
+ }
+ while (ret != Z_STREAM_END);
+ assert(strm.avail_in == 0);
+
+ outLength = bufferSize - strm.avail_out;
+ (void) inflateEnd(&strm);
+ return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+int inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out)
+{
+ unsigned int outLength = 0;
+ int ret = inflateMemory(in, inLength, out, outLength);
+
+ if (ret != Z_OK || out == NULL)
+ {
+ if (ret == Z_MEM_ERROR)
+ {
+ logger->log1("Error: Out of memory while decompressing map data!");
+ }
+ else if (ret == Z_VERSION_ERROR)
+ {
+ logger->log1("Error: Incompatible zlib version!");
+ }
+ else if (ret == Z_DATA_ERROR)
+ {
+ logger->log1("Error: Incorrect zlib compressed data!");
+ }
+ else
+ {
+ logger->log1("Error: Unknown error while decompressing map data!");
+ }
+
+ free(out);
+ out = NULL;
+ outLength = 0;
+ }
+
+ return outLength;
+}
+
+Map *MapReader::readMap(const std::string &filename)
+{
+ logger->log("Attempting to read map %s", filename.c_str());
+ // Load the file through resource manager
+ ResourceManager *resman = ResourceManager::getInstance();
+ int fileSize;
+ void *buffer = resman->loadFile(filename, fileSize);
+ Map *map = NULL;
+
+ if (buffer == NULL)
+ {
+ logger->log("Map file not found (%s)", filename.c_str());
+ return NULL;
+ }
+
+ unsigned char *inflated;
+ unsigned int inflatedSize;
+
+ if (filename.find(".gz", filename.length() - 3) != std::string::npos)
+ {
+ // Inflate the gzipped map data
+ inflatedSize =
+ inflateMemory((unsigned char*) buffer, fileSize, inflated);
+ free(buffer);
+
+ if (inflated == NULL)
+ {
+ logger->log("Could not decompress map file (%s)",
+ filename.c_str());
+ return NULL;
+ }
+ }
+ else
+ {
+ inflated = (unsigned char*) buffer;
+ inflatedSize = fileSize;
+ }
+
+ XML::Document doc((char*) inflated, inflatedSize);
+ free(inflated);
+
+ xmlNodePtr node = doc.rootNode();
+
+ // Parse the inflated map data
+ if (node)
+ {
+ if (!xmlStrEqual(node->name, BAD_CAST "map"))
+ {
+ logger->log("Error: Not a map file (%s)!", filename.c_str());
+ }
+ else
+ {
+ map = readMap(node, filename);
+ }
+ }
+ else
+ {
+ logger->log("Error while parsing map file (%s)!", filename.c_str());
+ }
+
+ if (map) map->setProperty("_filename", filename);
+
+ return map;
+}
+
+Map *MapReader::readMap(xmlNodePtr node, const std::string &path)
+{
+ // Take the filename off the path
+ const std::string pathDir = path.substr(0, path.rfind("/") + 1);
+
+ const int w = XML::getProperty(node, "width", 0);
+ const int h = XML::getProperty(node, "height", 0);
+ const int tilew = XML::getProperty(node, "tilewidth", -1);
+ const int tileh = XML::getProperty(node, "tileheight", -1);
+
+ bool showWarps = config.getBoolValue("warpParticle");
+ const std::string warpPath = paths.getStringValue("particles")
+ + paths.getStringValue("portalEffectFile");
+
+ if (tilew < 0 || tileh < 0)
+ {
+ logger->log("MapReader: Warning: "
+ "Unitialized tile width or height value for map: %s",
+ path.c_str());
+ return 0;
+ }
+
+ Map *map = new Map(w, h, tilew, tileh);
+
+ for_each_xml_child_node(childNode, node)
+ {
+ if (xmlStrEqual(childNode->name, BAD_CAST "tileset"))
+ {
+ Tileset *tileset = readTileset(childNode, pathDir, map);
+ if (tileset)
+ {
+ map->addTileset(tileset);
+ }
+ }
+ else if (xmlStrEqual(childNode->name, BAD_CAST "layer"))
+ {
+ readLayer(childNode, map);
+ }
+ else if (xmlStrEqual(childNode->name, BAD_CAST "properties"))
+ {
+ readProperties(childNode, map);
+ }
+ else if (xmlStrEqual(childNode->name, BAD_CAST "objectgroup"))
+ {
+ // The object group offset is applied to each object individually
+ const int tileOffsetX = XML::getProperty(childNode, "x", 0);
+ const int tileOffsetY = XML::getProperty(childNode, "y", 0);
+ const int offsetX = tileOffsetX * tilew;
+ const int offsetY = tileOffsetY * tileh;
+
+ for_each_xml_child_node(objectNode, childNode)
+ {
+ if (xmlStrEqual(objectNode->name, BAD_CAST "object"))
+ {
+ std::string objType = XML::getProperty(
+ objectNode, "type", "");
+
+ objType = toUpper(objType);
+
+/*
+ if (objType == "NPC" ||
+ objType == "SCRIPT")
+ {
+ logger->log("hidden obj: " + objType);
+ // Silently skip server-side objects.
+ continue;
+ }
+*/
+
+ const std::string objName = XML::getProperty(
+ objectNode, "name", "");
+ const int objX = XML::getProperty(objectNode, "x", 0);
+ const int objY = XML::getProperty(objectNode, "y", 0);
+ const int objW = XML::getProperty(objectNode, "width", 0);
+ const int objH = XML::getProperty(objectNode, "height", 0);
+
+ logger->log("- Loading object name: %s type: %s at %d:%d"
+ " (%dx%d)", objName.c_str(), objType.c_str(),
+ objX, objY, objW, objH);
+
+ if (objType == "PARTICLE_EFFECT")
+ {
+ if (objName.empty())
+ {
+ logger->log1(" Warning: No particle file given");
+ continue;
+ }
+
+ map->addParticleEffect(objName,
+ objX + offsetX,
+ objY + offsetY,
+ objW, objH);
+ }
+ else if (objType == "WARP")
+ {
+ if (showWarps)
+ {
+ map->addParticleEffect(warpPath,
+ objX, objY, objW, objH);
+ }
+ map->addPortal(objName, MapItem::PORTAL,
+ objX, objY, objW, objH);
+ }
+ else if (objType == "SPAWN")
+ {
+// map->addPortal(_("Spawn: ") + objName, MapItem::PORTAL,
+// objX, objY, objW, objH);
+ }
+ else
+ {
+ logger->log1(" Warning: Unknown object type");
+ }
+ }
+ }
+ }
+ }
+
+ map->initializeAmbientLayers();
+
+ return map;
+}
+
+void MapReader::readProperties(xmlNodePtr node, Properties *props)
+{
+ if (!props)
+ return;
+
+ for_each_xml_child_node(childNode, node)
+ {
+ if (!xmlStrEqual(childNode->name, BAD_CAST "property"))
+ continue;
+
+ // Example: <property name="name" value="value"/>
+ const std::string name = XML::getProperty(childNode, "name", "");
+ const std::string value = XML::getProperty(childNode, "value", "");
+
+ if (!name.empty() && !value.empty())
+ props->setProperty(name, value);
+ }
+}
+
+static void setTile(Map *map, MapLayer *layer, int x, int y, int gid)
+{
+ const Tileset * const set = map->getTilesetWithGid(gid);
+ if (layer)
+ {
+ // Set regular tile on a layer
+ Image * const img = set ? set->get(gid - set->getFirstGid()) : 0;
+ layer->setTile(x, y, img);
+ }
+ else
+ {
+ // Set collision tile
+// if (set && (gid - set->getFirstGid() == 1)) buggy update
+ if (set && (gid - set->getFirstGid() != 0))
+ map->blockTile(x, y, Map::BLOCKTYPE_WALL);
+ }
+}
+
+void MapReader::readLayer(xmlNodePtr node, Map *map)
+{
+ // Layers are not necessarily the same size as the map
+ const int w = XML::getProperty(node, "width", map->getWidth());
+ const int h = XML::getProperty(node, "height", map->getHeight());
+ const int offsetX = XML::getProperty(node, "x", 0);
+ const int offsetY = XML::getProperty(node, "y", 0);
+ std::string name = XML::getProperty(node, "name", "");
+ name = toLower(name);
+
+ const bool isFringeLayer = (name.substr(0, 6) == "fringe");
+ const bool isCollisionLayer = (name.substr(0, 9) == "collision");
+
+ MapLayer *layer = 0;
+
+ if (!isCollisionLayer)
+ {
+ layer = new MapLayer(offsetX, offsetY, w, h, isFringeLayer);
+ map->addLayer(layer);
+ }
+
+ logger->log("- Loading layer \"%s\"", name.c_str());
+ int x = 0;
+ int y = 0;
+
+ // Load the tile data
+ for_each_xml_child_node(childNode, node)
+ {
+ if (!xmlStrEqual(childNode->name, BAD_CAST "data"))
+ continue;
+
+ const std::string encoding =
+ XML::getProperty(childNode, "encoding", "");
+ const std::string compression =
+ XML::getProperty(childNode, "compression", "");
+
+ if (encoding == "base64")
+ {
+ if (!compression.empty() && compression != "gzip")
+ {
+ logger->log1("Warning: only gzip layer"
+ " compression supported!");
+ return;
+ }
+
+ // Read base64 encoded map file
+ xmlNodePtr dataChild = childNode->xmlChildrenNode;
+ if (!dataChild)
+ continue;
+
+ int len = static_cast<int>(strlen(
+ (const char*)dataChild->content) + 1);
+ unsigned char *charData = new unsigned char[len + 1];
+ const char *charStart = (const char*)dataChild->content;
+ unsigned char *charIndex = charData;
+
+ while (*charStart)
+ {
+ if (*charStart != ' ' && *charStart != '\t' &&
+ *charStart != '\n')
+ {
+ *charIndex = *charStart;
+ charIndex++;
+ }
+ charStart++;
+ }
+ *charIndex = '\0';
+
+ int binLen;
+ unsigned char *binData = php3_base64_decode(charData,
+ static_cast<int>(strlen((char*)charData)), &binLen);
+
+ delete[] charData;
+
+ if (binData)
+ {
+ if (compression == "gzip")
+ {
+ // Inflate the gzipped layer data
+ unsigned char *inflated;
+ unsigned int inflatedSize =
+ inflateMemory(binData, binLen, inflated);
+
+ free(binData);
+ binData = inflated;
+ binLen = inflatedSize;
+
+ if (!inflated)
+ {
+ logger->log1("Error: Could not decompress layer!");
+ return;
+ }
+ }
+
+ for (int i = 0; i < binLen - 3; i += 4)
+ {
+ const int gid = binData[i] |
+ binData[i + 1] << 8 |
+ binData[i + 2] << 16 |
+ binData[i + 3] << 24;
+
+ setTile(map, layer, x, y, gid);
+
+ TileAnimation* ani = map->getAnimationForGid(gid);
+ if (ani)
+ ani->addAffectedTile(layer, x + y * w);
+
+ x++;
+ if (x == w)
+ {
+ x = 0; y++;
+
+ // When we're done, don't crash on too much data
+ if (y == h)
+ break;
+ }
+ }
+ free(binData);
+ }
+ }
+ else
+ {
+ // Read plain XML map file
+ for_each_xml_child_node(childNode2, childNode)
+ {
+ if (!xmlStrEqual(childNode2->name, BAD_CAST "tile"))
+ continue;
+
+ const int gid = XML::getProperty(childNode2, "gid", -1);
+ setTile(map, layer, x, y, gid);
+
+ x++;
+ if (x == w)
+ {
+ x = 0; y++;
+ if (y >= h)
+ break;
+ }
+ }
+ }
+
+ if (y < h)
+ std::cerr << "TOO SMALL!\n";
+ if (x)
+ std::cerr << "TOO SMALL!\n";
+
+ // There can be only one data element
+ break;
+ }
+
+/*
+ if (!layer)
+ return;
+
+ for (int y = 0; y < layer->getHeight(); y ++)
+ {
+ for (int x = 0 ; x < layer->getWidth() ; x ++)
+ {
+ int width;
+ int c = layer->getTileDrawWidth(x, y, layer->getWidth(), width);
+ layer->setTileInfo(x, y, width, c);
+ }
+ }
+*/
+
+/*
+ Image *img1 = 0;
+ for (int y = 0; y < layer->getHeight(); y ++)
+ {
+ int skipWidth = 0;
+ int skipCount = 0;
+ img1 = layer->getTile(0, y);
+ layer->setTileInfo(layer->getWidth() - 1, y, skipWidth, skipCount);
+ for (int x = layer->getWidth() - 1 ; x > 0 ; x --)
+ {
+ Image *img = layer->getTile(x, y);
+ if (img)
+ {
+ if (img != img1)
+ { // different tile
+ skipWidth = 0;
+ skipCount = 0;
+ }
+ else
+ { // same tile
+ skipWidth += img1->getWidth();
+ skipCount ++;
+ }
+ }
+ else
+ {
+ skipWidth = 0;
+ skipCount = 0;
+ }
+ layer->setTileInfo(x, y, skipWidth, skipCount);
+ img1 = img;
+ }
+ }
+*/
+}
+
+Tileset *MapReader::readTileset(xmlNodePtr node, const std::string &path,
+ Map *map)
+{
+ if (!map)
+ return NULL;
+
+ int firstGid = XML::getProperty(node, "firstgid", 0);
+ int margin = XML::getProperty(node, "margin", 0);
+ int spacing = XML::getProperty(node, "spacing", 0);
+ XML::Document* doc = NULL;
+ Tileset *set = NULL;
+ std::string pathDir(path);
+
+ if (xmlHasProp(node, BAD_CAST "source"))
+ {
+ std::string filename = XML::getProperty(node, "source", "");
+ filename = resolveRelativePath(path, filename);
+
+ doc = new XML::Document(filename);
+ node = doc->rootNode();
+
+ // Reset path to be realtive to the tsx file
+ pathDir = filename.substr(0, filename.rfind("/") + 1);
+ }
+
+ const int tw = XML::getProperty(node, "tilewidth", map->getTileWidth());
+ const int th = XML::getProperty(node, "tileheight", map->getTileHeight());
+
+ for_each_xml_child_node(childNode, node)
+ {
+ if (xmlStrEqual(childNode->name, BAD_CAST "image"))
+ {
+ const std::string source = XML::getProperty(
+ childNode, "source", "");
+
+ if (!source.empty())
+ {
+ std::string sourceStr = resolveRelativePath(pathDir, source);
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ Image* tilebmp = resman->getImage(sourceStr);
+
+ if (tilebmp)
+ {
+ set = new Tileset(tilebmp, tw, th, firstGid, margin,
+ spacing);
+ tilebmp->decRef();
+ }
+ else
+ {
+ logger->log("Warning: Failed to load tileset (%s)",
+ source.c_str());
+ }
+ }
+ }
+ else if (xmlStrEqual(childNode->name, BAD_CAST "tile"))
+ {
+ for_each_xml_child_node(tileNode, childNode)
+ {
+ if (!xmlStrEqual(tileNode->name, BAD_CAST "properties"))
+ continue;
+
+ int tileGID = firstGid + XML::getProperty(childNode, "id", 0);
+
+ // read tile properties to a map for simpler handling
+ std::map<std::string, int> tileProperties;
+ for_each_xml_child_node(propertyNode, tileNode)
+ {
+ if (!xmlStrEqual(propertyNode->name, BAD_CAST "property"))
+ continue;
+ std::string name = XML::getProperty(
+ propertyNode, "name", "");
+ int value = XML::getProperty(propertyNode, "value", 0);
+ tileProperties[name] = value;
+ logger->log("Tile Prop of %d \"%s\" = \"%d\"",
+ tileGID, name.c_str(), value);
+ }
+
+ // create animation
+ if (!set)
+ continue;
+
+ Animation *ani = new Animation;
+ for (int i = 0; ; i++)
+ {
+ std::map<std::string, int>::iterator iFrame, iDelay;
+ iFrame = tileProperties.find(
+ "animation-frame" + toString(i));
+ iDelay = tileProperties.find(
+ "animation-delay" + toString(i));
+ if (iFrame != tileProperties.end()
+ && iDelay != tileProperties.end())
+ {
+ ani->addFrame(set->get(iFrame->second),
+ iDelay->second, 0, 0);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (ani->getLength() > 0)
+ {
+ map->addAnimation(tileGID, new TileAnimation(ani));
+ logger->log("Animation length: %d", ani->getLength());
+ }
+ else
+ {
+ delete ani;
+ ani = 0;
+ }
+ }
+ }
+ }
+
+ delete doc;
+
+ return set;
+}
diff --git a/src/resources/mapreader.h b/src/resources/mapreader.h
new file mode 100644
index 000000000..ffa69d838
--- /dev/null
+++ b/src/resources/mapreader.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MAPREADER_H
+#define MAPREADER_H
+
+#include <libxml/tree.h>
+
+#include <string>
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Map;
+class Properties;
+class Tileset;
+
+/**
+ * Reader for XML map files (*.tmx)
+ */
+class MapReader
+{
+ public:
+ /**
+ * Read an XML map from a file.
+ */
+ static Map *readMap(const std::string &filename);
+
+ /**
+ * Read an XML map from a parsed XML tree. The path is used to find the
+ * location of referenced tileset images.
+ */
+ static Map *readMap(xmlNodePtr node, const std::string &path);
+
+ private:
+ /**
+ * Reads the properties element.
+ *
+ * @param node The <code>properties</code> element.
+ * @param props The Properties instance to which the properties will
+ * be assigned.
+ */
+ static void readProperties(xmlNodePtr node, Properties* props);
+
+ /**
+ * Reads a map layer and adds it to the given map.
+ */
+ static void readLayer(xmlNodePtr node, Map *map);
+
+ /**
+ * Reads a tile set.
+ */
+ static Tileset *readTileset(xmlNodePtr node, const std::string &path,
+ Map *map);
+};
+
+#endif
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
new file mode 100644
index 000000000..badd123c7
--- /dev/null
+++ b/src/resources/monsterdb.cpp
@@ -0,0 +1,199 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/monsterdb.h"
+
+#include "log.h"
+
+#include "net/net.h"
+
+#include "resources/beinginfo.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/xml.h"
+
+#include "configuration.h"
+
+#define OLD_TMWATHENA_OFFSET 1002
+
+namespace
+{
+ BeingInfos mMonsterInfos;
+ bool mLoaded = false;
+}
+
+void MonsterDB::load()
+{
+ if (mLoaded)
+ unload();
+
+ logger->log1("Initializing monster database...");
+
+ XML::Document doc("monsters.xml");
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "monsters"))
+ {
+ logger->log("Monster Database: Error while loading monster.xml!");
+ mLoaded = true;
+ return;
+ }
+
+ int offset = XML::getProperty(rootNode, "offset", Net::getNetworkType() ==
+ ServerInfo::TMWATHENA ? OLD_TMWATHENA_OFFSET : 0);
+
+ //iterate <monster>s
+ for_each_xml_child_node(monsterNode, rootNode)
+ {
+ if (!xmlStrEqual(monsterNode->name, BAD_CAST "monster"))
+ continue;
+
+ BeingInfo *currentInfo = new BeingInfo;
+
+ currentInfo->setWalkMask(Map::BLOCKMASK_WALL
+ | Map::BLOCKMASK_CHARACTER
+ | Map::BLOCKMASK_MONSTER);
+ currentInfo->setBlockType(Map::BLOCKTYPE_MONSTER);
+
+ currentInfo->setName(XML::getProperty(
+ monsterNode, "name", _("unnamed")));
+
+ currentInfo->setTargetCursorSize(XML::getProperty(monsterNode,
+ "targetCursor", "medium"));
+
+ currentInfo->setTargetOffsetX(XML::getProperty(monsterNode,
+ "targetOffsetX", 0));
+
+ currentInfo->setTargetOffsetY(XML::getProperty(monsterNode,
+ "targetOffsetY", 0));
+
+ currentInfo->setMaxHP(XML::getProperty(monsterNode,
+ "maxHP", 0));
+
+ if (currentInfo->getMaxHP())
+ currentInfo->setStaticMaxHP(true);
+
+ SpriteDisplay display;
+
+ //iterate <sprite>s and <sound>s
+ for_each_xml_child_node(spriteNode, monsterNode)
+ {
+ if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
+ {
+ SpriteReference *currentSprite = new SpriteReference;
+ currentSprite->sprite
+ = (const char*)spriteNode->xmlChildrenNode->content;
+
+ currentSprite->variant = XML::getProperty(
+ spriteNode, "variant", 0);
+ display.sprites.push_back(currentSprite);
+ }
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "sound"))
+ {
+ std::string event = XML::getProperty(spriteNode, "event", "");
+ const char *filename;
+ filename = (const char*) spriteNode->xmlChildrenNode->content;
+
+ if (event == "hit")
+ {
+ currentInfo->addSound(SOUND_EVENT_HIT, filename);
+ }
+ else if (event == "miss")
+ {
+ currentInfo->addSound(SOUND_EVENT_MISS, filename);
+ }
+ else if (event == "hurt")
+ {
+ currentInfo->addSound(SOUND_EVENT_HURT, filename);
+ }
+ else if (event == "die")
+ {
+ currentInfo->addSound(SOUND_EVENT_DIE, filename);
+ }
+ else
+ {
+ logger->log("MonsterDB: Warning, sound effect %s for "
+ "unknown event %s of monster %s",
+ filename, event.c_str(),
+ currentInfo->getName().c_str());
+ }
+ }
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack"))
+ {
+ const int id = XML::getProperty(spriteNode, "id", 0);
+ const std::string particleEffect = XML::getProperty(
+ spriteNode, "particle-effect", "");
+ const std::string spriteAction = XML::getProperty(spriteNode,
+ "action",
+ "attack");
+ const std::string missileParticle = XML::getProperty(
+ spriteNode, "missile-particle", "");
+ currentInfo->addAttack(id, spriteAction,
+ particleEffect, missileParticle);
+ }
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
+ {
+ display.particles.push_back(
+ (const char*) spriteNode->xmlChildrenNode->content);
+ }
+ }
+ currentInfo->setDisplay(display);
+
+ mMonsterInfos[XML::getProperty(
+ monsterNode, "id", 0) + offset] = currentInfo;
+ }
+
+ mLoaded = true;
+}
+
+void MonsterDB::unload()
+{
+ delete_all(mMonsterInfos);
+ mMonsterInfos.clear();
+
+ mLoaded = false;
+}
+
+
+BeingInfo *MonsterDB::get(int id)
+{
+ BeingInfoIterator i = mMonsterInfos.find(id);
+
+ if (i == mMonsterInfos.end())
+ {
+ i = mMonsterInfos.find(id + /*1002*/ OLD_TMWATHENA_OFFSET);
+ if (i == mMonsterInfos.end())
+ {
+ logger->log("MonsterDB: Warning, unknown monster ID %d requested",
+ id);
+ return BeingInfo::Unknown;
+ }
+ else
+ {
+ return i->second;
+ }
+ }
+ else
+ {
+ return i->second;
+ }
+}
diff --git a/src/resources/monsterdb.h b/src/resources/monsterdb.h
new file mode 100644
index 000000000..50f704388
--- /dev/null
+++ b/src/resources/monsterdb.h
@@ -0,0 +1,39 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MONSTER_DB_H
+#define MONSTER_DB_H
+
+class BeingInfo;
+
+/**
+ * Monster information database.
+ */
+namespace MonsterDB
+{
+ void load();
+
+ void unload();
+
+ BeingInfo *get(int id);
+}
+
+#endif
diff --git a/src/resources/music.cpp b/src/resources/music.cpp
new file mode 100644
index 000000000..c939d4f79
--- /dev/null
+++ b/src/resources/music.cpp
@@ -0,0 +1,84 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/music.h"
+
+#include "log.h"
+
+Music::Music(Mix_Chunk *music):
+ mChunk(music),
+ mChannel(-1)
+{
+}
+
+Music::~Music()
+{
+ //Mix_FreeMusic(music);
+ Mix_FreeChunk(mChunk);
+}
+
+Resource *Music::load(void *buffer, unsigned bufferSize)
+{
+ // Load the raw file data from the buffer in an RWops structure
+ SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
+
+ // Use Mix_LoadMUS to load the raw music data
+ //Mix_Music* music = Mix_LoadMUS_RW(rw); Need to be implemeted
+ Mix_Chunk *tmpMusic = Mix_LoadWAV_RW(rw, 1);
+
+ if (tmpMusic)
+ {
+ return new Music(tmpMusic);
+ }
+ else
+ {
+ logger->log("Error, failed to load music: %s", Mix_GetError());
+ return NULL;
+ }
+}
+
+bool Music::play(int loops)
+{
+ /*
+ * Warning: loops should be always set to -1 (infinite) with current
+ * implementation to avoid halting the playback of other samples
+ */
+
+ /*if (Mix_PlayMusic(music, loops))
+ return true;*/
+ Mix_VolumeChunk(mChunk, 120);
+ mChannel = Mix_PlayChannel(-1, mChunk, loops);
+
+ return mChannel != -1;
+}
+
+void Music::stop()
+{
+ /*
+ * Warning: very dungerous trick, it could try to stop channels occupied
+ * by samples rather than the current music file
+ */
+
+ //Mix_HaltMusic();
+
+ if (mChannel != -1)
+ Mix_HaltChannel(mChannel);
+}
diff --git a/src/resources/music.h b/src/resources/music.h
new file mode 100644
index 000000000..c0cf5abe9
--- /dev/null
+++ b/src/resources/music.h
@@ -0,0 +1,81 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MUSIC_H
+#define MUSIC_H
+
+#include "resources/resource.h"
+
+#ifdef __APPLE__
+#include <SDL_mixer/SDL_mixer.h>
+#else
+#include <SDL_mixer.h>
+#endif
+
+/**
+ * Defines a class for loading and storing music.
+ */
+class Music : public Resource
+{
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~Music();
+
+ /**
+ * Loads a music from a buffer in memory.
+ *
+ * @param buffer The memory buffer containing the music data.
+ * @param bufferSize The size of the memory buffer in bytes.
+ *
+ * @return <code>NULL</code> if the an error occurred, a valid pointer
+ * otherwise.
+ */
+ static Resource *load(void *buffer, unsigned bufferSize);
+
+ /**
+ * Plays the music.
+ *
+ * @param loops Number of times to repeat the playback.
+ *
+ * @return <code>true</code> if the playback started properly
+ * <code>false</code> otherwise.
+ */
+ virtual bool play(int loops);
+
+ /**
+ * Stops the music.
+ */
+ virtual void stop();
+
+ protected:
+ /**
+ * Constructor.
+ */
+ Music(Mix_Chunk *music);
+
+ //Mix_Music *music;
+ Mix_Chunk *mChunk;
+ int mChannel;
+};
+
+#endif
diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp
new file mode 100644
index 000000000..a5b9298b0
--- /dev/null
+++ b/src/resources/npcdb.cpp
@@ -0,0 +1,127 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/npcdb.h"
+
+#include "log.h"
+
+#include "resources/beinginfo.h"
+
+#include "utils/dtor.h"
+#include "utils/xml.h"
+#include "configuration.h"
+
+namespace
+{
+ BeingInfos mNPCInfos;
+ bool mLoaded = false;
+}
+
+void NPCDB::load()
+{
+ if (mLoaded)
+ unload();
+
+ logger->log1("Initializing NPC database...");
+
+ XML::Document doc("npcs.xml");
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "npcs"))
+ {
+ logger->log("NPC Database: Error while loading npcs.xml!");
+ mLoaded = true;
+ return;
+ }
+
+ //iterate <npc>s
+ for_each_xml_child_node(npcNode, rootNode)
+ {
+ if (!xmlStrEqual(npcNode->name, BAD_CAST "npc"))
+ continue;
+
+ int id = XML::getProperty(npcNode, "id", 0);
+ if (id == 0)
+ {
+ logger->log1("NPC Database: NPC with missing ID in npcs.xml!");
+ continue;
+ }
+
+ BeingInfo *currentInfo = new BeingInfo;
+
+ currentInfo->setTargetCursorSize(XML::getProperty(npcNode,
+ "targetCursor", "medium"));
+
+ currentInfo->setTargetOffsetX(XML::getProperty(npcNode,
+ "targetOffsetX", 0));
+
+ currentInfo->setTargetOffsetY(XML::getProperty(npcNode,
+ "targetOffsetY", 0));
+ SpriteDisplay display;
+ for_each_xml_child_node(spriteNode, npcNode)
+ {
+ if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
+ {
+ SpriteReference *currentSprite = new SpriteReference;
+ currentSprite->sprite =
+ (const char*)spriteNode->xmlChildrenNode->content;
+ currentSprite->variant =
+ XML::getProperty(spriteNode, "variant", 0);
+ display.sprites.push_back(currentSprite);
+ }
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
+ {
+ std::string particlefx =
+ (const char*)spriteNode->xmlChildrenNode->content;
+ display.particles.push_back(particlefx);
+ }
+ }
+
+ currentInfo->setDisplay(display);
+
+ mNPCInfos[id] = currentInfo;
+ }
+
+ mLoaded = true;
+}
+
+void NPCDB::unload()
+{
+ delete_all(mNPCInfos);
+ mNPCInfos.clear();
+
+ mLoaded = false;
+}
+
+BeingInfo *NPCDB::get(int id)
+{
+ BeingInfoIterator i = mNPCInfos.find(id);
+
+ if (i == mNPCInfos.end())
+ {
+ logger->log("NPCDB: Warning, unknown NPC ID %d requested", id);
+ return BeingInfo::Unknown;
+ }
+ else
+ {
+ return i->second;
+ }
+}
diff --git a/src/resources/npcdb.h b/src/resources/npcdb.h
new file mode 100644
index 000000000..b0c89c804
--- /dev/null
+++ b/src/resources/npcdb.h
@@ -0,0 +1,39 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef NPC_DB_H
+#define NPC_DB_H
+
+class BeingInfo;
+
+/**
+ * NPC information database.
+ */
+namespace NPCDB
+{
+ void load();
+
+ void unload();
+
+ BeingInfo *get(int id);
+}
+
+#endif
diff --git a/src/resources/resource.cpp b/src/resources/resource.cpp
new file mode 100644
index 000000000..5a8dd3176
--- /dev/null
+++ b/src/resources/resource.cpp
@@ -0,0 +1,58 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/resource.h"
+
+#include "client.h"
+#include "log.h"
+
+#include "resources/resourcemanager.h"
+
+#include <cassert>
+
+Resource::~Resource()
+{
+}
+
+void Resource::incRef()
+{
+ mRefCount++;
+}
+
+void Resource::decRef()
+{
+ // Reference may not already have reached zero
+ if (mRefCount == 0)
+ {
+ logger->log("Warning: mRefCount already zero for %s", mIdPath.c_str());
+ return;
+// assert(false);
+ }
+
+ mRefCount--;
+
+ if (mRefCount == 0)
+ {
+ // Warn the manager that this resource is no longer used.
+ ResourceManager *resman = ResourceManager::getInstance();
+ resman->release(this);
+ }
+}
diff --git a/src/resources/resource.h b/src/resources/resource.h
new file mode 100644
index 000000000..89fcc9de7
--- /dev/null
+++ b/src/resources/resource.h
@@ -0,0 +1,81 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+#include <ctime>
+#include <string>
+
+/**
+ * A generic reference counted resource object.
+ */
+class Resource
+{
+ friend class ResourceManager;
+
+ public:
+ /**
+ * Constructor
+ */
+ Resource(): mRefCount(0)
+ { }
+
+ /**
+ * Increments the internal reference count.
+ */
+ void incRef();
+
+ /**
+ * Decrements the reference count and deletes the object
+ * if no references are left.
+ *
+ * @return <code>true</code> if the object was deleted
+ * <code>false</code> otherwise.
+ */
+ void decRef();
+
+ /**
+ * Return the path identifying this resource.
+ */
+ const std::string &getIdPath() const
+ { return mIdPath; }
+
+ /**
+ * Return refCount for this resource.
+ */
+ unsigned getRefCount()
+ { return mRefCount; }
+
+ protected:
+ /**
+ * Destructor.
+ */
+ virtual ~Resource();
+
+ private:
+ std::string mIdPath; /**< Path identifying this resource. */
+ time_t mTimeStamp; /**< Time at which the resource was orphaned. */
+ unsigned mRefCount; /**< Reference count. */
+ std::string mName;
+};
+
+#endif
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
new file mode 100644
index 000000000..7bdcce386
--- /dev/null
+++ b/src/resources/resourcemanager.cpp
@@ -0,0 +1,658 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/resourcemanager.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "log.h"
+#include "main.h"
+
+#include "resources/dye.h"
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/music.h"
+#include "resources/soundeffect.h"
+#include "resources/spritedef.h"
+
+#include <physfs.h>
+#include <SDL_image.h>
+#include <cassert>
+#include <sstream>
+
+#include <sys/time.h>
+
+#define THEMES_FOLDER "themes"
+
+ResourceManager *ResourceManager::instance = NULL;
+
+ResourceManager::ResourceManager()
+ : mOldestOrphan(0),
+ mSelectedSkin(""),
+ mSkinName("")
+{
+ logger->log1("Initializing resource manager...");
+}
+
+ResourceManager::~ResourceManager()
+{
+ mResources.insert(mOrphanedResources.begin(), mOrphanedResources.end());
+
+ // Release any remaining spritedefs first because they depend on image sets
+ ResourceIterator iter = mResources.begin();
+
+#ifdef DEBUG_LEAKS
+ while (iter != mResources.end())
+ {
+ if (iter->second)
+ {
+ if (iter->second->getRefCount())
+ {
+ logger->log("ResourceLeak: " + iter->second->getIdPath()
+ + " (" + toString(iter->second->getRefCount())
+ + ")");
+ }
+ }
+ ++iter;
+ }
+
+ iter = mResources.begin();
+#endif
+
+ while (iter != mResources.end())
+ {
+#ifdef DEBUG_LEAKS
+ if (iter->second && iter->second->getRefCount())
+ {
+ ++iter;
+ continue;
+ }
+#endif
+ if (dynamic_cast<SpriteDef*>(iter->second) != 0)
+ {
+ cleanUp(iter->second);
+ ResourceIterator toErase = iter;
+ ++iter;
+ mResources.erase(toErase);
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+
+ // Release any remaining image sets first because they depend on images
+ iter = mResources.begin();
+ while (iter != mResources.end())
+ {
+#ifdef DEBUG_LEAKS
+ if (iter->second && iter->second->getRefCount())
+ {
+ ++iter;
+ continue;
+ }
+#endif
+ if (dynamic_cast<ImageSet*>(iter->second) != 0)
+ {
+ cleanUp(iter->second);
+ ResourceIterator toErase = iter;
+ ++iter;
+ mResources.erase(toErase);
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+
+ // Release remaining resources, logging the number of dangling references.
+ iter = mResources.begin();
+ while (iter != mResources.end())
+ {
+#ifdef DEBUG_LEAKS
+ if (iter->second && iter->second->getRefCount())
+ {
+ ++iter;
+ continue;
+ }
+#endif
+ if (iter->second)
+ cleanUp(iter->second);
+ ++iter;
+ }
+}
+
+void ResourceManager::cleanUp(Resource *res)
+{
+ if (!res)
+ return;
+
+ if (res->mRefCount > 0)
+ {
+ logger->log("ResourceManager::~ResourceManager() cleaning up %d "
+ "reference%s to %s",
+ res->mRefCount,
+ (res->mRefCount == 1) ? "" : "s",
+ res->mIdPath.c_str());
+ }
+
+ delete res;
+}
+
+void ResourceManager::cleanOrphans()
+{
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ // Delete orphaned resources after 30 seconds.
+ time_t oldest = tv.tv_sec, threshold = oldest - 30;
+
+ if (mOrphanedResources.empty() || mOldestOrphan >= threshold)
+ return;
+
+ ResourceIterator iter = mOrphanedResources.begin();
+ while (iter != mOrphanedResources.end())
+ {
+ Resource *res = iter->second;
+ if (!res)
+ {
+ ++iter;
+ continue;
+ }
+ time_t t = res->mTimeStamp;
+ if (t >= threshold)
+ {
+ if (t < oldest) oldest = t;
+ ++iter;
+ }
+ else
+ {
+ logger->log("ResourceManager::release(%s)", res->mIdPath.c_str());
+ ResourceIterator toErase = iter;
+ ++iter;
+ mOrphanedResources.erase(toErase);
+ delete res; // delete only after removal from list,
+ // to avoid issues in recursion
+ }
+ }
+
+ mOldestOrphan = oldest;
+}
+
+bool ResourceManager::setWriteDir(const std::string &path)
+{
+ return (bool) PHYSFS_setWriteDir(path.c_str());
+}
+
+bool ResourceManager::addToSearchPath(const std::string &path, bool append)
+{
+ logger->log("Adding to PhysicsFS: %s (%s)", path.c_str(),
+ append ? "append" : "prepend");
+ if (!PHYSFS_addToSearchPath(path.c_str(), append ? 1 : 0))
+ {
+ logger->log("Error: %s", PHYSFS_getLastError());
+ return false;
+ }
+ return true;
+}
+
+bool ResourceManager::removeFromSearchPath(const std::string &path)
+{
+ logger->log("Removing from PhysicsFS: %s", path.c_str());
+ if (!PHYSFS_removeFromSearchPath(path.c_str()))
+ {
+ logger->log("Error: %s", PHYSFS_getLastError());
+ return false;
+ }
+ return true;
+}
+
+void ResourceManager::searchAndAddArchives(const std::string &path,
+ const std::string &ext,
+ bool append)
+{
+ const char *dirSep = PHYSFS_getDirSeparator();
+ char **list = PHYSFS_enumerateFiles(path.c_str());
+
+ for (char **i = list; *i; i++)
+ {
+ size_t len = strlen(*i);
+
+ if (len > ext.length() && !ext.compare((*i) + (len - ext.length())))
+ {
+ std::string file, realPath, archive, realFixPath;
+
+ file = path + (*i);
+ realPath = std::string(PHYSFS_getRealDir(file.c_str()));
+ archive = realPath + dirSep + file;
+
+ addToSearchPath(archive, append);
+ }
+ }
+
+ PHYSFS_freeList(list);
+}
+
+void ResourceManager::searchAndRemoveArchives(const std::string &path,
+ const std::string &ext)
+{
+ const char *dirSep = PHYSFS_getDirSeparator();
+ char **list = PHYSFS_enumerateFiles(path.c_str());
+
+ for (char **i = list; *i; i++)
+ {
+ size_t len = strlen(*i);
+
+ if (len > ext.length() && !ext.compare((*i) + (len - ext.length())))
+ {
+ std::string file, realPath, archive, realFixPath;
+
+ file = path + (*i);
+ realPath = std::string(PHYSFS_getRealDir(file.c_str()));
+ archive = realPath + dirSep + file;
+
+ removeFromSearchPath(archive);
+ }
+ }
+
+ PHYSFS_freeList(list);
+}
+
+bool ResourceManager::mkdir(const std::string &path)
+{
+ return (bool) PHYSFS_mkdir(path.c_str());
+}
+
+bool ResourceManager::exists(const std::string &path)
+{
+ return PHYSFS_exists(path.c_str());
+}
+
+bool ResourceManager::isDirectory(const std::string &path)
+{
+ return PHYSFS_isDirectory(path.c_str());
+}
+
+std::string ResourceManager::getPath(const std::string &file)
+{
+ // get the real path to the file
+ const char* tmp = PHYSFS_getRealDir(file.c_str());
+ std::string path;
+
+ // if the file is not in the search path, then its NULL
+ if (tmp)
+ {
+ path = std::string(tmp) + "/" + file;
+ }
+ else
+ {
+ // if not found in search path return the default path
+ path = Client::getPackageDirectory() + "/" + file;
+ }
+
+ return path;
+}
+
+bool ResourceManager::addResource(const std::string &idPath,
+ Resource* resource)
+{
+ if (resource)
+ {
+ resource->incRef();
+ resource->mIdPath = idPath;
+ mResources[idPath] = resource;
+ return true;
+ }
+ return false;
+}
+
+Resource *ResourceManager::get(const std::string &idPath, generator fun,
+ void *data)
+{
+ // Check if the id exists, and return the value if it does.
+ ResourceIterator resIter = mResources.find(idPath);
+ if (resIter != mResources.end())
+ {
+ if (resIter->second)
+ resIter->second->incRef();
+ return resIter->second;
+ }
+
+ resIter = mOrphanedResources.find(idPath);
+ if (resIter != mOrphanedResources.end())
+ {
+ Resource *res = resIter->second;
+ mResources.insert(*resIter);
+ mOrphanedResources.erase(resIter);
+ if (res)
+ res->incRef();
+ return res;
+ }
+
+ Resource *resource = fun(data);
+
+ if (resource)
+ {
+ resource->incRef();
+ resource->mIdPath = idPath;
+ mResources[idPath] = resource;
+ cleanOrphans();
+ }
+ else
+ {
+ logger->log("Error loaging image: " + idPath);
+ }
+
+ // Returns NULL if the object could not be created.
+ return resource;
+}
+
+struct ResourceLoader
+{
+ ResourceManager *manager;
+ std::string path;
+ ResourceManager::loader fun;
+ static Resource *load(void *v)
+ {
+ ResourceLoader *l = static_cast< ResourceLoader * >(v);
+ int fileSize;
+ if (!l->manager)
+ return NULL;
+ void *buffer = l->manager->loadFile(l->path, fileSize);
+ if (!buffer)
+ return NULL;
+ Resource *res = l->fun(buffer, fileSize);
+ free(buffer);
+ return res;
+ }
+};
+
+Resource *ResourceManager::load(const std::string &path, loader fun)
+{
+ ResourceLoader l = { this, path, fun };
+ return get(path, ResourceLoader::load, &l);
+}
+
+Music *ResourceManager::getMusic(const std::string &idPath)
+{
+ return static_cast<Music*>(load(idPath, Music::load));
+}
+
+SoundEffect *ResourceManager::getSoundEffect(const std::string &idPath)
+{
+ return static_cast<SoundEffect*>(load(idPath, SoundEffect::load));
+}
+
+struct DyedImageLoader
+{
+ ResourceManager *manager;
+ std::string path;
+ static Resource *load(void *v)
+ {
+ if (!v)
+ return NULL;
+
+ DyedImageLoader *l = static_cast< DyedImageLoader * >(v);
+ if (!l->manager)
+ return NULL;
+
+ std::string path = l->path;
+ std::string::size_type p = path.find('|');
+ Dye *d = NULL;
+ if (p != std::string::npos)
+ {
+ d = new Dye(path.substr(p + 1));
+ path = path.substr(0, p);
+ }
+ int fileSize;
+ void *buffer = l->manager->loadFile(path, fileSize);
+ if (!buffer)
+ {
+ delete d;
+ return 0;
+ }
+ Resource *res = d ? Image::load(buffer, fileSize, *d)
+ : Image::load(buffer, fileSize);
+ free(buffer);
+ delete d;
+ return res;
+ }
+};
+
+Image *ResourceManager::getImage(const std::string &idPath)
+{
+ DyedImageLoader l = { this, idPath };
+ return static_cast<Image*>(get(idPath, DyedImageLoader::load, &l));
+}
+
+/*
+Image *ResourceManager::getSkinImage(const std::string &idPath)
+{
+ if (mSelectedSkin.empty())
+ return getImage(idPath);
+
+ DyedImageLoader l = { this, mSelectedSkin + idPath };
+ void *ptr = get(idPath, DyedImageLoader::load, &l);
+ if (ptr)
+ return static_cast<Image*>(ptr);
+ else
+ return getImage(idPath);
+}
+*/
+
+struct ImageSetLoader
+{
+ ResourceManager *manager;
+ std::string path;
+ int w, h;
+ static Resource *load(void *v)
+ {
+ if (!v)
+ return NULL;
+
+ ImageSetLoader *l = static_cast< ImageSetLoader * >(v);
+ if (!l->manager)
+ return NULL;
+
+ Image *img = l->manager->getImage(l->path);
+ if (!img)
+ return NULL;
+ ImageSet *res = new ImageSet(img, l->w, l->h);
+ img->decRef();
+ return res;
+ }
+};
+
+ImageSet *ResourceManager::getImageSet(const std::string &imagePath,
+ int w, int h)
+{
+ ImageSetLoader l = { this, imagePath, w, h };
+ std::stringstream ss;
+ ss << imagePath << "[" << w << "x" << h << "]";
+ return static_cast<ImageSet*>(get(ss.str(), ImageSetLoader::load, &l));
+}
+
+struct SpriteDefLoader
+{
+ std::string path;
+ int variant;
+ static Resource *load(void *v)
+ {
+ if (!v)
+ return NULL;
+
+ SpriteDefLoader *l = static_cast< SpriteDefLoader * >(v);
+ return SpriteDef::load(l->path, l->variant);
+ }
+};
+
+SpriteDef *ResourceManager::getSprite(const std::string &path, int variant)
+{
+ SpriteDefLoader l = { path, variant };
+ std::stringstream ss;
+ ss << path << "[" << variant << "]";
+ return static_cast<SpriteDef*>(get(ss.str(), SpriteDefLoader::load, &l));
+}
+
+void ResourceManager::release(Resource *res)
+{
+ if (!res)
+ return;
+
+ ResourceIterator resIter = mResources.find(res->mIdPath);
+
+ // The resource has to exist
+ assert(resIter != mResources.end() && resIter->second == res);
+
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ time_t timestamp = tv.tv_sec;
+
+ res->mTimeStamp = timestamp;
+ if (mOrphanedResources.empty()) mOldestOrphan = timestamp;
+
+ mOrphanedResources.insert(*resIter);
+ mResources.erase(resIter);
+}
+
+ResourceManager *ResourceManager::getInstance()
+{
+ // Create a new instance if necessary.
+ if (!instance)
+ instance = new ResourceManager;
+ return instance;
+}
+
+void ResourceManager::deleteInstance()
+{
+ delete instance;
+ instance = 0;
+}
+
+void *ResourceManager::loadFile(const std::string &fileName, int &fileSize)
+{
+ // Attempt to open the specified file using PhysicsFS
+ PHYSFS_file *file = PHYSFS_openRead(fileName.c_str());
+
+ // If the handler is an invalid pointer indicate failure
+ if (file == NULL)
+ {
+ logger->log("Warning: Failed to load %s: %s",
+ fileName.c_str(), PHYSFS_getLastError());
+ return NULL;
+ }
+
+ // Log the real dir of the file
+ logger->log("Loaded %s/%s", PHYSFS_getRealDir(fileName.c_str()),
+ fileName.c_str());
+
+ // Get the size of the file
+ fileSize = static_cast<int>(PHYSFS_fileLength(file));
+
+ // Allocate memory and load the file
+ void *buffer = malloc(fileSize);
+ PHYSFS_read(file, buffer, 1, fileSize);
+
+ // Close the file and let the user deallocate the memory
+ PHYSFS_close(file);
+
+ return buffer;
+}
+
+bool ResourceManager::copyFile(const std::string &src, const std::string &dst)
+{
+ PHYSFS_file *srcFile = PHYSFS_openRead(src.c_str());
+ if (!srcFile)
+ {
+ logger->log("Read error: %s", PHYSFS_getLastError());
+ return false;
+ }
+ PHYSFS_file *dstFile = PHYSFS_openWrite(dst.c_str());
+ if (!dstFile)
+ {
+ logger->log("Write error: %s", PHYSFS_getLastError());
+ PHYSFS_close(srcFile);
+ return false;
+ }
+
+ int fileSize = static_cast<int>(PHYSFS_fileLength(srcFile));
+ void *buf = malloc(fileSize);
+ PHYSFS_read(srcFile, buf, 1, fileSize);
+ PHYSFS_write(dstFile, buf, 1, fileSize);
+
+ PHYSFS_close(srcFile);
+ PHYSFS_close(dstFile);
+ free(buf);
+ return true;
+}
+
+std::vector<std::string> ResourceManager::loadTextFile(
+ const std::string &fileName)
+{
+ int contentsLength;
+ char *fileContents = (char*)loadFile(fileName, contentsLength);
+ std::vector<std::string> lines;
+
+ if (!fileContents)
+ {
+ logger->log("Couldn't load text file: %s", fileName.c_str());
+ return lines;
+ }
+
+ std::istringstream iss(std::string(fileContents, contentsLength));
+ std::string line;
+
+ while (getline(iss, line))
+ lines.push_back(line);
+
+ free(fileContents);
+ return lines;
+}
+
+SDL_Surface *ResourceManager::loadSDLSurface(const std::string &filename)
+{
+ int fileSize;
+ void *buffer = loadFile(filename, fileSize);
+ SDL_Surface *tmp = NULL;
+
+ if (buffer)
+ {
+ SDL_RWops *rw = SDL_RWFromMem(buffer, fileSize);
+ tmp = IMG_Load_RW(rw, 1);
+ ::free(buffer);
+ }
+
+ return tmp;
+}
+
+void ResourceManager::scheduleDelete(SDL_Surface* surface)
+{
+ deletedSurfaces.insert(surface);
+}
+
+void ResourceManager::clearScheduled()
+{
+ for (std::set<SDL_Surface*>::iterator i = deletedSurfaces.begin(),
+ i_end = deletedSurfaces.end(); i != i_end; ++i)
+ {
+ SDL_FreeSurface(*i);
+ }
+ deletedSurfaces.clear();
+}
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
new file mode 100644
index 000000000..163369a64
--- /dev/null
+++ b/src/resources/resourcemanager.h
@@ -0,0 +1,265 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef RESOURCE_MANAGER_H
+#define RESOURCE_MANAGER_H
+
+#include <ctime>
+#include <map>
+#include <string>
+#include <vector>
+#include <set>
+
+class Image;
+class ImageSet;
+class Music;
+class Resource;
+class SoundEffect;
+class SpriteDef;
+struct SDL_Surface;
+
+/**
+ * A class for loading and managing resources.
+ */
+class ResourceManager
+{
+ friend class Resource;
+
+ public:
+
+ typedef Resource *(*loader)(void *, unsigned);
+ typedef Resource *(*generator)(void *);
+
+ ResourceManager();
+
+ /**
+ * Destructor. Cleans up remaining resources, warning about resources
+ * that were still referenced.
+ */
+ ~ResourceManager();
+
+ /**
+ * Sets the write directory.
+ *
+ * @param path The path of the directory to be added.
+ * @return <code>true</code> on success, <code>false</code> otherwise.
+ */
+ bool setWriteDir(const std::string &path);
+
+ /**
+ * Adds a directory or archive to the search path. If append is true
+ * then the directory is added to the end of the search path, otherwise
+ * it is added at the front.
+ *
+ * @return <code>true</code> on success, <code>false</code> otherwise.
+ */
+ bool addToSearchPath(const std::string &path, bool append);
+
+ /**
+ * Remove a directory or archive from the search path.
+ *
+ * @return <code>true</code> on success, <code>false</code> otherwise.
+ */
+ bool removeFromSearchPath(const std::string &path);
+
+ /**
+ * Searches for zip files and adds them to the search path.
+ */
+ void searchAndAddArchives(const std::string &path,
+ const std::string &ext,
+ bool append);
+
+ /**
+ * Searches for zip files and remove them from the search path.
+ */
+ void searchAndRemoveArchives(const std::string &path,
+ const std::string &ext);
+
+ /**
+ * Creates a directory in the write path
+ */
+ bool mkdir(const std::string &path);
+
+ /**
+ * Checks whether the given file or directory exists in the search path
+ */
+ bool exists(const std::string &path);
+
+ /**
+ * Checks whether the given path is a directory.
+ */
+ bool isDirectory(const std::string &path);
+
+ /**
+ * Returns the real path to a file. Note that this method will always
+ * return a path, it does not check whether the file exists.
+ *
+ * @param file The file to get the real path to.
+ * @return The real path.
+ */
+ std::string getPath(const std::string &file);
+
+ /**
+ * Creates a resource and adds it to the resource map.
+ *
+ * @param idPath The resource identifier path.
+ * @param fun A function for generating the resource.
+ * @param data Extra parameters for the generator.
+ * @return A valid resource or <code>NULL</code> if the resource could
+ * not be generated.
+ */
+ Resource *get(const std::string &idPath, generator fun, void *data);
+
+ /**
+ * Loads a resource from a file and adds it to the resource map.
+ *
+ * @param path The file name.
+ * @param fun A function for parsing the file.
+ * @return A valid resource or <code>NULL</code> if the resource could
+ * not be loaded.
+ */
+ Resource *load(const std::string &path, loader fun);
+
+ /**
+ * Adds a preformatted resource to the resource map.
+ *
+ * @param path The file name.
+ * @param Resource The Resource to add.
+ * @return true if successfull, false otherwise.
+ */
+ bool addResource(const std::string &idPath, Resource* resource);
+
+ /**
+ * Copies a file from one place to another (useful for extracting
+ * raw files from a zip archive, for example)
+ *
+ * @param src Source file name
+ * @param dst Destination file name
+ * @return true on success, false on failure. An error message should be
+ * in the log file.
+ */
+ bool copyFile(const std::string &src, const std::string &dst);
+
+ /**
+ * Convenience wrapper around ResourceManager::get for loading
+ * images.
+ */
+ Image *getImage(const std::string &idPath);
+
+ /**
+ * Convenience wrapper around ResourceManager::get for loading
+ * songs.
+ */
+ Music *getMusic(const std::string &idPath);
+
+ /**
+ * Convenience wrapper around ResourceManager::get for loading
+ * samples.
+ */
+ SoundEffect *getSoundEffect(const std::string &idPath);
+
+ /**
+ * Creates a image set based on the image referenced by the given
+ * path and the supplied sprite sizes
+ */
+ ImageSet *getImageSet(const std::string &imagePath, int w, int h);
+
+ /**
+ * Creates a sprite definition based on a given path and the supplied
+ * variant.
+ */
+ SpriteDef *getSprite(const std::string &path, int variant = 0);
+
+ /**
+ * Releases a resource, placing it in the set of orphaned resources.
+ */
+ void release(Resource *);
+
+ /**
+ * Allocates data into a buffer pointer for raw data loading. The
+ * returned data is expected to be freed using <code>free()</code>.
+ *
+ * @param fileName The name of the file to be loaded.
+ * @param fileSize The size of the file that was loaded.
+ *
+ * @return An allocated byte array containing the data that was loaded,
+ * or <code>NULL</code> on fail.
+ */
+ void *loadFile(const std::string &fileName, int &fileSize);
+
+ /**
+ * Retrieves the contents of a text file.
+ */
+ std::vector<std::string> loadTextFile(const std::string &fileName);
+
+ /**
+ * Loads the given filename as an SDL surface. The returned surface is
+ * expected to be freed by the caller using SDL_FreeSurface.
+ */
+ SDL_Surface *loadSDLSurface(const std::string &filename);
+
+ void scheduleDelete(SDL_Surface* surface);
+
+ void clearScheduled();
+
+ /**
+ * Returns an instance of the class, creating one if it does not
+ * already exist.
+ */
+ static ResourceManager *getInstance();
+
+ /**
+ * Deletes the class instance if it exists.
+ */
+ static void deleteInstance();
+
+/*
+ void selectSkin();
+
+ Image *getSkinImage(const std::string &idPath);
+
+ std::string mapPathToSkin(const std::string &file);
+
+ void fillSkinsList(std::vector<std::string> &list) const;
+
+ std::string getSkinName() const { return mSkinName; }
+*/
+
+ private:
+ /**
+ * Deletes the resource after logging a cleanup message.
+ */
+ static void cleanUp(Resource *resource);
+
+ void cleanOrphans();
+
+ static ResourceManager *instance;
+ typedef std::map<std::string, Resource*> Resources;
+ typedef Resources::iterator ResourceIterator;
+ std::set<SDL_Surface*> deletedSurfaces;
+ Resources mResources;
+ Resources mOrphanedResources;
+ time_t mOldestOrphan;
+ std::string mSelectedSkin;
+ std::string mSkinName;
+};
+
+#endif
diff --git a/src/resources/soundeffect.cpp b/src/resources/soundeffect.cpp
new file mode 100644
index 000000000..823529c63
--- /dev/null
+++ b/src/resources/soundeffect.cpp
@@ -0,0 +1,58 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/soundeffect.h"
+
+#include "log.h"
+
+SoundEffect::~SoundEffect()
+{
+ Mix_FreeChunk(mChunk);
+}
+
+Resource *SoundEffect::load(void *buffer, unsigned bufferSize)
+{
+ if (!buffer)
+ return NULL;
+
+ // Load the raw file data from the buffer in an RWops structure
+ SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
+
+ // Load the music data and free the RWops structure
+ Mix_Chunk *tmpSoundEffect = Mix_LoadWAV_RW(rw, 1);
+
+ if (tmpSoundEffect)
+ {
+ return new SoundEffect(tmpSoundEffect);
+ }
+ else
+ {
+ logger->log("Error, failed to load sound effect: %s", Mix_GetError());
+ return NULL;
+ }
+}
+
+bool SoundEffect::play(int loops, int volume)
+{
+ Mix_VolumeChunk(mChunk, volume);
+
+ return Mix_PlayChannel(-1, mChunk, loops) != -1;
+}
diff --git a/src/resources/soundeffect.h b/src/resources/soundeffect.h
new file mode 100644
index 000000000..e7c832f42
--- /dev/null
+++ b/src/resources/soundeffect.h
@@ -0,0 +1,75 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SOUND_EFFECT_H
+#define SOUND_EFFECT_H
+
+#include "resources/resource.h"
+
+#ifdef __APPLE__
+#include <SDL_mixer/SDL_mixer.h>
+#else
+#include <SDL_mixer.h>
+#endif
+
+/**
+ * Defines a class for loading and storing sound effects.
+ */
+class SoundEffect : public Resource
+{
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~SoundEffect();
+
+ /**
+ * Loads a sample from a buffer in memory.
+ *
+ * @param buffer The memory buffer containing the sample data.
+ * @param bufferSize The size of the memory buffer in bytes.
+ *
+ * @return <code>NULL</code> if the an error occurred, a valid pointer
+ * otherwise.
+ */
+ static Resource *load(void *buffer, unsigned bufferSize);
+
+ /**
+ * Plays the sample.
+ *
+ * @param loops Number of times to repeat the playback.
+ * @param volume Sample playback volume.
+ *
+ * @return <code>true</code> if the playback started properly
+ * <code>false</code> otherwise.
+ */
+ virtual bool play(int loops, int volume);
+
+ protected:
+ /**
+ * Constructor.
+ */
+ SoundEffect(Mix_Chunk *soundEffect): mChunk(soundEffect) {}
+
+ Mix_Chunk *mChunk;
+};
+
+#endif // SOUND_EFFECT_H
diff --git a/src/resources/specialdb.cpp b/src/resources/specialdb.cpp
new file mode 100644
index 000000000..93edfb683
--- /dev/null
+++ b/src/resources/specialdb.cpp
@@ -0,0 +1,132 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/specialdb.h"
+
+#include "log.h"
+
+#include "utils/dtor.h"
+#include "utils/xml.h"
+
+
+namespace
+{
+ SpecialInfos mSpecialInfos;
+ bool mLoaded = false;
+}
+
+SpecialInfo::TargetMode SpecialDB::targetModeFromString(const std::string& str)
+{
+ if (str == "self") return SpecialInfo::TARGET_SELF;
+ else if (str == "friend") return SpecialInfo::TARGET_FRIEND;
+ else if (str == "enemy") return SpecialInfo::TARGET_ENEMY;
+ else if (str == "being") return SpecialInfo::TARGET_BEING;
+ else if (str == "point") return SpecialInfo::TARGET_POINT;
+
+ logger->log("SpecialDB: Warning, unknown target mode \"%s\"",
+ str.c_str() );
+ return SpecialInfo::TARGET_SELF;
+}
+
+void SpecialDB::load()
+{
+ if (mLoaded)
+ unload();
+
+ logger->log("Initializing special database...");
+
+ XML::Document doc("specials.xml");
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "specials"))
+ {
+ logger->log("Error loading specials file specials.xml");
+ return;
+ }
+
+ std::string setName;
+
+ for_each_xml_child_node(set, root)
+ {
+ if (xmlStrEqual(set->name, BAD_CAST "set"))
+ {
+ setName = XML::getProperty(set, "name", "Actions");
+
+ for_each_xml_child_node(special, set)
+ {
+ if (xmlStrEqual(special->name, BAD_CAST "special"))
+ {
+ SpecialInfo *info = new SpecialInfo();
+ int id = XML::getProperty(special, "id", 0);
+ info->id = id;
+ info->set = setName;
+ info->name = XML::getProperty(special, "name", "");
+ info->icon = XML::getProperty(special, "icon", "");
+
+ info->isActive = XML::getBoolProperty(
+ special, "active", false);
+ info->targetMode = targetModeFromString(XML::getProperty(
+ special, "target", "self"));
+
+ info->level = XML::getProperty(special, "level", -1);
+ info->hasLevel = info->level > -1;
+
+ info->hasRechargeBar = XML::getBoolProperty(special,
+ "recharge", false);
+ info->rechargeNeeded = 0;
+ info->rechargeCurrent = 0;
+
+ if (mSpecialInfos.find(id) != mSpecialInfos.end())
+ {
+ logger->log("SpecialDB: Duplicate special ID"
+ " %d (ignoring)", id);
+ }
+ else
+ {
+ mSpecialInfos[id] = info;
+ }
+ }
+ }
+ }
+ }
+
+ mLoaded = true;
+}
+
+void SpecialDB::unload()
+{
+ delete_all(mSpecialInfos);
+ mSpecialInfos.clear();
+
+ mLoaded = false;
+}
+
+
+SpecialInfo *SpecialDB::get(int id)
+{
+ SpecialInfos::iterator i = mSpecialInfos.find(id);
+
+ if (i == mSpecialInfos.end())
+ return NULL;
+ else
+ return i->second;
+ return NULL;
+}
+
diff --git a/src/resources/specialdb.h b/src/resources/specialdb.h
new file mode 100644
index 000000000..988651723
--- /dev/null
+++ b/src/resources/specialdb.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SPECIAL_DB_H
+#define SPECIAL_DB_H
+
+#include <string>
+#include <map>
+
+struct SpecialInfo
+{
+ enum TargetMode
+ {
+ TARGET_SELF = 0, // no target selection
+ TARGET_FRIEND, // target friendly being
+ TARGET_ENEMY, // target hostile being
+ TARGET_BEING, // target any being
+ TARGET_POINT // target map location
+ };
+ int id;
+ std::string set; // tab on which the special is shown
+ std::string name; // displayed name of special
+ std::string icon; // filename of graphical icon
+
+ bool isActive; // true when the special can be used
+ TargetMode targetMode; // target mode
+
+ bool hasLevel; // true when the special has levels
+ int level; // level of special when applicable
+
+ bool hasRechargeBar; // true when the special has a recharge bar
+ int rechargeNeeded; // maximum recharge when applicable
+ int rechargeCurrent; // current recharge when applicable
+};
+
+/**
+ * Special information database.
+ */
+namespace SpecialDB
+{
+ void load();
+
+ void unload();
+
+ /** gets the special info for ID. Will return 0 when it is
+ * a server-specific special.
+ */
+ SpecialInfo *get(int id);
+
+ SpecialInfo::TargetMode targetModeFromString(const std::string& str);
+}
+
+typedef std::map<int, SpecialInfo *> SpecialInfos;
+
+#endif
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
new file mode 100644
index 000000000..dddee575f
--- /dev/null
+++ b/src/resources/spritedef.cpp
@@ -0,0 +1,339 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/spritedef.h"
+
+#include "log.h"
+
+#include "resources/action.h"
+#include "resources/animation.h"
+#include "resources/dye.h"
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/resourcemanager.h"
+
+#include "configuration.h"
+
+#include "utils/xml.h"
+
+#include <set>
+
+SpriteReference *SpriteReference::Empty = new SpriteReference(
+ paths.getStringValue("spriteErrorFile"), 0);
+
+Action *SpriteDef::getAction(std::string action) const
+{
+ Actions::const_iterator i = mActions.find(action);
+
+ if (i == mActions.end())
+ {
+ logger->log("Warning: no action \"%s\" defined!", action.c_str());
+ return NULL;
+ }
+
+ return i->second;
+}
+
+SpriteDef *SpriteDef::load(const std::string &animationFile, int variant)
+{
+ std::string::size_type pos = animationFile.find('|');
+ std::string palettes;
+ if (pos != std::string::npos)
+ palettes = animationFile.substr(pos + 1);
+
+ XML::Document doc(animationFile.substr(0, pos));
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "sprite"))
+ {
+ logger->log("Error, failed to parse %s", animationFile.c_str());
+
+ std::string errorFile = paths.getStringValue("sprites")
+ + paths.getStringValue("spriteErrorFile");
+ if (animationFile != errorFile)
+ return load(errorFile, 0);
+ else
+ return NULL;
+ }
+
+ SpriteDef *def = new SpriteDef;
+ def->loadSprite(rootNode, variant, palettes);
+ def->substituteActions();
+ return def;
+}
+
+void SpriteDef::substituteAction(std::string complete, std::string with)
+{
+ if (mActions.find(complete) == mActions.end())
+ {
+ Actions::iterator i = mActions.find(with);
+ if (i != mActions.end())
+ mActions[complete] = i->second;
+ }
+}
+
+void SpriteDef::substituteActions()
+{
+ substituteAction(SpriteAction::STAND, SpriteAction::DEFAULT);
+ substituteAction(SpriteAction::MOVE, SpriteAction::STAND);
+ substituteAction(SpriteAction::ATTACK, SpriteAction::STAND);
+ substituteAction(SpriteAction::CAST_MAGIC, SpriteAction::ATTACK);
+ substituteAction(SpriteAction::USE_ITEM, SpriteAction::CAST_MAGIC);
+ substituteAction(SpriteAction::SIT, SpriteAction::STAND);
+ substituteAction(SpriteAction::SLEEP, SpriteAction::SIT);
+ substituteAction(SpriteAction::HURT, SpriteAction::STAND);
+ substituteAction(SpriteAction::DEAD, SpriteAction::HURT);
+}
+
+void SpriteDef::loadSprite(xmlNodePtr spriteNode, int variant,
+ const std::string &palettes)
+{
+ // Get the variant
+ const int variantCount = XML::getProperty(spriteNode, "variants", 0);
+ int variant_offset = 0;
+
+ if (variantCount > 0 && variant < variantCount)
+ {
+ variant_offset =
+ variant * XML::getProperty(spriteNode, "variant_offset", 0);
+ }
+
+ for_each_xml_child_node(node, spriteNode)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "imageset"))
+ loadImageSet(node, palettes);
+ else if (xmlStrEqual(node->name, BAD_CAST "action"))
+ loadAction(node, variant_offset);
+ else if (xmlStrEqual(node->name, BAD_CAST "include"))
+ includeSprite(node);
+ }
+}
+
+void SpriteDef::loadImageSet(xmlNodePtr node, const std::string &palettes)
+{
+ const std::string name = XML::getProperty(node, "name", "");
+
+ // We don't allow redefining image sets. This way, an included sprite
+ // definition will use the already loaded image set with the same name.
+ if (mImageSets.find(name) != mImageSets.end())
+ return;
+
+ const int width = XML::getProperty(node, "width", 0);
+ const int height = XML::getProperty(node, "height", 0);
+ std::string imageSrc = XML::getProperty(node, "src", "");
+ Dye::instantiate(imageSrc, palettes);
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ ImageSet *imageSet = resman->getImageSet(imageSrc, width, height);
+
+ if (!imageSet)
+ {
+ logger->log1("Couldn't load imageset!");
+ return;
+ }
+
+ mImageSets[name] = imageSet;
+}
+
+void SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
+{
+ const std::string actionName = XML::getProperty(node, "name", "");
+ const std::string imageSetName = XML::getProperty(node, "imageset", "");
+
+ ImageSetIterator si = mImageSets.find(imageSetName);
+ if (si == mImageSets.end())
+ {
+ logger->log("Warning: imageset \"%s\" not defined in %s",
+ imageSetName.c_str(), getIdPath().c_str());
+ return;
+ }
+ ImageSet *imageSet = si->second;
+
+ if (actionName == SpriteAction::INVALID)
+ {
+ logger->log("Warning: Unknown action \"%s\" defined in %s",
+ actionName.c_str(), getIdPath().c_str());
+ return;
+ }
+ Action *action = new Action;
+ mActions[actionName] = action;
+
+ // dirty hack to fix bad resources in tmw server
+ if (actionName == "attack_stab")
+ mActions["attack"] = action;
+
+ // When first action set it as default direction
+ if (mActions.size() == 1)
+ mActions[SpriteAction::DEFAULT] = action;
+
+ // Load animations
+ for_each_xml_child_node(animationNode, node)
+ {
+ if (xmlStrEqual(animationNode->name, BAD_CAST "animation"))
+ loadAnimation(animationNode, action, imageSet, variant_offset);
+ }
+}
+
+void SpriteDef::loadAnimation(xmlNodePtr animationNode,
+ Action *action, ImageSet *imageSet,
+ int variant_offset)
+{
+ if (!action || !imageSet)
+ return;
+
+ const std::string directionName =
+ XML::getProperty(animationNode, "direction", "");
+ const SpriteDirection directionType = makeSpriteDirection(directionName);
+
+ if (directionType == DIRECTION_INVALID)
+ {
+ logger->log("Warning: Unknown direction \"%s\" used in %s",
+ directionName.c_str(), getIdPath().c_str());
+ return;
+ }
+
+ Animation *animation = new Animation;
+ action->setAnimation(directionType, animation);
+
+ // Get animation frames
+ for_each_xml_child_node(frameNode, animationNode)
+ {
+ const int delay = XML::getProperty(frameNode, "delay", 0);
+ int offsetX = XML::getProperty(frameNode, "offsetX", 0);
+ int offsetY = XML::getProperty(frameNode, "offsetY", 0);
+ offsetY -= imageSet->getHeight() - 32;
+ offsetX -= imageSet->getWidth() / 2 - 16;
+
+ if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
+ {
+ const int index = XML::getProperty(frameNode, "index", -1);
+
+ if (index < 0)
+ {
+ logger->log1("No valid value for 'index'");
+ continue;
+ }
+
+ Image *img = imageSet->get(index + variant_offset);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", index + variant_offset);
+ continue;
+ }
+
+ animation->addFrame(img, delay, offsetX, offsetY);
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
+ {
+ int start = XML::getProperty(frameNode, "start", -1);
+ const int end = XML::getProperty(frameNode, "end", -1);
+
+ if (start < 0 || end < 0)
+ {
+ logger->log1("No valid value for 'start' or 'end'");
+ continue;
+ }
+
+ while (end >= start)
+ {
+ Image *img = imageSet->get(start + variant_offset);
+
+ if (!img)
+ {
+ logger->log("No image at index %d",
+ start + variant_offset);
+ start++;
+ continue;
+ }
+
+ animation->addFrame(img, delay, offsetX, offsetY);
+ start++;
+ }
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "end"))
+ {
+ animation->addTerminator();
+ }
+ } // for frameNode
+}
+
+void SpriteDef::includeSprite(xmlNodePtr includeNode)
+{
+ // TODO: Perform circular dependency check, since it's easy to crash the
+ // client this way.
+ const std::string filename = XML::getProperty(includeNode, "file", "");
+
+ if (filename.empty())
+ return;
+
+ XML::Document doc(paths.getStringValue("sprites") + filename);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "sprite"))
+ {
+ logger->log("Error, no sprite root node in %s", filename.c_str());
+ return;
+ }
+
+ loadSprite(rootNode, 0);
+}
+
+SpriteDef::~SpriteDef()
+{
+ // Actions are shared, so ensure they are deleted only once.
+ std::set< Action * > actions;
+ for (Actions::const_iterator i = mActions.begin(),
+ i_end = mActions.end(); i != i_end; ++i)
+ {
+ actions.insert(i->second);
+ }
+
+ for (std::set< Action * >::const_iterator i = actions.begin(),
+ i_end = actions.end(); i != i_end; ++i)
+ {
+ delete *i;
+ }
+
+//need actions.clear?
+
+ for (ImageSetIterator i = mImageSets.begin();
+ i != mImageSets.end(); ++i)
+ {
+ i->second->decRef();
+ }
+}
+
+SpriteDirection SpriteDef::makeSpriteDirection(const std::string &direction)
+{
+ if (direction.empty() || direction == "default")
+ return DIRECTION_DEFAULT;
+ else if (direction == "up")
+ return DIRECTION_UP;
+ else if (direction == "left")
+ return DIRECTION_LEFT;
+ else if (direction == "right")
+ return DIRECTION_RIGHT;
+ else if (direction == "down")
+ return DIRECTION_DOWN;
+ else
+ return DIRECTION_INVALID;
+}
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
new file mode 100644
index 000000000..84582c779
--- /dev/null
+++ b/src/resources/spritedef.h
@@ -0,0 +1,176 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SPRITEDEF_H
+#define SPRITEDEF_H
+
+#include "resources/resource.h"
+
+#include <libxml/tree.h>
+
+#include <list>
+#include <map>
+#include <string>
+
+class Action;
+class ImageSet;
+
+struct SpriteReference
+{
+ static SpriteReference *Empty;
+
+ SpriteReference():
+ sprite(""), variant(0)
+ {}
+
+ SpriteReference(std::string sprite, int variant)
+ { this->sprite = sprite; this->variant = variant; }
+
+ std::string sprite;
+ int variant;
+};
+
+struct SpriteDisplay
+{
+ std::string image;
+ std::list<SpriteReference*> sprites;
+ std::list<std::string> particles;
+};
+
+typedef std::list<SpriteReference*>::const_iterator SpriteRefs;
+
+/*
+ * Remember those are the main action.
+ * Action subtypes, e.g.: "attack_bow" are to be passed by items.xml after
+ * an ACTION_ATTACK call.
+ * Which special to be use to to be passed with the USE_SPECIAL call.
+ * Running, walking, ... is a sub-type of moving.
+ * ...
+ * Please don't add hard-coded subtypes here!
+ */
+namespace SpriteAction
+{
+ static const std::string DEFAULT = "stand";
+ static const std::string STAND = "stand";
+ static const std::string SIT = "sit";
+ static const std::string SLEEP = "sleep";
+ static const std::string DEAD = "dead";
+ static const std::string MOVE = "walk";
+ static const std::string ATTACK = "attack";
+ static const std::string HURT = "hurt";
+ static const std::string USE_SPECIAL = "special";
+ static const std::string CAST_MAGIC = "magic";
+ static const std::string USE_ITEM = "item";
+ static const std::string INVALID = "";
+}
+
+enum SpriteDirection
+{
+ DIRECTION_DEFAULT = 0,
+ DIRECTION_UP,
+ DIRECTION_DOWN,
+ DIRECTION_LEFT,
+ DIRECTION_RIGHT,
+ DIRECTION_INVALID
+};
+
+/**
+ * Defines a class to load an animation.
+ */
+class SpriteDef : public Resource
+{
+ public:
+ /**
+ * Loads a sprite definition file.
+ */
+ static SpriteDef *load(const std::string &file, int variant);
+
+ /**
+ * Returns the specified action.
+ */
+ Action *getAction(std::string action) const;
+
+ /**
+ * Converts a string into a SpriteDirection enum.
+ */
+ static SpriteDirection
+ makeSpriteDirection(const std::string &direction);
+
+ private:
+ /**
+ * Constructor.
+ */
+ SpriteDef() {}
+
+ /**
+ * Destructor.
+ */
+ ~SpriteDef();
+
+ /**
+ * Loads a sprite element.
+ */
+ void loadSprite(xmlNodePtr spriteNode, int variant,
+ const std::string &palettes = "");
+
+ /**
+ * Loads an imageset element.
+ */
+ void loadImageSet(xmlNodePtr node, const std::string &palettes);
+
+ /**
+ * Loads an action element.
+ */
+ void loadAction(xmlNodePtr node, int variant_offset);
+
+ /**
+ * Loads an animation element.
+ */
+ void loadAnimation(xmlNodePtr animationNode,
+ Action *action, ImageSet *imageSet,
+ int variant_offset);
+
+ /**
+ * Include another sprite into this one.
+ */
+ void includeSprite(xmlNodePtr includeNode);
+
+ /**
+ * Complete missing actions by copying existing ones.
+ */
+ void substituteActions();
+
+ /**
+ * When there are no animations defined for the action "complete", its
+ * animations become a copy of those of the action "with".
+ */
+ void substituteAction(std::string complete, std::string with);
+
+ typedef std::map<std::string, ImageSet*> ImageSets;
+ typedef ImageSets::iterator ImageSetIterator;
+
+ typedef std::map<std::string, Action*> Actions;
+
+ ImageSets mImageSets;
+ Actions mActions;
+};
+
+#endif // SPRITEDEF_H
diff --git a/src/resources/wallpaper.cpp b/src/resources/wallpaper.cpp
new file mode 100644
index 000000000..d3ccef38b
--- /dev/null
+++ b/src/resources/wallpaper.cpp
@@ -0,0 +1,172 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "resources/wallpaper.h"
+
+#include "resources/resourcemanager.h"
+#include "log.h"
+
+#include "utils/stringutils.h"
+#include "configuration.h"
+
+#include <physfs.h>
+
+#include <algorithm>
+#include <cstring>
+#include <time.h>
+#include <vector>
+
+//define WALLPAPER_FOLDER "graphics/images/"
+//define WALLPAPER_BASE "login_wallpaper.png"
+
+struct WallpaperData
+{
+ std::string filename;
+ int width;
+ int height;
+};
+
+bool wallpaperCompare(WallpaperData a, WallpaperData b);
+
+static std::vector<WallpaperData> wallpaperData;
+static bool haveBackup; // Is the backup (no size given) version available?
+
+static std::string wallpaperPath;
+static std::string wallpaperFile;
+
+// Search for the wallpaper path values sequentially..
+static void initDefaultWallpaperPaths()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ // Init the path
+ wallpaperPath = branding.getStringValue("wallpapersPath");
+
+ if (!wallpaperPath.empty() && resman->isDirectory(wallpaperPath))
+ return;
+ else
+ wallpaperPath = paths.getValue("wallpapers", "graphics/images/");
+
+ // Init the default file
+ wallpaperFile = branding.getStringValue("wallpaperFile");
+
+ if (!wallpaperFile.empty())
+ return;
+ else
+ wallpaperFile = paths.getValue("wallpaperFile", "login_wallpaper.png");
+}
+
+bool wallpaperCompare(WallpaperData a, WallpaperData b)
+{
+ int aa = a.width * a.height;
+ int ab = b.width * b.height;
+
+ return (aa > ab || (aa == ab && a.width > b.width));
+}
+#include <iostream>
+void Wallpaper::loadWallpapers()
+{
+ wallpaperData.clear();
+
+ initDefaultWallpaperPaths();
+
+ char **imgs = PHYSFS_enumerateFiles(wallpaperPath.c_str());
+
+ for (char **i = imgs; *i != NULL; i++)
+ {
+ int width;
+ int height;
+
+ // If the backup file is found, we tell it.
+ if (strncmp (*i, wallpaperFile.c_str(), strlen(*i)) == 0)
+ haveBackup = true;
+
+ // If the image format is terminated by: "_<width>x<height>.png"
+ // It is taken as a potential wallpaper.
+
+ // First, get the base filename of the image:
+ std::string filename = *i;
+ unsigned long separator = filename.rfind("_");
+ filename = filename.substr(0, separator);
+
+ // Check that the base filename doesn't have any '%' markers.
+ separator = filename.find("%");
+ if (separator == std::string::npos)
+ {
+ // Then, append the width and height search mask.
+ filename.append("_%dx%d.png");
+
+ if (sscanf(*i, filename.c_str(), &width, &height) == 2)
+ {
+ WallpaperData wp;
+ wp.filename = wallpaperPath;
+ wp.filename.append(*i);
+ wp.width = width;
+ wp.height = height;
+ wallpaperData.push_back(wp);
+ }
+ }
+ }
+
+ PHYSFS_freeList(imgs);
+
+ std::sort(wallpaperData.begin(), wallpaperData.end(), wallpaperCompare);
+}
+
+std::string Wallpaper::getWallpaper(int width, int height)
+{
+ std::vector<WallpaperData>::iterator iter;
+ WallpaperData wp;
+
+ // Wallpaper filename container
+ std::vector<std::string> wallPaperVector;
+
+ for (iter = wallpaperData.begin(); iter != wallpaperData.end(); iter++)
+ {
+ wp = *iter;
+ if (wp.width <= width && wp.height <= height)
+ wallPaperVector.push_back(wp.filename);
+ }
+
+ if (!wallPaperVector.empty())
+ {
+ // If we've got more than one occurence of a valid wallpaper...
+ if (wallPaperVector.size() > 0)
+ {
+ // Return randomly a wallpaper between vector[0] and
+ // vector[vector.size() - 1]
+ srand((unsigned) time(0));
+ return wallPaperVector[int(static_cast<double>(
+ wallPaperVector.size()) * rand() / (RAND_MAX + 1.0))];
+ }
+ else // If there at least one, we return it
+ {
+ return wallPaperVector[0];
+ }
+ }
+
+ // Return the backup file if everything else failed...
+ if (haveBackup)
+ return std::string(wallpaperPath + wallpaperFile);
+
+ // Return an empty string if everything else failed
+ return std::string();
+}
diff --git a/src/resources/wallpaper.h b/src/resources/wallpaper.h
new file mode 100644
index 000000000..bb640d1ef
--- /dev/null
+++ b/src/resources/wallpaper.h
@@ -0,0 +1,50 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef WALLPAPER_H
+#define WALLPAPER_H
+
+#include <string>
+
+/**
+ * Handles organizing and choosing of wallpapers.
+ */
+class Wallpaper
+{
+ public:
+ /**
+ * Reads the folder that contains wallpapers and organizes the
+ * wallpapers found by area, width, and height.
+ */
+ static void loadWallpapers();
+
+ /**
+ * Returns the largest wallpaper for the given resolution, or the
+ * default wallpaper if none are found.
+ *
+ * @param width the desired width
+ * @param height the desired height
+ * @return the file to use, or empty if no wallpapers are useable
+ */
+ static std::string getWallpaper(int width, int height);
+};
+
+#endif // WALLPAPER_H
diff --git a/src/rotationalparticle.cpp b/src/rotationalparticle.cpp
new file mode 100644
index 000000000..1e0ae9618
--- /dev/null
+++ b/src/rotationalparticle.cpp
@@ -0,0 +1,82 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "rotationalparticle.h"
+#include "graphics.h"
+#include "simpleanimation.h"
+
+#define PI 3.14159265
+
+RotationalParticle::RotationalParticle(Map *map, Animation *animation):
+ ImageParticle(map, NULL),
+ mAnimation(new SimpleAnimation(animation))
+{
+}
+
+RotationalParticle::RotationalParticle(Map *map, xmlNodePtr animationNode):
+ ImageParticle(map, 0),
+ mAnimation(new SimpleAnimation(animationNode))
+{
+}
+
+RotationalParticle::~RotationalParticle()
+{
+ delete mAnimation;
+ mAnimation = 0;
+ mImage = 0;
+}
+
+bool RotationalParticle::update()
+{
+ if (!mAnimation)
+ return false;
+
+ // TODO: cache velocities to avoid spamming atan2()
+
+ float rad = static_cast<float>(atan2(mVelocity.x, mVelocity.y));
+ if (rad < 0)
+ rad = static_cast<float>(PI + (PI + rad));
+ int size = mAnimation->getLength();
+
+ float range = static_cast<float>(PI / size);
+
+ // Determines which frame the particle should play
+ if (rad < range || rad > ((PI*2) - range))
+ {
+ mAnimation->setFrame(0);
+ }
+ else
+ {
+ for (int c = 1; c < size; c++)
+ {
+ if (((static_cast<float>(c) * (2 * range)) - range) < rad
+ && rad < ((static_cast<float>(c) * (2 * range)) + range))
+ {
+ mAnimation->setFrame(c);
+ break;
+ }
+ }
+ }
+
+ mImage = mAnimation->getCurrentImage();
+
+ return Particle::update();
+}
diff --git a/src/rotationalparticle.h b/src/rotationalparticle.h
new file mode 100644
index 000000000..535cfb58a
--- /dev/null
+++ b/src/rotationalparticle.h
@@ -0,0 +1,48 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef ROTATIONAL_PARTICLE_H
+#define ROTATIONAL_PARTICLE_H
+
+#include "imageparticle.h"
+
+#include <libxml/tree.h>
+
+class Animation;
+class Map;
+class SimpleAnimation;
+
+class RotationalParticle : public ImageParticle
+{
+ public:
+ RotationalParticle(Map *map, Animation *animation);
+
+ RotationalParticle(Map *map, xmlNodePtr animationNode);
+
+ ~RotationalParticle();
+
+ virtual bool update();
+
+ private:
+ SimpleAnimation *mAnimation; /**< Used animation for this particle */
+};
+
+#endif
diff --git a/src/shopitem.cpp b/src/shopitem.cpp
new file mode 100644
index 000000000..56fec1fac
--- /dev/null
+++ b/src/shopitem.cpp
@@ -0,0 +1,95 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "shopitem.h"
+
+#include "units.h"
+
+#include "utils/stringutils.h"
+
+#include "resources/iteminfo.h"
+
+ShopItem::ShopItem(int inventoryIndex, int id,
+ int quantity, int price) :
+ Item(id, 0),
+ mPrice(price)
+{
+ mDisplayName = getInfo().getName() + " ("
+ + Units::formatCurrency(mPrice).c_str() + ") ";
+ if (quantity > 0)
+ mDisplayName += "[" + toString(quantity) + "]";
+
+ setInvIndex(inventoryIndex);
+ addDuplicate(inventoryIndex, quantity);
+}
+
+ShopItem::ShopItem (int id, int price) : Item (id, 0), mPrice(price)
+{
+ mDisplayName = getInfo().getName() +
+ " (" + Units::formatCurrency(mPrice).c_str() + ")";
+ setInvIndex(-1);
+ addDuplicate(-1, 0);
+}
+
+ShopItem::~ShopItem()
+{
+ /** Clear all remaining duplicates on Object destruction. */
+ while (!mDuplicates.empty())
+ {
+ delete mDuplicates.top();
+ mDuplicates.pop();
+ }
+}
+
+void ShopItem::addDuplicate(int inventoryIndex, int quantity)
+{
+ DuplicateItem* di = new DuplicateItem;
+ di->inventoryIndex = inventoryIndex;
+ di->quantity = quantity;
+ mDuplicates.push(di);
+ mQuantity += quantity;
+}
+
+void ShopItem::addDuplicate()
+{
+ DuplicateItem* di = new DuplicateItem;
+ di->inventoryIndex = -1;
+ di->quantity = 0;
+ mDuplicates.push(di);
+}
+
+int ShopItem::sellCurrentDuplicate(int quantity)
+{
+ DuplicateItem* dupl = mDuplicates.top();
+ if (!dupl)
+ return 0;
+
+ int sellCount = quantity <= dupl->quantity ? quantity : dupl->quantity;
+ dupl->quantity -= sellCount;
+ mQuantity -= sellCount;
+ if (dupl->quantity == 0)
+ {
+ delete dupl;
+ dupl = 0;
+ mDuplicates.pop();
+ }
+ return sellCount;
+}
diff --git a/src/shopitem.h b/src/shopitem.h
new file mode 100644
index 000000000..04d26df8f
--- /dev/null
+++ b/src/shopitem.h
@@ -0,0 +1,140 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef _SHOPITEM_H
+#define _SHOPITEM_H
+
+#include "item.h"
+
+#include <stack>
+
+/**
+ * Represents an item in a shop inventory. It can store quantity and inventory
+ * indices of duplicate entries in the shop as well.
+ */
+class ShopItem : public Item
+{
+ public:
+ /**
+ * Constructor. Creates a new ShopItem.
+ *
+ * @param inventoryIndex the inventory index of the item
+ * @param id the id of the item
+ * @param quantity number of available copies of the item
+ * @param price price of the item
+ */
+ ShopItem(int inventoryIndex, int id, int quantity, int price);
+
+ /**
+ * Constructor. Creates a new ShopItem. Inventory index will be set to
+ * -1 and quantity to 0.
+ *
+ * @param id the id of the item
+ * @param price price of the item
+ */
+ ShopItem(int id, int price);
+
+ /**
+ * Destructor.
+ */
+ ~ShopItem();
+
+ /**
+ * Add a duplicate. Id and price will be taken from this item.
+ *
+ * @param inventoryIndex the inventory index of the item
+ * @param quantity number of available copies of the item
+ */
+ void addDuplicate(int inventoryIndex, int quantity);
+
+ /**
+ * Add a duplicate. Id and price will be taken from this item.
+ * Needed for compatibility with ShopDuplicateItems (see) class
+ * documentation).
+ */
+ void addDuplicate();
+
+ /**
+ * Gets the quantity of the currently topmost duplicate.
+ *
+ * @return the quantity of the currently topmost duplicate
+ */
+ int getCurrentQuantity() const
+ {
+ return mDuplicates.empty() ? 0 : mDuplicates.top()->quantity;
+ }
+
+ /**
+ * Gets the inventory index of the currently topmost duplicate.
+ *
+ * @return the inventory index of the currently topmost duplicate
+ */
+ int getCurrentInvIndex() const
+ {
+ return mDuplicates.empty() ? mInvIndex :
+ mDuplicates.top()->inventoryIndex;
+ }
+
+ /**
+ * Reduces the quantity of the topmost duplicate by the specified
+ * amount. Also reduces the total quantity of this DuplicateItem.
+ * Empty duplicates are automatically removed.
+ *
+ * If the amount is bigger than the quantity of the current topmost,
+ * only sell as much as possible. Returns the amount actually sold (do
+ * not ignore the return value!)
+ *
+ * @return the amount, that actually was sold.
+ */
+ int sellCurrentDuplicate(int quantity);
+
+ /**
+ * Gets the price of the item.
+ *
+ * @return the price of the item
+ */
+ int getPrice() const
+ { return mPrice; }
+
+ /**
+ * Gets the display name for the item in the shop list.
+ *
+ * @return the display name for the item in the shop list
+ */
+ const std::string &getDisplayName() const
+ { return mDisplayName; }
+
+ protected:
+ int mPrice;
+ std::string mDisplayName;
+
+ /**
+ * Struct to keep track of duplicates.
+ */
+ typedef struct
+ {
+ int inventoryIndex;
+ int quantity;
+ } DuplicateItem;
+ std::stack<DuplicateItem*> mDuplicates; /** <-- Stores duplicates */
+};
+
+#endif
diff --git a/src/simpleanimation.cpp b/src/simpleanimation.cpp
new file mode 100644
index 000000000..154da1e40
--- /dev/null
+++ b/src/simpleanimation.cpp
@@ -0,0 +1,212 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "simpleanimation.h"
+
+#include "graphics.h"
+#include "log.h"
+
+#include "utils/stringutils.h"
+
+#include "resources/animation.h"
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/resourcemanager.h"
+
+SimpleAnimation::SimpleAnimation(Animation *animation):
+ mAnimation(animation),
+ mAnimationTime(0),
+ mAnimationPhase(0),
+ mCurrentFrame(mAnimation->getFrame(0)),
+ mInitialized(true)
+{
+}
+
+SimpleAnimation::SimpleAnimation(xmlNodePtr animationNode):
+ mAnimation(new Animation),
+ mAnimationTime(0),
+ mAnimationPhase(0),
+ mInitialized(false)
+{
+ initializeAnimation(animationNode);
+ if (mAnimation)
+ mCurrentFrame = mAnimation->getFrame(0);
+ else
+ mCurrentFrame = 0;
+}
+
+SimpleAnimation::~SimpleAnimation()
+{
+ delete mAnimation;
+ mAnimation = 0;
+}
+
+bool SimpleAnimation::draw(Graphics *graphics, int posX, int posY) const
+{
+ if (!mCurrentFrame || !mCurrentFrame->image)
+ return false;
+
+ return graphics->drawImage(mCurrentFrame->image,
+ posX + mCurrentFrame->offsetX,
+ posY + mCurrentFrame->offsetY);
+}
+
+void SimpleAnimation::reset()
+{
+ mAnimationTime = 0;
+ mAnimationPhase = 0;
+}
+
+void SimpleAnimation::setFrame(int frame)
+{
+ if (!mAnimation)
+ return;
+
+ if (frame < 0)
+ frame = 0;
+ if ((unsigned)frame >= mAnimation->getLength())
+ frame = mAnimation->getLength() - 1;
+ mAnimationPhase = frame;
+ mCurrentFrame = mAnimation->getFrame(mAnimationPhase);
+}
+
+void SimpleAnimation::update(int timePassed)
+{
+ if (!mCurrentFrame || !mAnimation)
+ return;
+
+ if (mInitialized && mAnimation)
+ {
+ mAnimationTime += timePassed;
+
+ while (mAnimationTime > mCurrentFrame->delay
+ && mCurrentFrame->delay > 0)
+ {
+ mAnimationTime -= mCurrentFrame->delay;
+ mAnimationPhase++;
+
+ if ((unsigned)mAnimationPhase >= mAnimation->getLength())
+ mAnimationPhase = 0;
+
+ mCurrentFrame = mAnimation->getFrame(mAnimationPhase);
+ }
+ }
+
+}
+
+int SimpleAnimation::getLength() const
+{
+ if (!mAnimation)
+ return 0;
+
+ return mAnimation->getLength();
+}
+
+Image *SimpleAnimation::getCurrentImage() const
+{
+ if (mCurrentFrame)
+ return mCurrentFrame->image;
+ else
+ return NULL;
+}
+
+void SimpleAnimation::initializeAnimation(xmlNodePtr animationNode)
+{
+ mInitialized = false;
+
+ if (!animationNode)
+ return;
+
+ ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
+ XML::getProperty(animationNode, "imageset", ""),
+ XML::getProperty(animationNode, "width", 0),
+ XML::getProperty(animationNode, "height", 0)
+ );
+
+ if (!imageset)
+ return;
+
+ // Get animation frames
+ for (xmlNodePtr frameNode = animationNode->xmlChildrenNode;
+ frameNode; frameNode = frameNode->next)
+ {
+ int delay = XML::getProperty(frameNode, "delay", 0);
+ int offsetX = XML::getProperty(frameNode, "offsetX", 0);
+ int offsetY = XML::getProperty(frameNode, "offsetY", 0);
+ offsetY -= imageset->getHeight() - 32;
+ offsetX -= imageset->getWidth() / 2 - 16;
+
+ if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
+ {
+ int index = XML::getProperty(frameNode, "index", -1);
+
+ if (index < 0)
+ {
+ logger->log1("No valid value for 'index'");
+ continue;
+ }
+
+ Image *img = imageset->get(index);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", index);
+ continue;
+ }
+
+ if (mAnimation)
+ mAnimation->addFrame(img, delay, offsetX, offsetY);
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
+ {
+ int start = XML::getProperty(frameNode, "start", -1);
+ int end = XML::getProperty(frameNode, "end", -1);
+
+ if (start < 0 || end < 0)
+ {
+ logger->log1("No valid value for 'start' or 'end'");
+ continue;
+ }
+
+ while (end >= start)
+ {
+ Image *img = imageset->get(start);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", start);
+ continue;
+ }
+
+ if (mAnimation)
+ mAnimation->addFrame(img, delay, offsetX, offsetY);
+ start++;
+ }
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "end"))
+ {
+ if (mAnimation)
+ mAnimation->addTerminator();
+ }
+ }
+
+ mInitialized = true;
+}
diff --git a/src/simpleanimation.h b/src/simpleanimation.h
new file mode 100644
index 000000000..e679442e4
--- /dev/null
+++ b/src/simpleanimation.h
@@ -0,0 +1,86 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SIMPLEANIMAION_H
+#define SIMPLEANIMAION_H
+
+#include "utils/xml.h"
+
+class Animation;
+class Frame;
+class Graphics;
+class Image;
+
+/**
+ * This class is a leightweight alternative to the AnimatedSprite class.
+ * It hosts a looping animation without actions and directions.
+ */
+class SimpleAnimation
+{
+ public:
+ /**
+ * Creates a simple animation with an already created \a animation.
+ * Takes ownership over the given animation.
+ */
+ SimpleAnimation(Animation *animation);
+
+ /**
+ * Creates a simple animation that creates its animation from XML Data.
+ */
+ SimpleAnimation(xmlNodePtr animationNode);
+
+ ~SimpleAnimation();
+
+ void setFrame(int frame);
+
+ int getLength() const;
+
+ void update(int timePassed);
+
+ bool draw(Graphics *graphics, int posX, int posY) const;
+
+ /**
+ * Resets the animation.
+ */
+ void reset();
+
+ Image *getCurrentImage() const;
+
+ private:
+ void initializeAnimation(xmlNodePtr animationNode);
+
+ /** The hosted animation. */
+ Animation *mAnimation;
+
+ /** Time in game ticks the current frame is shown. */
+ int mAnimationTime;
+
+ /** Index of current animation phase. */
+ int mAnimationPhase;
+
+ /** Current animation phase. */
+ Frame *mCurrentFrame;
+
+ /** Tell whether the animation is ready */
+ bool mInitialized;
+};
+
+#endif
diff --git a/src/sound.cpp b/src/sound.cpp
new file mode 100644
index 000000000..8742ce361
--- /dev/null
+++ b/src/sound.cpp
@@ -0,0 +1,344 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <SDL.h>
+
+#include "configuration.h"
+#include "log.h"
+#include "sound.h"
+
+#include "resources/resourcemanager.h"
+#include "resources/soundeffect.h"
+
+#include "configuration.h"
+
+Sound::Sound():
+ mInstalled(false),
+ mSfxVolume(100),
+ mMusicVolume(60),
+ mMusic(0),
+ mPlayBattle(false),
+ mPlayGui(false),
+ mPlayMusic(false)
+{
+}
+
+Sound::~Sound()
+{
+ config.removeListener("playBattleSound", this);
+ config.removeListener("playGuiSound", this);
+ config.removeListener("playMusic", this);
+}
+
+void Sound::optionChanged(const std::string &value)
+{
+ if (value == "playBattleSound")
+ mPlayBattle = config.getBoolValue("playBattleSound");
+ else if (value == "playGuiSound")
+ mPlayGui = config.getBoolValue("playGuiSound");
+ else if (value == "playMusic")
+ mPlayMusic = config.getBoolValue("playMusic");
+}
+
+void Sound::init()
+{
+ // Don't initialize sound engine twice
+ if (mInstalled)
+ return;
+
+ logger->log1("Sound::init() Initializing sound...");
+
+ mPlayBattle = config.getBoolValue("playBattleSound");
+ mPlayGui = config.getBoolValue("playGuiSound");
+ mPlayMusic = config.getBoolValue("playMusic");
+ config.addListener("playBattleSound", this);
+ config.addListener("playGuiSound", this);
+ config.addListener("playMusic", this);
+
+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1)
+ {
+ logger->log1("Sound::init() Failed to initialize audio subsystem");
+ return;
+ }
+
+ const size_t audioBuffer = 4096;
+
+ const int res = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
+ MIX_DEFAULT_CHANNELS, audioBuffer);
+ if (res < 0)
+ {
+ logger->log("Sound::init Could not initialize audio: %s",
+ Mix_GetError());
+ return;
+ }
+
+ Mix_AllocateChannels(16);
+ Mix_VolumeMusic(mMusicVolume);
+ Mix_Volume(-1, mSfxVolume);
+
+ info();
+
+ mInstalled = true;
+
+ if (!mCurrentMusicFile.empty() && mPlayMusic)
+ playMusic(mCurrentMusicFile);
+}
+
+void Sound::info()
+{
+ SDL_version compiledVersion;
+ const SDL_version *linkedVersion;
+ char driver[40] = "Unknown";
+ const char *format = "Unknown";
+ int rate = 0;
+ Uint16 audioFormat = 0;
+ int channels = 0;
+
+ MIX_VERSION(&compiledVersion);
+ linkedVersion = Mix_Linked_Version();
+
+ SDL_AudioDriverName(driver, 40);
+
+ Mix_QuerySpec(&rate, &audioFormat, &channels);
+ switch (audioFormat)
+ {
+ case AUDIO_U8: format = "U8"; break;
+ case AUDIO_S8: format = "S8"; break;
+ case AUDIO_U16LSB: format = "U16LSB"; break;
+ case AUDIO_S16LSB: format = "S16LSB"; break;
+ case AUDIO_U16MSB: format = "U16MSB"; break;
+ case AUDIO_S16MSB: format = "S16MSB"; break;
+ default: break;
+ }
+
+ logger->log("Sound::info() SDL_mixer: %i.%i.%i (compiled)",
+ compiledVersion.major,
+ compiledVersion.minor,
+ compiledVersion.patch);
+ logger->log("Sound::info() SDL_mixer: %i.%i.%i (linked)",
+ linkedVersion->major,
+ linkedVersion->minor,
+ linkedVersion->patch);
+ logger->log("Sound::info() Driver: %s", driver);
+ logger->log("Sound::info() Format: %s", format);
+ logger->log("Sound::info() Rate: %i", rate);
+ logger->log("Sound::info() Channels: %i", channels);
+}
+
+int Sound::getMaxVolume() const
+{
+ return MIX_MAX_VOLUME;
+}
+
+void Sound::setMusicVolume(int volume)
+{
+ mMusicVolume = volume;
+
+ if (mInstalled)
+ Mix_VolumeMusic(mMusicVolume);
+}
+
+void Sound::setSfxVolume(int volume)
+{
+ mSfxVolume = volume;
+
+ if (mInstalled)
+ Mix_Volume(-1, mSfxVolume);
+}
+
+static Mix_Music *loadMusic(const std::string &filename)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ std::string path = resman->getPath(
+ paths.getStringValue("music") + filename);
+
+ if (path.find(".zip/") != std::string::npos ||
+ path.find(".zip\\") != std::string::npos)
+ {
+ // Music file is a virtual file inside a zip archive - we have to copy
+ // it to a temporary physical file so that SDL_mixer can stream it.
+ logger->log("Loading music \"%s\" from temporary file tempMusic.ogg",
+ path.c_str());
+ bool success = resman->copyFile(paths.getStringValue("music")
+ + filename, "tempMusic.ogg");
+ if (success)
+ path = resman->getPath("tempMusic.ogg");
+ else
+ return NULL;
+ }
+ else
+ {
+ logger->log("Loading music \"%s\"", path.c_str());
+ }
+
+ if (path.empty())
+ return 0;
+
+ Mix_Music *music = Mix_LoadMUS(path.c_str());
+
+ if (!music)
+ {
+ logger->log("Mix_LoadMUS() Error loading '%s': %s", path.c_str(),
+ Mix_GetError());
+ }
+
+ return music;
+}
+
+void Sound::playMusic(const std::string &filename)
+{
+ mCurrentMusicFile = filename;
+
+ if (!mInstalled || !mPlayMusic)
+ return;
+
+ haltMusic();
+
+ if ((mMusic = loadMusic(filename)))
+ Mix_PlayMusic(mMusic, -1); // Loop forever
+}
+
+void Sound::stopMusic()
+{
+ if (!mInstalled)
+ return;
+
+ logger->log1("Sound::stopMusic()");
+
+ if (mMusic)
+ {
+ Mix_HaltMusic();
+ Mix_FreeMusic(mMusic);
+ mMusic = NULL;
+ }
+}
+
+void Sound::fadeInMusic(const std::string &path, int ms)
+{
+ mCurrentMusicFile = path;
+
+ if (!mInstalled || !mPlayMusic)
+ return;
+
+ haltMusic();
+
+ if ((mMusic = loadMusic(path.c_str())))
+ Mix_FadeInMusic(mMusic, -1, ms); // Loop forever
+}
+
+void Sound::fadeOutMusic(int ms)
+{
+ mCurrentMusicFile.clear();
+
+ if (!mInstalled)
+ return;
+
+ logger->log("Sound::fadeOutMusic() Fading-out (%i ms)", ms);
+
+ if (mMusic)
+ {
+ Mix_FadeOutMusic(ms);
+ Mix_FreeMusic(mMusic);
+ mMusic = NULL;
+ }
+}
+
+void Sound::playSfx(const std::string &path)
+{
+ if (!mInstalled || path.empty() || !mPlayBattle)
+ return;
+
+ std::string tmpPath;
+ if (!path.find("sfx/"))
+ tmpPath = path;
+ else
+ tmpPath = paths.getValue("sfx", "sfx/") + path;
+ ResourceManager *resman = ResourceManager::getInstance();
+ SoundEffect *sample = resman->getSoundEffect(tmpPath);
+ if (sample)
+ {
+ logger->log("Sound::playSfx() Playing: %s", path.c_str());
+ sample->play(0, 120);
+ }
+}
+
+void Sound::playGuiSfx(const std::string &path)
+{
+ if (!mInstalled || path.empty() || !mPlayGui)
+ return;
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ SoundEffect *sample = resman->getSoundEffect(
+ paths.getStringValue("sfx") + path);
+ if (sample)
+ {
+ logger->log("Sound::playSfx() Playing: %s", path.c_str());
+ sample->play(0, 120);
+ }
+}
+
+void Sound::close()
+{
+ if (!mInstalled)
+ return;
+
+ haltMusic();
+ logger->log1("Sound::close() Shutting down sound...");
+ Mix_CloseAudio();
+
+ mInstalled = false;
+}
+
+void Sound::haltMusic()
+{
+ if (!mMusic)
+ return;
+
+ Mix_HaltMusic();
+ Mix_FreeMusic(mMusic);
+ mMusic = NULL;
+}
+
+void Sound::changeAudio()
+{
+ if (mInstalled)
+ close();
+ else
+ init();
+}
+
+void Sound::volumeOff()
+{
+ if (mInstalled)
+ {
+ Mix_VolumeMusic(0);
+ Mix_Volume(-1, 0);
+ }
+}
+
+void Sound::volumeRestore()
+{
+ if (mInstalled)
+ {
+ Mix_VolumeMusic(mMusicVolume);
+ Mix_Volume(-1, mSfxVolume);
+ }
+}
diff --git a/src/sound.h b/src/sound.h
new file mode 100644
index 000000000..100c228c1
--- /dev/null
+++ b/src/sound.h
@@ -0,0 +1,130 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SOUND_H
+#define SOUND_H
+
+#ifdef __APPLE__
+#include <SDL_mixer/SDL_mixer.h>
+#else
+#include <SDL_mixer.h>
+#endif
+
+#include "configlistener.h"
+
+#include <string>
+
+/** Sound engine
+ *
+ * \ingroup CORE
+ */
+class Sound : public ConfigListener
+{
+ public:
+ Sound();
+ ~Sound();
+
+ void optionChanged(const std::string &value);
+
+ /**
+ * Installs the sound engine.
+ */
+ void init();
+
+ /**
+ * Removes all sound functionalities.
+ */
+ void close();
+
+ /**
+ * Starts background music.
+ *
+ * @param path The full path to the music file.
+ */
+ void playMusic(const std::string &path);
+
+ /**
+ * Stops currently running background music track.
+ */
+ void stopMusic();
+
+ /**
+ * Fades in background music.
+ *
+ * @param path The full path to the music file.
+ * @param ms Duration of fade-in effect (ms)
+ */
+ void fadeInMusic(const std::string &path, int ms = 2000);
+
+ /**
+ * Fades out currently running background music track.
+ *
+ * @param ms Duration of fade-out effect (ms)
+ */
+ void fadeOutMusic(int ms);
+
+ int getMaxVolume() const;
+
+ void setMusicVolume(int volume);
+ void setSfxVolume(int volume);
+
+ /**
+ * Plays an item.
+ *
+ * @param path The resource path to the sound file.
+ */
+ void playSfx(const std::string &path);
+
+ /**
+ * Plays an item for gui.
+ *
+ * @param path The resource path to the sound file.
+ */
+ void playGuiSfx(const std::string &path);
+
+ void changeAudio();
+
+ void volumeOff();
+
+ void volumeRestore();
+
+ private:
+ /** Logs various info about sound device. */
+ void info();
+
+ /** Halts and frees currently playing music. */
+ void haltMusic();
+
+ bool mInstalled;
+
+ int mSfxVolume;
+ int mMusicVolume;
+
+ std::string mCurrentMusicFile;
+ Mix_Music *mMusic;
+ bool mPlayBattle;
+ bool mPlayGui;
+ bool mPlayMusic;
+};
+
+extern Sound sound;
+
+#endif
diff --git a/src/spellmanager.cpp b/src/spellmanager.cpp
new file mode 100644
index 000000000..2f4e7bd26
--- /dev/null
+++ b/src/spellmanager.cpp
@@ -0,0 +1,346 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "spellmanager.h"
+
+#include "being.h"
+#include "configuration.h"
+#include "log.h"
+#include "localplayer.h"
+#include "playerinfo.h"
+
+#include "gui/chat.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+
+#include "utils/dtor.h"
+#include "utils/stringutils.h"
+
+SpellManager::SpellManager()
+{
+ //fillSpells();
+ load();
+}
+
+SpellManager::~SpellManager()
+{
+ delete_all(mSpells);
+ mSpells.clear();
+ mSpellsVector.clear();
+// save();
+}
+
+TextCommand* SpellManager::getSpell(int spellId)
+{
+ if (spellId < 0 || (unsigned int)spellId >= mSpells.size())
+ return NULL;
+
+ return mSpells[spellId];
+}
+
+TextCommand* SpellManager::getSpellByItem(int itemId)
+{
+ return getSpell(itemId - SPELL_MIN_ID);
+}
+
+void SpellManager::fillSpells()
+{
+//id, std::string name, std::string symbol, ST type, int basicLvl, MagicSchool school, int schoolLvl, int mana)
+
+ addSpell(new TextCommand(0, "lum", "#lum", ALLOWTARGET,
+ "", 1, SKILL_MAGIC_LIFE, 0, 6));
+ addSpell(new TextCommand(1, "inm", "#inma", NEEDTARGET,
+ "", 2, SKILL_MAGIC_LIFE, 2, 10));
+ addSpell(new TextCommand(2, "fla", "#flar", NOTARGET,
+ "", 1, SKILL_MAGIC_WAR, 0, 10));
+ addSpell(new TextCommand(3, "chi", "#chiza", NOTARGET,
+ "", 1, SKILL_MAGIC_WAR, 0, 9));
+ addSpell(new TextCommand(4, "ing", "#ingrav", NOTARGET,
+ "", 2, SKILL_MAGIC_WAR, 2, 20));
+ addSpell(new TextCommand(5, "fri", "#frillyar", NOTARGET,
+ "", 2, SKILL_MAGIC_WAR, 2, 25));
+ addSpell(new TextCommand(6, "upm", "#upmarmu", NOTARGET,
+ "", 2, SKILL_MAGIC_WAR, 2, 20));
+ addSpell(new TextCommand(7, "ite", "#itenplz", NOTARGET,
+ "", 1, SKILL_MAGIC_NATURE, 0, 3));
+ addSpell(new TextCommand(8, "bet", "#betsanc", ALLOWTARGET,
+ "", 2, SKILL_MAGIC_NATURE, 2, 14));
+ addSpell(new TextCommand(9, "abi", "#abizit", NOTARGET,
+ "", 1, SKILL_MAGIC, 0, 1));
+ addSpell(new TextCommand(10, "inw", "#inwilt", NOTARGET,
+ "", 2, SKILL_MAGIC, 2, 7));
+ addSpell(new TextCommand(11, "hi", "hi", NOTARGET, ""));
+ addSpell(new TextCommand(12, "hea", "heal", NOTARGET, ""));
+ addSpell(new TextCommand(13, "@sp", "@spawn maggot 10", NOTARGET, ""));
+ for (int f = 12; f < SPELL_SHORTCUT_ITEMS; f++)
+ addSpell(new TextCommand(f));
+}
+
+bool SpellManager::addSpell(TextCommand *spell)
+{
+ if (!spell)
+ return false;
+
+ std::map<unsigned int, TextCommand*>::iterator
+ i = mSpells.find(spell->getId());
+ if (i == mSpells.end())
+ {
+ mSpells[spell->getId()] = spell;
+ mSpellsVector.push_back(spell);
+ return true;
+ }
+ return false;
+}
+
+std::vector<TextCommand*> SpellManager::getAll()
+{
+ //logger->log(("mSpellsVector = " + toString(mSpellsVector.size())).c_str());
+ return mSpellsVector;
+}
+
+void SpellManager::useItem(int itemId)
+{
+ invoke(itemId - SPELL_MIN_ID);
+}
+
+void SpellManager::invoke(int spellId)
+{
+ if (!player_node)
+ return;
+
+ TextCommand* spell = getSpell(spellId);
+ if (!spell)
+ return;
+
+ if (spell->getCommand() == "")
+ return;
+
+ if (spell->getCommandType() == TEXT_COMMAND_TEXT
+ || (Net::getPlayerHandler()->canUseMagic()
+ && PlayerInfo::getStatEffective(SKILL_MAGIC) >= spell->getBaseLvl()
+ && PlayerInfo::getStatEffective(
+ spell->getSchool()) >= spell->getSchoolLvl()
+ && PlayerInfo::getAttribute(MP) >= spell->getMana()))
+ {
+ Being* target = player_node->getTarget();
+ if (spell->getTargetType() == NOTARGET)
+ {
+ invokeSpell(spell);
+ }
+ if ((target && (target->getType() != Being::MONSTER
+ || spell->getCommandType() == TEXT_COMMAND_TEXT))
+ && (spell->getTargetType() == ALLOWTARGET
+ || spell->getTargetType() == NEEDTARGET))
+ {
+ invokeSpell(spell, target);
+ }
+ else if (spell->getTargetType() == ALLOWTARGET)
+ {
+ invokeSpell(spell);
+ }
+ }
+}
+
+void SpellManager::invokeSpell(TextCommand* spell) const
+{
+ if (!chatWindow || !spell)
+ return;
+ chatWindow->localChatInput(parseCommand(spell->getCommand(), 0));
+}
+
+void SpellManager::invokeSpell(TextCommand* spell, Being* target) const
+{
+ if (!chatWindow || !spell || !target)
+ return;
+ chatWindow->localChatInput(parseCommand(spell->getCommand(), target));
+}
+
+std::string SpellManager::parseCommand(std::string command,
+ Being *target) const
+{
+ if (!player_node)
+ return command;
+
+ std::string name = "";
+ std::string id = "";
+ std::string name2;
+
+ if (target)
+ {
+ name = target->getName();
+ name2 = target->getName();
+ id = toString(target->getId());
+ }
+ else
+ {
+ name2 = player_node->getName();
+ }
+
+ bool found = false;
+
+ int idx = command.find("<TARGET>");
+ if (idx >= 0)
+ {
+ found = true;
+ command = replaceAll(command, "<TARGET>", name);
+ }
+ idx = command.find("<TARGETID>");
+ if (idx >= 0)
+ {
+ found = true;
+ command = replaceAll(command, "<TARGETID>", id);
+ }
+ idx = command.find("<TARGETORSELF>");
+ if (idx >= 0)
+ {
+ found = true;
+ command = replaceAll(command, "<TARGETORSELF>", name2);
+ }
+
+ if (!found && !name.empty())
+ command += " " + name;
+
+ return command;
+}
+
+TextCommand *SpellManager::createNewSpell()
+{
+ return new TextCommand(static_cast<unsigned>(mSpellsVector.size()));
+}
+
+void SpellManager::load(bool oldConfig)
+{
+ Configuration *cfg;
+ if (oldConfig)
+ cfg = &config;
+ else
+ cfg = &serverConfig;
+
+ delete_all(mSpells);
+ mSpells.clear();
+ mSpellsVector.clear();
+
+ if (cfg->getValue("commandShortcutFlags0", "") == "")
+ {
+ fillSpells();
+ save();
+ return;
+ }
+
+ unsigned int targetType;
+ unsigned int basicLvl;
+ unsigned int school;
+ unsigned int schoolLvl;
+ unsigned int mana;
+ unsigned int commandType;
+
+ for (int i = 0; i < SPELL_SHORTCUT_ITEMS; i++)
+ {
+ std::string flags =
+ cfg->getValue("commandShortcutFlags" + toString(i), "");
+ std::stringstream ss(flags);
+ ss >> commandType;
+ ss >> targetType;
+ ss >> basicLvl;
+ ss >> school;
+ ss >> schoolLvl;
+ ss >> mana;
+
+ std::string cmd = cfg->getValue("commandShortcutCmd"
+ + toString(i), "");
+ std::string symbol = cfg->getValue("commandShortcutSymbol"
+ + toString(i), "");
+ std::string icon = cfg->getValue("commandShortcutIcon"
+ + toString(i), "");
+
+ if ((TextCommandType)commandType == TEXT_COMMAND_MAGIC)
+ {
+ addSpell(new TextCommand(i, symbol, cmd, (SpellTarget)targetType,
+ icon, basicLvl, (MagicSchool)school, schoolLvl, mana));
+ }
+ else
+ {
+ addSpell(new TextCommand(i, symbol, cmd, (SpellTarget)targetType,
+ icon));
+ }
+ }
+}
+
+void SpellManager::save()
+{
+ for (int i = 0; i < SPELL_SHORTCUT_ITEMS; i++)
+ {
+ TextCommand *spell = mSpellsVector[i];
+ if (spell)
+ {
+ serverConfig.setValue("commandShortcutCmd" + toString(i),
+ spell->getCommand());
+ serverConfig.setValue("commandShortcutSymbol" + toString(i),
+ spell->getSymbol());
+ serverConfig.setValue("commandShortcutIcon" + toString(i),
+ spell->getIcon());
+ serverConfig.setValue("commandShortcutFlags" + toString(i),
+ strprintf("%u %u %u %u %u %u", spell->getCommandType(),
+ spell->getTargetType(), spell->getBaseLvl(),
+ spell->getSchool(), spell->getSchoolLvl(), spell->getMana()));
+ }
+ }
+}
+
+std::string SpellManager::autoComplete(std::string partName)
+{
+ std::vector<TextCommand*>::iterator i = mSpellsVector.begin();
+ std::string newName = "";
+ TextCommand *newCommand = NULL;
+
+ while (i != mSpellsVector.end())
+ {
+ TextCommand *cmd = *i;
+ std::string line = cmd->getCommand();
+
+ if (line != "")
+ {
+ std::string::size_type pos = line.find(partName, 0);
+ if (pos == 0)
+ {
+ if (newName != "")
+ {
+ newName = findSameSubstring(line, newName);
+ newCommand = NULL;
+ }
+ else
+ {
+ newName = line;
+ newCommand = cmd;
+ }
+ }
+ }
+ ++i;
+ }
+ if (newName != "" && newCommand
+ && newCommand->getTargetType() == NEEDTARGET)
+ {
+ return newName + " ";
+ }
+ return newName;
+}
diff --git a/src/spellmanager.h b/src/spellmanager.h
new file mode 100644
index 000000000..b156fb74b
--- /dev/null
+++ b/src/spellmanager.h
@@ -0,0 +1,76 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SPELLMANAGER_H
+#define SPELLMANAGER_H
+
+#include <string>
+#include <vector>
+#include "textcommand.h"
+
+#include "being.h"
+
+#define SPELL_MIN_ID 100000
+#define SPELL_SHORTCUT_ITEMS 49
+
+class SpellManager
+{
+ public:
+ SpellManager();
+ ~SpellManager();
+
+ TextCommand *getSpell(int spellId);
+
+ TextCommand* getSpellByItem(int itemId);
+
+ bool addSpell(TextCommand *spell);
+
+ TextCommand *createNewSpell();
+
+ std::vector<TextCommand*> getAll();
+
+ void useItem(int itemId);
+
+ void invoke(int spellId);
+
+ void load(bool oldConfig = false);
+
+ void save();
+
+ std::string autoComplete(std::string partName);
+
+ private:
+ void fillSpells();
+
+ void invokeSpell(TextCommand* spell, Being* target) const;
+
+ void invokeSpell(TextCommand* spell) const;
+
+ std::string parseCommand(std::string command, Being* target) const;
+
+ std::map<unsigned int, TextCommand*> mSpells;
+ std::vector<TextCommand*> mSpellsVector;
+};
+
+extern SpellManager *spellManager;
+
+#endif // SPELLMANAGER_H
diff --git a/src/spellshortcut.cpp b/src/spellshortcut.cpp
new file mode 100644
index 000000000..5f3da7c4d
--- /dev/null
+++ b/src/spellshortcut.cpp
@@ -0,0 +1,71 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "configuration.h"
+#include "inventory.h"
+#include "item.h"
+#include "spellshortcut.h"
+#include "localplayer.h"
+
+#include "gui/chat.h"
+#include "gui/widgets/chattab.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "utils/stringutils.h"
+
+SpellShortcut *spellShortcut;
+
+SpellShortcut::SpellShortcut()
+{
+ mItemSelected = -1;
+ load();
+}
+
+SpellShortcut::~SpellShortcut()
+{
+}
+
+void SpellShortcut::load()
+{
+ for (int f = 0; f < SPELL_SHORTCUT_ITEMS; f ++)
+ mItems[f] = -1;
+
+ if (!spellManager)
+ return;
+
+ std::vector<TextCommand*> spells = spellManager->getAll();
+ int k = 0;
+
+ for (std::vector<TextCommand*>::const_iterator i = spells.begin(),
+ i_end = spells.end(); i != i_end && k < SPELL_SHORTCUT_ITEMS; ++i)
+ {
+ mItems[k++] = (*i)->getId();
+ }
+
+}
+
+unsigned int SpellShortcut::getSpellsCount() const
+{
+ return SPELL_SHORTCUT_ITEMS;
+} \ No newline at end of file
diff --git a/src/spellshortcut.h b/src/spellshortcut.h
new file mode 100644
index 000000000..5210fc4dc
--- /dev/null
+++ b/src/spellshortcut.h
@@ -0,0 +1,91 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SPELLSHORTCUT_H
+#define SPELLSHORTCUT_H
+
+#include "spellmanager.h"
+#include "log.h"
+#include "utils/stringutils.h"
+
+class TextCommand;
+
+/**
+ * The class which keeps track of the item shortcuts.
+ */
+class SpellShortcut
+{
+ public:
+ /**
+ * Constructor.
+ */
+ SpellShortcut();
+
+ /**
+ * Destructor.
+ */
+ ~SpellShortcut();
+
+ /**
+ * Load the configuration information.
+ */
+ void load();
+
+ unsigned int getSpellsCount() const;
+
+ /**
+ * Set the item that is selected.
+ *
+ * @param itemId The ID of the item that is to be assigned.
+ */
+ void setItemSelected(int itemId)
+ { mItemSelected = itemId; }
+
+ /**
+ * A flag to check if the item is selected.
+ */
+ bool isItemSelected() const
+ { return mItemSelected > -1; }
+
+ /**
+ * Returns selected shortcut item ID.
+ */
+ int getSelectedItem() const
+ { return mItemSelected; }
+
+ /**
+ * Returns the shortcut item ID specified by the index.
+ *
+ * @param index Index of the shortcut item.
+ */
+ int getItem(int index) const
+ { return mItems[index]; }
+
+ private:
+ int mItems[SPELL_SHORTCUT_ITEMS]; /**< The items stored. */
+ int mItemSelected; /**< The item held by cursor. */
+};
+
+extern SpellShortcut *spellShortcut;
+extern SpellManager *spellManager;
+
+#endif
diff --git a/src/sprite.h b/src/sprite.h
new file mode 100644
index 000000000..4374a1e14
--- /dev/null
+++ b/src/sprite.h
@@ -0,0 +1,110 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef SPRITE_H
+#define SPRITE_H
+
+#include "resources/spritedef.h"
+
+class Graphics;
+class Image;
+
+class Sprite
+{
+ public:
+ virtual ~Sprite() {}
+
+ /**
+ * Resets the sprite.
+ *
+ * @returns true if the sprite changed, false otherwise
+ */
+ virtual bool reset() = 0;
+
+ /**
+ * Plays an action using the current direction.
+ *
+ * @returns true if the sprite changed, false otherwise
+ */
+ virtual bool play(std::string action) = 0;
+
+ /**
+ * Inform the animation of the passed time so that it can output the
+ * correct animation frame.
+ *
+ * @returns true if the sprite changed, false otherwise
+ */
+ virtual bool update(int time) = 0;
+
+ /**
+ * Draw the current animation frame at the coordinates given in screen
+ * pixels.
+ */
+ virtual bool draw(Graphics* graphics, int posX, int posY) const = 0;
+
+ /**
+ * Gets the width in pixels of the image of the current frame
+ */
+ virtual int getWidth() const = 0;
+
+ /**
+ * Gets the height in pixels of the image of the current frame
+ */
+ virtual int getHeight() const = 0;
+
+ /**
+ * Returns a reference to the current image being drawn.
+ */
+ virtual const Image* getImage() const = 0;
+
+ /**
+ * Sets the direction.
+ *
+ * @returns true if the sprite changed, false otherwise
+ */
+ virtual bool setDirection(SpriteDirection direction) = 0;
+
+ /**
+ * Sets the alpha value of the animated sprite
+ */
+ virtual void setAlpha(float alpha)
+ { mAlpha = alpha; }
+
+ /**
+ * Returns the current alpha opacity of the animated sprite.
+ */
+ virtual float getAlpha() const
+ { return mAlpha; }
+
+ /**
+ * Returns the current frame number for the sprite.
+ */
+ virtual unsigned int getCurrentFrame() const = 0;
+
+ /**
+ * Returns the frame count for the sprite.
+ */
+ virtual unsigned int getFrameCount() const = 0;
+
+ protected:
+ float mAlpha; /**< The alpha opacity used to draw */
+};
+
+#endif // SPRITE_H
diff --git a/src/statuseffect.cpp b/src/statuseffect.cpp
new file mode 100644
index 000000000..1a399410b
--- /dev/null
+++ b/src/statuseffect.cpp
@@ -0,0 +1,205 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "statuseffect.h"
+
+#include "log.h"
+#include "sound.h"
+
+#include "gui/widgets/chattab.h"
+
+#include "utils/xml.h"
+
+#include "configuration.h"
+
+#include <map>
+
+#define STATUS_EFFECTS_FILE "status-effects.xml"
+
+void unloadMap(std::map<int, StatusEffect *> map);
+
+bool StatusEffect::mLoaded = false;
+
+StatusEffect::StatusEffect() :
+ mPersistentParticleEffect(false)
+{}
+
+StatusEffect::~StatusEffect()
+{}
+
+void StatusEffect::playSFX()
+{
+ if (!mSFXEffect.empty())
+ sound.playSfx(mSFXEffect);
+}
+
+void StatusEffect::deliverMessage()
+{
+ if (!mMessage.empty() && localChatTab)
+ localChatTab->chatLog(mMessage, BY_SERVER);
+}
+
+Particle *StatusEffect::getParticle()
+{
+ if (!particleEngine || mParticleEffect.empty())
+ return NULL;
+ else
+ return particleEngine->addEffect(mParticleEffect, 0, 0);
+}
+
+AnimatedSprite *StatusEffect::getIcon()
+{
+ if (mIcon.empty())
+ {
+ return NULL;
+ }
+ else
+ {
+ AnimatedSprite *sprite = AnimatedSprite::load(
+ paths.getStringValue("sprites") + mIcon);
+ if (false && sprite)
+ {
+ sprite->play(SpriteAction::DEFAULT);
+ sprite->reset();
+ }
+ return sprite;
+ }
+}
+
+std::string StatusEffect::getAction()
+{
+ if (mAction.empty())
+ return SpriteAction::INVALID;
+ else
+ return mAction;
+}
+
+
+// -- initialisation and static parts --
+
+
+typedef std::map<int, StatusEffect *> status_effect_map[2];
+
+static status_effect_map statusEffects;
+static status_effect_map stunEffects;
+static std::map<int, int> blockEffectIndexMap;
+
+int StatusEffect::blockEffectIndexToEffectIndex(int blockIndex)
+{
+ if (blockEffectIndexMap.find(blockIndex) == blockEffectIndexMap.end())
+ return -1;
+ return blockEffectIndexMap[blockIndex];
+}
+
+StatusEffect *StatusEffect::getStatusEffect(int index, bool enabling)
+{
+ return statusEffects[enabling][index];
+}
+
+StatusEffect *StatusEffect::getStunEffect(int index, bool enabling)
+{
+ return stunEffects[enabling][index];
+}
+
+void StatusEffect::load()
+{
+ if (mLoaded)
+ unload();
+
+ XML::Document doc(STATUS_EFFECTS_FILE);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "status-effects"))
+ {
+ logger->log1("Error loading status effects file: "
+ STATUS_EFFECTS_FILE);
+ return;
+ }
+
+ for_each_xml_child_node(node, rootNode)
+ {
+ status_effect_map *the_map = NULL;
+
+ int index = atoi(XML::getProperty(node, "id", "-1").c_str());
+
+ if (xmlStrEqual(node->name, BAD_CAST "status-effect"))
+ {
+ the_map = &statusEffects;
+ int block_index = atoi(XML::getProperty(
+ node, "block-id", "-1").c_str());
+
+ if (index >= 0 && block_index >= 0)
+ blockEffectIndexMap[block_index] = index;
+
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "stun-effect"))
+ the_map = &stunEffects;
+
+ if (the_map)
+ {
+ StatusEffect *startEffect = new StatusEffect;
+ StatusEffect *endEffect = new StatusEffect;
+
+ startEffect->mMessage = XML::getProperty(
+ node, "start-message", "");
+ startEffect->mSFXEffect = XML::getProperty(
+ node, "start-audio", "");
+ startEffect->mParticleEffect = XML::getProperty(
+ node, "start-particle", "");
+
+ startEffect->mIcon = XML::getProperty(node, "icon", "");
+ startEffect->mAction = XML::getProperty(node, "action", "");
+ startEffect->mPersistentParticleEffect = (XML::getProperty(
+ node, "persistent-particle-effect", "no")) != "no";
+
+ endEffect->mMessage = XML::getProperty(node, "end-message", "");
+ endEffect->mSFXEffect = XML::getProperty(node, "end-audio", "");
+ endEffect->mParticleEffect = XML::getProperty(
+ node, "end-particle", "");
+
+ (*the_map)[1][index] = startEffect;
+ (*the_map)[0][index] = endEffect;
+ }
+ }
+}
+
+void unloadMap(std::map<int, StatusEffect *> map)
+{
+ std::map<int, StatusEffect *>::iterator it;
+
+ for (it = map.begin(); it != map.end(); it++)
+ delete (*it).second;
+
+ map.clear();
+}
+
+void StatusEffect::unload()
+{
+ if (!mLoaded)
+ return;
+
+ unloadMap(statusEffects[0]);
+ unloadMap(statusEffects[1]);
+ unloadMap(stunEffects[0]);
+ unloadMap(stunEffects[1]);
+
+ mLoaded = false;
+}
diff --git a/src/statuseffect.h b/src/statuseffect.h
new file mode 100644
index 000000000..cb0439120
--- /dev/null
+++ b/src/statuseffect.h
@@ -0,0 +1,112 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef STATUS_EFFECT_H
+#define STATUS_EFFECT_H
+
+#include "particle.h"
+#include "animatedsprite.h"
+
+#include "resources/animation.h"
+
+class StatusEffect
+{
+public:
+ StatusEffect();
+ ~StatusEffect();
+
+ /**
+ * Plays the sound effect associated with this status effect, if possible.
+ */
+ void playSFX();
+
+ /**
+ * Delivers the chat message associated with this status effect, if
+ * possible.
+ */
+ void deliverMessage();
+
+ /**
+ * Creates the particle effect associated with this status effect, if
+ * possible.
+ */
+ Particle *getParticle();
+
+ /**
+ * Retrieves the status icon for this effect, if applicable
+ */
+ AnimatedSprite *getIcon();
+
+ /**
+ * Retrieves an action to perform, or SpriteAction::INVALID
+ */
+ std::string getAction();
+
+ /**
+ * Determines whether the particle effect should be restarted when the
+ * being changes maps
+ */
+ bool particleEffectIsPersistent() const
+ { return mPersistentParticleEffect; }
+
+
+ /**
+ * Retrieves a status effect.
+ *
+ * \param index Index of the status effect.
+ * \param enabling Whether to retrieve the activating effect (true) or
+ * the deactivating effect (false).
+ */
+ static StatusEffect *getStatusEffect(int index, bool enabling);
+
+ /**
+ * Retrieves a stun effect.
+ *
+ * \param index Index of the stun effect.
+ * \param enabling Whether to retrieve the activating effect (true) or
+ * the deactivating effect (false).
+ */
+ static StatusEffect *getStunEffect(int index, bool enabling);
+
+ /**
+ * Maps a block effect index to its corresponding effect index. Block
+ * effect indices are used for opt2/opt3/status.option blocks; their
+ * mapping to regular effect indices is handled in the config file.
+ *
+ * Returns -1 on failure.
+ */
+ static int blockEffectIndexToEffectIndex(int blocKIndex);
+
+ static void load();
+
+ static void unload();
+private:
+ static bool mLoaded;
+
+ std::string mMessage;
+ std::string mSFXEffect;
+ std::string mParticleEffect;
+ std::string mIcon;
+ std::string mAction;
+ bool mPersistentParticleEffect;
+};
+
+#endif // !defined(STATUS_EFFECT_H)
diff --git a/src/text.cpp b/src/text.cpp
new file mode 100644
index 000000000..e878d96b8
--- /dev/null
+++ b/src/text.cpp
@@ -0,0 +1,194 @@
+/*
+ * Support for non-overlapping floating text
+ * Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "text.h"
+
+#include "configuration.h"
+#include "textmanager.h"
+#include "textrenderer.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+#include "gui/theme.h"
+
+#include "resources/resourcemanager.h"
+#include "resources/image.h"
+
+#include <guichan/font.hpp>
+
+int Text::mInstances = 0;
+ImageRect Text::mBubble;
+Image *Text::mBubbleArrow;
+
+Text::Text(const std::string &text, int x, int y,
+ gcn::Graphics::Alignment alignment,
+ const gcn::Color* color, bool isSpeech,
+ gcn::Font *font) :
+ mText(text),
+ mColor(color),
+ mIsSpeech(isSpeech)
+{
+ if (!font)
+ mFont = gui->getFont();
+ else
+ mFont = font;
+
+ if (textManager == 0)
+ {
+ textManager = new TextManager;
+ Image *sbImage = Theme::getImageFromTheme("bubble.png|W:#"
+ + config.getStringValue("speechBubblecolor"));
+ if (sbImage)
+ {
+ mBubble.grid[0] = sbImage->getSubImage(0, 0, 5, 5);
+ mBubble.grid[1] = sbImage->getSubImage(5, 0, 5, 5);
+ mBubble.grid[2] = sbImage->getSubImage(10, 0, 5, 5);
+ mBubble.grid[3] = sbImage->getSubImage(0, 5, 5, 5);
+ mBubble.grid[4] = sbImage->getSubImage(5, 5, 5, 5);
+ mBubble.grid[5] = sbImage->getSubImage(10, 5, 5, 5);
+ mBubble.grid[6] = sbImage->getSubImage(0, 10, 5, 5);
+ mBubble.grid[7] = sbImage->getSubImage(5, 10, 5, 5);
+ mBubble.grid[8] = sbImage->getSubImage(10, 10, 5, 5);
+ mBubbleArrow = sbImage->getSubImage(0, 15, 15, 10);
+ }
+ else
+ {
+ for (int f = 0; f < 9; f ++)
+ mBubble.grid[f] = 0;
+ mBubbleArrow = 0;
+ }
+ const float bubbleAlpha = config.getFloatValue("speechBubbleAlpha");
+ for (int i = 0; i < 9; i++)
+ {
+ if (mBubble.grid[i])
+ mBubble.grid[i]->setAlpha(bubbleAlpha);
+ }
+ if (mBubbleArrow)
+ mBubbleArrow->setAlpha(bubbleAlpha);
+ if (sbImage)
+ sbImage->decRef();
+ }
+ ++mInstances;
+ mHeight = mFont->getHeight();
+ mWidth = mFont->getWidth(text);
+
+ switch (alignment)
+ {
+ case gcn::Graphics::LEFT:
+ mXOffset = 0;
+ break;
+ case gcn::Graphics::CENTER:
+ mXOffset = mWidth / 2;
+ break;
+ case gcn::Graphics::RIGHT:
+ mXOffset = mWidth;
+ break;
+ default:
+ break;
+ }
+ mX = x - mXOffset;
+ mY = y;
+ if (textManager)
+ textManager->addText(this);
+}
+
+Text::~Text()
+{
+ if (textManager)
+ textManager->removeText(this);
+ if (--mInstances == 0)
+ {
+ delete textManager;
+ textManager = 0;
+ delete mBubble.grid[0];
+ mBubble.grid[0] = 0;
+ delete mBubble.grid[1];
+ mBubble.grid[1] = 0;
+ delete mBubble.grid[2];
+ mBubble.grid[2] = 0;
+ delete mBubble.grid[3];
+ mBubble.grid[3] = 0;
+ delete mBubble.grid[4];
+ mBubble.grid[4] = 0;
+ delete mBubble.grid[5];
+ mBubble.grid[5] = 0;
+ delete mBubble.grid[6];
+ mBubble.grid[6] = 0;
+ delete mBubble.grid[7];
+ mBubble.grid[7] = 0;
+ delete mBubble.grid[8];
+ mBubble.grid[8] = 0;
+ delete mBubbleArrow;
+ mBubbleArrow = 0;
+ }
+}
+
+void Text::setColor(const gcn::Color *color)
+{
+ mColor = color;
+}
+
+void Text::adviseXY(int x, int y)
+{
+ if (textManager)
+ textManager->moveText(this, x - mXOffset, y);
+}
+
+void Text::draw(gcn::Graphics *graphics, int xOff, int yOff)
+{
+ if (mIsSpeech)
+ {
+ static_cast<Graphics*>(graphics)->drawImageRect(
+ mX - xOff - 5, mY - yOff - 5, mWidth + 10, mHeight + 10,
+ mBubble);
+ /*
+ if (mWidth >= 15)
+ {
+ static_cast<Graphics*>(graphics)->drawImage(
+ mBubbleArrow, mX - xOff - 7 + mWidth / 2,
+ mY - yOff + mHeight + 4);
+ }
+ */
+ }
+
+ TextRenderer::renderText(graphics, mText,
+ mX - xOff, mY - yOff, gcn::Graphics::LEFT,
+ *mColor, mFont, !mIsSpeech, true);
+}
+
+FlashText::FlashText(const std::string &text, int x, int y,
+ gcn::Graphics::Alignment alignment,
+ const gcn::Color *color, gcn::Font *font) :
+ Text(text, x, y, alignment, color, false, font),
+ mTime(0)
+{
+}
+
+void FlashText::draw(gcn::Graphics *graphics, int xOff, int yOff)
+{
+ if (mTime)
+ {
+ if ((--mTime & 4) == 0)
+ return;
+ }
+ Text::draw(graphics, xOff, yOff);
+}
diff --git a/src/text.h b/src/text.h
new file mode 100644
index 000000000..7c8063ccf
--- /dev/null
+++ b/src/text.h
@@ -0,0 +1,113 @@
+/*
+ * Support for non-overlapping floating text
+ * Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TEXT_H
+#define TEXT_H
+
+#include "graphics.h"
+#include "guichanfwd.h"
+
+#include <guichan/color.hpp>
+
+class TextManager;
+
+class Text
+{
+ friend class TextManager;
+
+ public:
+ /**
+ * Constructor creates a text object to display on the screen.
+ */
+ Text(const std::string &text, int x, int y,
+ gcn::Graphics::Alignment alignment,
+ const gcn::Color *color, bool isSpeech = false,
+ gcn::Font *font = 0);
+
+ /**
+ * Destructor. The text is removed from the screen.
+ */
+ virtual ~Text();
+
+ void setColor(const gcn::Color *color);
+
+ int getWidth() const
+ { return mWidth; }
+
+ int getHeight() const
+ { return mHeight; }
+
+ /**
+ * Allows the originator of the text to specify the ideal coordinates.
+ */
+ void adviseXY(int x, int y);
+
+ /**
+ * Draws the text.
+ */
+ virtual void draw(gcn::Graphics *graphics, int xOff, int yOff);
+
+ private:
+ int mX; /**< Actual x-value of left of text written. */
+ int mY; /**< Actual y-value of top of text written. */
+ int mWidth; /**< The width of the text. */
+ int mHeight; /**< The height of the text. */
+ int mXOffset; /**< The offset of mX from the desired x. */
+ static int mInstances; /**< Instances of text. */
+ std::string mText; /**< The text to display. */
+ const gcn::Color *mColor; /**< The color of the text. */
+ gcn::Font *mFont; /**< The font of the text */
+ bool mIsSpeech; /**< Is this text a speech bubble? */
+
+ protected:
+ static ImageRect mBubble; /**< Speech bubble graphic */
+ static Image *mBubbleArrow; /**< Speech bubble arrow graphic */
+};
+
+class FlashText : public Text
+{
+ public:
+ FlashText(const std::string &text, int x, int y,
+ gcn::Graphics::Alignment alignment,
+ const gcn::Color* color,
+ gcn::Font *font = 0);
+
+ /**
+ * Remove the text from the screen
+ */
+ virtual ~FlashText() {}
+
+ /**
+ * Flash the text for so many refreshes.
+ */
+ void flash(int time) {mTime = time; }
+
+ /**
+ * Draws the text.
+ */
+ virtual void draw(gcn::Graphics *graphics, int xOff, int yOff);
+
+ private:
+ int mTime; /**< Time left for flashing */
+};
+
+#endif // TEXT_H
diff --git a/src/textcommand.cpp b/src/textcommand.cpp
new file mode 100644
index 000000000..402aef5c5
--- /dev/null
+++ b/src/textcommand.cpp
@@ -0,0 +1,115 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "textcommand.h"
+
+#include "gui/theme.h"
+
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
+
+TextCommand::TextCommand(unsigned int id, std::string symbol,
+ std::string command, SpellTarget type,
+ std::string icon, unsigned int basicLvl,
+ MagicSchool school, unsigned int schoolLvl,
+ int mana) :
+ mImage(0)
+{
+ mId = id;
+ mCommand = command;
+ mSymbol = symbol;
+ mTargetType = type;
+ mIcon = icon;
+ mBaseLvl = basicLvl;
+ mSchool = school;
+ mSchoolLvl = schoolLvl;
+ mMana = mana;
+ mCommandType = TEXT_COMMAND_MAGIC;
+ loadImage();
+}
+
+
+TextCommand::TextCommand(unsigned int id, std::string symbol,
+ std::string command, SpellTarget type,
+ std::string icon) :
+ mImage(0)
+{
+ mId = id;
+ mCommand = command;
+ mSymbol = symbol;
+ mTargetType = type;
+ mIcon = icon;
+ mCommandType = TEXT_COMMAND_TEXT;
+ mBaseLvl = 0;
+ mSchool = SKILL_MAGIC;
+ mSchoolLvl = 0;
+ mMana = 0;
+ mCommandType = TEXT_COMMAND_TEXT;
+ loadImage();
+}
+
+TextCommand::TextCommand(unsigned int id) :
+ mImage(0)
+{
+ mId = id;
+ mCommand = "";
+ mSymbol = "";
+ mTargetType = NOTARGET;
+ mIcon = "";
+ mCommandType = TEXT_COMMAND_TEXT;
+ mBaseLvl = 0;
+ mSchool = SKILL_MAGIC;
+ mSchoolLvl = 0;
+ mMana = 0;
+ mCommandType = TEXT_COMMAND_TEXT;
+ loadImage();
+}
+
+
+TextCommand::~TextCommand()
+{
+ if (mImage)
+ {
+ mImage->decRef();
+ mImage = 0;
+ }
+}
+
+void TextCommand::loadImage()
+{
+ if (mImage)
+ {
+ mImage->decRef();
+ mImage = 0;
+ }
+
+ if (getIcon().empty())
+ return;
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ SpriteDisplay display = ItemDB::get(getIcon()).getDisplay();
+ mImage = resman->getImage("graphics/items/" + display.image);
+
+ if (!mImage)
+ mImage = Theme::getImageFromTheme("unknown-item.png");
+} \ No newline at end of file
diff --git a/src/textcommand.h b/src/textcommand.h
new file mode 100644
index 000000000..dbd621901
--- /dev/null
+++ b/src/textcommand.h
@@ -0,0 +1,173 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 Andrei Karas
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TEXTCOMMAND_H
+#define TEXTCOMMAND_H
+
+#include "resources/itemdb.h"
+
+#define MAGIC_START_ID 340
+
+class Image;
+
+enum SpellTarget
+{
+ NOTARGET = 0,
+ ALLOWTARGET = 1,
+ NEEDTARGET = 2
+};
+
+enum MagicSchool
+{
+ SKILL_MAGIC = 340,
+ SKILL_MAGIC_LIFE = 341,
+ SKILL_MAGIC_WAR = 342,
+ SKILL_MAGIC_TRANSMUTE = 343,
+ SKILL_MAGIC_NATURE = 344,
+ SKILL_MAGIC_ASTRAL = 345
+};
+
+enum TextCommandType
+{
+ TEXT_COMMAND_MAGIC = 0,
+ TEXT_COMMAND_TEXT = 1
+};
+
+/**
+ * Represents one or more instances of a certain item type.
+ */
+class TextCommand
+{
+ public:
+ /**
+ * Constructor.
+ */
+ TextCommand(unsigned int id, std::string symbol,
+ std::string command, SpellTarget type,
+ std::string icon, unsigned int basicLvl,
+ MagicSchool school = SKILL_MAGIC,
+ unsigned int schoolLvl = 0, int mana = 0);
+
+ /**
+ * Constructor.
+ */
+ TextCommand(unsigned int id, std::string symbol,
+ std::string command, SpellTarget type,
+ std::string icon);
+
+ /**
+ * Constructor.
+ */
+ TextCommand(unsigned int id);
+
+ /**
+ * Destructor.
+ */
+ ~TextCommand();
+
+ std::string getName() const
+ { return mCommand; }
+
+ std::string getCommand() const
+ { return mCommand; }
+
+ std::string getSymbol() const
+ { return mSymbol; }
+
+ unsigned int getId() const
+ { return mId; }
+
+ SpellTarget getTargetType() const
+ { return mTargetType; }
+
+ std::string getIcon() const
+ { return mIcon; }
+
+ int getMana() const
+ { return mMana; }
+
+ MagicSchool getSchool() const
+ { return mSchool; }
+
+ int getBaseLvl() const
+ { return mBaseLvl; }
+
+ int getSchoolLvl() const
+ { return mSchoolLvl; }
+
+ TextCommandType getCommandType() const
+ { return mCommandType; }
+
+ void setCommand(std::string command)
+ { mCommand = command; }
+
+ void setSymbol(std::string symbol)
+ { mSymbol = symbol; }
+
+ void setId(unsigned int id)
+ { mId = id; }
+
+ void setTargetType(SpellTarget targetType)
+ { mTargetType = targetType; }
+
+ void setIcon(std::string icon)
+ { mIcon = icon; loadImage(); }
+
+ void setMana(unsigned int mana)
+ { mMana = mana; }
+
+ void setSchool(MagicSchool school)
+ { mSchool = school; }
+
+ void setBaseLvl(unsigned int baseLvl)
+ { mBaseLvl = baseLvl; }
+
+ void setSchoolLvl(unsigned int schoolLvl)
+ { mSchoolLvl = schoolLvl; }
+
+ void setCommandType(TextCommandType commandType)
+ { mCommandType = commandType; }
+
+ bool isEmpty() const
+ { return mCommand == "" && mSymbol == "" ; }
+
+ Image *getImage()
+ { return mImage; }
+
+ private:
+ void loadImage();
+
+ protected:
+ std::string mCommand;
+ std::string mSymbol;
+ SpellTarget mTargetType;
+ std::string mIcon;
+ unsigned int mId;
+ int mMana;
+ MagicSchool mSchool;
+ int mBaseLvl;
+ int mSchoolLvl;
+ TextCommandType mCommandType;
+ Image *mImage;
+};
+
+#endif
diff --git a/src/textmanager.cpp b/src/textmanager.cpp
new file mode 100644
index 000000000..348ab829b
--- /dev/null
+++ b/src/textmanager.cpp
@@ -0,0 +1,170 @@
+/*
+ * Support for non-overlapping floating text
+ * Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "textmanager.h"
+
+#include "text.h"
+
+#include <cstring>
+
+TextManager *textManager = 0;
+
+TextManager::TextManager()
+{
+}
+
+void TextManager::addText(Text *text)
+{
+ place(text, 0, text->mX, text->mY, text->mHeight);
+ mTextList.push_back(text);
+}
+
+void TextManager::moveText(Text *text, int x, int y)
+{
+ text->mX = x;
+ text->mY = y;
+ place(text, text, text->mX, text->mY, text->mHeight);
+}
+
+void TextManager::removeText(const Text *text)
+{
+ for (TextList::iterator ptr = mTextList.begin(),
+ pEnd = mTextList.end(); ptr != pEnd; ++ptr)
+ {
+ if (*ptr == text)
+ {
+ mTextList.erase(ptr);
+ return;
+ }
+ }
+}
+
+TextManager::~TextManager()
+{
+}
+
+void TextManager::draw(gcn::Graphics *graphics, int xOff, int yOff)
+{
+ for (TextList::iterator bPtr = mTextList.begin(), ePtr = mTextList.end();
+ bPtr != ePtr; ++bPtr)
+ {
+ (*bPtr)->draw(graphics, xOff, yOff);
+ }
+}
+
+void TextManager::place(const Text *textObj, const Text *omit,
+ int &x _UNUSED_, int &y, int h)
+{
+ int xLeft = textObj->mX;
+ int xRight1 = xLeft + textObj->mWidth;
+ const int TEST = 50; // Number of lines to test for text
+ const int nBeings = 50;
+ bool occupied[TEST]; // is some other text obscuring this line?
+ std::memset(&occupied, 0, sizeof(occupied)); // set all to false
+ int wantedTop = (TEST - h) / 2; // Entry in occupied at top of text
+ int occupiedTop = y - wantedTop; // Line in map representing to of occupied
+ int cnt = 0;
+
+ for (TextList::const_iterator ptr = mTextList.begin(),
+ pEnd = mTextList.end(); ptr != pEnd && cnt < nBeings; ++ptr, cnt ++)
+ {
+ if (*ptr != omit &&
+ (*ptr)->mX + 1 <= xRight1 &&
+ (*ptr)->mX + (*ptr)->mWidth > xLeft)
+ {
+ int from = (*ptr)->mY - occupiedTop;
+ int to = from + (*ptr)->mHeight - 1;
+ if (to < 0 || from >= TEST) // out of range considered
+ continue;
+ if (from < 0)
+ from = 0;
+ if (to >= TEST)
+ to = TEST - 1;
+ for (int i = from; i <= to; ++i)
+ occupied[i] = true;
+ }
+ }
+ bool ok = true;
+ for (int i = wantedTop; i < wantedTop + h; ++i)
+ {
+ ok = ok && !occupied[i];
+ }
+
+ if (ok)
+ return;
+
+ // Have to move it up or down, so find nearest spaces either side
+ int consec = 0;
+ int upSlot = -1; // means not found
+ for (int seek = wantedTop + h - 2; seek >= 0; --seek)
+ {
+ if (occupied[seek])
+ {
+ consec = 0;
+ }
+ else
+ {
+ if (++consec == h)
+ {
+ upSlot = seek;
+ break;
+ }
+ }
+ }
+ int downSlot = -1;
+ consec = 0;
+ for (int seek = wantedTop + 1; seek < TEST; ++seek)
+ {
+ if (occupied[seek])
+ {
+ consec = 0;
+ }
+ else
+ {
+ if (++consec == h)
+ {
+ downSlot = seek - h + 1;
+ break;
+ }
+ }
+ }
+ if (upSlot == -1 && downSlot == -1) // no good solution, so leave as is
+ {
+ return;
+ }
+ if (upSlot == -1) // must go down
+ {
+ y += downSlot - wantedTop;
+ return;
+ }
+ if (downSlot == -1) // must go up
+ {
+ y -= wantedTop - upSlot;
+ return;
+ }
+ if (wantedTop - upSlot > downSlot - wantedTop) // down is better
+ {
+ y += downSlot - wantedTop;
+ }
+ else
+ {
+ y -= wantedTop - upSlot;
+ }
+}
diff --git a/src/textmanager.h b/src/textmanager.h
new file mode 100644
index 000000000..a75623708
--- /dev/null
+++ b/src/textmanager.h
@@ -0,0 +1,82 @@
+/*
+ * Support for non-overlapping floating text
+ * Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TEXTMANAGER_H
+#define TEXTMANAGER_H
+
+#include <list>
+
+#include "guichanfwd.h"
+
+#ifdef __GNUC__
+#define _UNUSED_ __attribute__ ((unused))
+#else
+#define _UNUSED_
+#endif
+
+class Text;
+
+class TextManager
+{
+ public:
+ /**
+ * Constructor
+ */
+ TextManager();
+
+ /**
+ * Add text to the manager
+ */
+ void addText(Text *text);
+
+ /**
+ * Move the text around the screen
+ */
+ void moveText(Text *text, int x, int y);
+
+ /**
+ * Remove the text from the manager
+ */
+ void removeText(const Text *text);
+
+ /**
+ * Destroy the manager
+ */
+ ~TextManager();
+
+ /**
+ * Draw the text
+ */
+ void draw(gcn::Graphics *graphics, int xOff, int yOff);
+
+ private:
+ /**
+ * Position the text so as to avoid conflict
+ */
+ void place(const Text *textObj, const Text *omit,
+ int &x, int &y, int h);
+
+ typedef std::list<Text *> TextList; /**< The container type */
+ TextList mTextList; /**< The container */
+};
+
+extern TextManager *textManager;
+
+#endif // TEXTMANAGER_H
diff --git a/src/textparticle.cpp b/src/textparticle.cpp
new file mode 100644
index 000000000..b70155347
--- /dev/null
+++ b/src/textparticle.cpp
@@ -0,0 +1,69 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "textparticle.h"
+
+#include "textrenderer.h"
+
+#include <guichan/color.hpp>
+
+TextParticle::TextParticle(Map *map, const std::string &text,
+ const gcn::Color *color,
+ gcn::Font *font, bool outline):
+ Particle(map),
+ mText(text),
+ mTextFont(font),
+ mColor(color),
+ mOutline(outline)
+{
+}
+
+bool TextParticle::draw(Graphics *graphics, int offsetX, int offsetY) const
+{
+ if (!isAlive())
+ return false;
+
+ int screenX = (int) mPos.x + offsetX;
+ int screenY = (int) mPos.y - (int) mPos.z + offsetY;
+
+ float alpha = mAlpha * 255.0f;
+
+ if (mFadeOut && mLifetimeLeft > -1 && mLifetimeLeft < mFadeOut)
+ {
+ alpha = alpha * static_cast<float>(mLifetimeLeft)
+ / static_cast<float>(mFadeOut);
+ }
+
+ if (mFadeIn && mLifetimePast < mFadeIn)
+ {
+ alpha = alpha * static_cast<float>(mLifetimePast)
+ / static_cast<float>(mFadeIn);
+ }
+
+ gcn::Color color = *mColor;
+// color.a = (int)alpha;
+
+ TextRenderer::renderText(graphics, mText,
+ screenX, screenY, gcn::Graphics::CENTER,
+ color, mTextFont, mOutline, false, static_cast<int>(alpha));
+
+ return true;
+}
diff --git a/src/textparticle.h b/src/textparticle.h
new file mode 100644
index 000000000..7d99a057b
--- /dev/null
+++ b/src/textparticle.h
@@ -0,0 +1,54 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2006-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TEXTPARTICLE_H
+#define TEXTPARTICLE_H
+
+#include "guichanfwd.h"
+#include "particle.h"
+
+class TextParticle : public Particle
+{
+ public:
+ /**
+ * Constructor.
+ */
+ TextParticle(Map *map, const std::string &text,
+ const gcn::Color* color,
+ gcn::Font *font, bool outline = false);
+
+ /**
+ * Draws the particle image.
+ */
+ virtual bool draw(Graphics *graphics, int offsetX, int offsetY) const;
+
+ // hack to improve text visibility
+ virtual int getPixelY() const
+ { return (int) (mPos.y + mPos.z); }
+
+ private:
+ std::string mText; /**< Text of the particle. */
+ gcn::Font *mTextFont; /**< Font used for drawing the text. */
+ const gcn::Color *mColor; /**< Color used for drawing the text. */
+ bool mOutline; /**< Make the text better readable */
+};
+
+#endif
diff --git a/src/textrenderer.h b/src/textrenderer.h
new file mode 100644
index 000000000..9b3c0292e
--- /dev/null
+++ b/src/textrenderer.h
@@ -0,0 +1,78 @@
+/*
+ * Text Renderer
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TEXT_RENDERER_H
+#define TEXT_RENDERER_H
+
+#include "graphics.h"
+
+#include "gui/theme.h"
+
+/**
+ * Class for text rendering. Used by the TextParticle, the Text and FlashText
+ * objects and the Preview in the color dialog.
+ */
+class TextRenderer
+{
+ public:
+ /**
+ * Renders a specified text.
+ */
+ static inline void renderText(gcn::Graphics *graphics,
+ const std::string &text,
+ int x, int y,
+ gcn::Graphics::Alignment align,
+ const gcn::Color &color,
+ gcn::Font *font,
+ bool outline = false,
+ bool shadow = false,
+ int alpha = 255)
+ {
+ graphics->setFont(font);
+
+ // Text shadow
+ if (shadow)
+ {
+ graphics->setColor(Theme::getThemeColor(Theme::SHADOW,
+ color.a / 2));
+ if (outline)
+ graphics->drawText(text, x + 2, y + 2, align);
+ else
+ graphics->drawText(text, x + 1, y + 1, align);
+ }
+
+ if (outline)
+ {
+ // Text outline
+ graphics->setColor(Theme::getThemeColor(Theme::OUTLINE, alpha));
+// graphics->setColor(Theme::getThemeColor(Theme::OUTLINE, color.a));
+ graphics->drawText(text, x + 1, y, align);
+ graphics->drawText(text, x - 1, y, align);
+ graphics->drawText(text, x, y + 1, align);
+ graphics->drawText(text, x, y - 1, align);
+ }
+
+ graphics->setColor(color);
+ graphics->drawText(text, x, y, align);
+ }
+};
+
+#endif
diff --git a/src/tileset.h b/src/tileset.h
new file mode 100644
index 000000000..9a45667c5
--- /dev/null
+++ b/src/tileset.h
@@ -0,0 +1,53 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef TILESET_H
+#define TILESET_H
+
+#include "resources/imageset.h"
+
+/**
+ * A tileset, which is basically just an image set but it stores a firstgid.
+ */
+class Tileset : public ImageSet
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Tileset(Image *img, int w, int h, int firstGid,
+ int margin, int spacing):
+ ImageSet(img, w, h, margin, spacing),
+ mFirstGid(firstGid)
+ {
+ }
+
+ /**
+ * Returns the first gid.
+ */
+ int getFirstGid() const
+ { return mFirstGid; }
+
+ private:
+ int mFirstGid;
+};
+
+#endif
diff --git a/src/units.cpp b/src/units.cpp
new file mode 100644
index 000000000..68272c24a
--- /dev/null
+++ b/src/units.cpp
@@ -0,0 +1,248 @@
+/*
+ * Support for custom units
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "units.h"
+
+#include "log.h"
+
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <cmath>
+#include <climits>
+#include <vector>
+
+struct UnitLevel
+{
+ std::string symbol;
+ int count;
+ int round;
+};
+
+struct UnitDescription
+{
+ std::vector<struct UnitLevel> levels;
+ double conversion;
+ bool mix;
+};
+
+enum UnitType
+{
+ UNIT_WEIGHT = 0,
+ UNIT_CURRENCY = 1,
+ UNIT_END
+};
+
+std::string formatUnit(int value, int type);
+
+struct UnitDescription units[UNIT_END];
+
+void Units::loadUnits()
+{
+ { // Setup default weight
+ struct UnitDescription ud;
+
+ ud.conversion = 1.0;
+ ud.mix = false;
+
+ struct UnitLevel bu;
+ bu.symbol = "g";
+ bu.count = 1;
+ bu.round = 0;
+
+ ud.levels.push_back(bu);
+
+ struct UnitLevel ul;
+ ul.symbol = "kg";
+ ul.count = 1000;
+ ul.round = 2;
+
+ ud.levels.push_back(ul);
+
+ units[UNIT_WEIGHT] = ud;
+ }
+
+ { // Setup default currency
+ struct UnitDescription ud;
+
+ ud.conversion = 1.0;
+ ud.mix = false;
+
+ struct UnitLevel bu;
+ bu.symbol = "¤";
+ bu.count = 1;
+ bu.round = 0;
+
+ ud.levels.push_back(bu);
+
+ units[UNIT_CURRENCY] = ud;
+ }
+
+ XML::Document doc("units.xml");
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "units"))
+ {
+ logger->log1("Error loading unit definition file: units.xml");
+ return;
+ }
+
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "unit"))
+ {
+ struct UnitDescription ud;
+ int level = 1;
+ const std::string type = XML::getProperty(node, "type", "");
+ ud.conversion = XML::getProperty(node, "conversion", 1);
+ ud.mix = XML::getProperty(node, "mix", "no") == "yes";
+
+ struct UnitLevel bu;
+ bu.symbol = XML::getProperty(node, "base", "¤");
+ bu.count = 1;
+ bu.round = XML::getProperty(node, "round", 2);
+
+ ud.levels.push_back(bu);
+
+ for_each_xml_child_node(uLevel, node)
+ {
+ if (xmlStrEqual(uLevel->name, BAD_CAST "level"))
+ {
+ struct UnitLevel ul;
+ ul.symbol = XML::getProperty(uLevel, "symbol",
+ strprintf("¤%d", level));
+ ul.count = XML::getProperty(uLevel, "count", -1);
+ ul.round = XML::getProperty(uLevel, "round", bu.round);
+
+ if (ul.count > 0)
+ {
+ ud.levels.push_back(ul);
+ level++;
+ }
+ else
+ {
+ logger->log("Error bad unit count: %d for %s in %s",
+ ul.count, ul.symbol.c_str(),
+ bu.symbol.c_str());
+ }
+ }
+ }
+
+ // Add one more level for saftey
+ struct UnitLevel ll;
+ ll.symbol = "";
+ ll.count = INT_MAX;
+ ll.round = 0;
+
+ ud.levels.push_back(ll);
+
+ if (type == "weight")
+ units[UNIT_WEIGHT] = ud;
+ else if (type == "currency")
+ units[UNIT_CURRENCY] = ud;
+ else
+ logger->log("Error unknown unit type: %s", type.c_str());
+ }
+ }
+}
+
+std::string formatUnit(int value, int type)
+{
+ struct UnitDescription ud = units[type];
+ struct UnitLevel ul;
+
+ // Shortcut for 0; do the same for values less than 0 (for now)
+ if (value <= 0)
+ {
+ ul = ud.levels[0];
+ return strprintf("0%s", ul.symbol.c_str());
+ }
+ else
+ {
+ double amount = ud.conversion * value;
+
+ // If only the first level is needed, act like mix if false
+ if (ud.mix && ud.levels.size() > 0 && ud.levels[1].count < amount)
+ {
+ std::string output;
+ struct UnitLevel pl = ud.levels[0];
+ ul = ud.levels[1];
+ int levelAmount = (int) amount;
+ int nextAmount = 0;
+
+ if (ul.count)
+ levelAmount /= ul.count;
+
+ amount -= levelAmount * ul.count;
+
+ if (amount > 0)
+ {
+ output = strprintf("%.*f%s", pl.round, amount,
+ pl.symbol.c_str());
+ }
+
+ for (unsigned int i = 2; i < ud.levels.size(); i++)
+ {
+ pl = ul;
+ ul = ud.levels[i];
+
+ if (ul.count)
+ nextAmount = levelAmount / ul.count;
+ levelAmount %= ul.count;
+
+ if (levelAmount > 0) output = strprintf("%d%s",
+ levelAmount, pl.symbol.c_str()) + output;
+
+ if (!nextAmount)
+ break;
+ levelAmount = nextAmount;
+ }
+
+ return output;
+ }
+ else
+ {
+ for (unsigned int i = 0; i < ud.levels.size(); i++)
+ {
+ ul = ud.levels[i];
+ if (amount < ul.count && ul.count > 0)
+ {
+ ul = ud.levels[i - 1];
+ break;
+ }
+ if (ul.count)
+ amount /= ul.count;
+ }
+
+ return strprintf("%.*f%s", ul.round, amount, ul.symbol.c_str());
+ }
+ }
+}
+
+std::string Units::formatCurrency(int value)
+{
+ return formatUnit(value, UNIT_CURRENCY);
+}
+
+std::string Units::formatWeight(int value)
+{
+ return formatUnit(value, UNIT_WEIGHT);
+}
diff --git a/src/units.h b/src/units.h
new file mode 100644
index 000000000..d779efe70
--- /dev/null
+++ b/src/units.h
@@ -0,0 +1,46 @@
+/*
+ * Support for custom units
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UNITS_H
+#define UNITS_H
+
+#include <string>
+
+class Units
+{
+ public:
+ /**
+ * Loads and parses the units.xml file (if found).
+ */
+ static void loadUnits();
+
+ /**
+ * Formats the given number in the correct currency format.
+ */
+ static std::string formatCurrency(int value);
+
+ /**
+ * Formats the given number in the correct weight/mass format.
+ */
+ static std::string formatWeight(int value);
+};
+
+#endif // UNITS_H
diff --git a/src/utils/base64.cpp b/src/utils/base64.cpp
new file mode 100644
index 000000000..1221a7c7f
--- /dev/null
+++ b/src/utils/base64.cpp
@@ -0,0 +1,170 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2000 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | 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 both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Author: Jim Winstead (jimw@php.net) |
+ +----------------------------------------------------------------------+
+ */
+
+#include "utils/base64.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+static char base64_table[] =
+{
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
+};
+static char base64_pad = '=';
+
+unsigned char *php3_base64_encode(const unsigned char *string,
+ int length, int *ret_length)
+{
+ const unsigned char *current = string;
+ int i = 0;
+ unsigned char *result = (unsigned char *)malloc(
+ ((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char));
+
+ while (length > 2)
+ { /* keep going until we have less than 24 bits */
+ result[i++] = base64_table[current[0] >> 2];
+ result[i++] = base64_table[((current[0] & 0x03)
+ << 4) + (current[1] >> 4)];
+ result[i++] = base64_table[((current[1] & 0x0f)
+ << 2) + (current[2] >> 6)];
+ result[i++] = base64_table[current[2] & 0x3f];
+
+ current += 3;
+ length -= 3; /* we just handle 3 octets of data */
+ }
+
+ /* now deal with the tail end of things */
+ if (length != 0)
+ {
+ result[i++] = base64_table[current[0] >> 2];
+ if (length > 1)
+ {
+ result[i++] = base64_table[((current[0] & 0x03) << 4)
+ + (current[1] >> 4)];
+ result[i++] = base64_table[(current[1] & 0x0f) << 2];
+ result[i++] = base64_pad;
+ }
+ else
+ {
+ result[i++] = base64_table[(current[0] & 0x03) << 4];
+ result[i++] = base64_pad;
+ result[i++] = base64_pad;
+ }
+ }
+ if (ret_length)
+ {
+ *ret_length = i;
+ }
+ result[i] = '\0';
+ return result;
+}
+
+/* as above, but backwards. :) */
+unsigned char *php3_base64_decode(const unsigned char *string,
+ int length, int *ret_length)
+{
+ const unsigned char *current = string;
+ int ch, i = 0, j = 0, k;
+ char *chp;
+
+ unsigned char *result = (unsigned char *)malloc(length + 1);
+
+ if (result == NULL)
+ return NULL;
+
+ /* run through the whole string, converting as we go */
+ while ((ch = *current++) != '\0')
+ {
+ if (ch == base64_pad) break;
+
+ /* When Base64 gets POSTed, all pluses are interpreted as spaces.
+ This line changes them back. It's not exactly the Base64 spec,
+ but it is completely compatible with it (the spec says that
+ spaces are invalid). This will also save many people considerable
+ headache. - Turadg Aleahmad <turadg@wise.berkeley.edu>
+ */
+
+ if (ch == ' ') ch = '+';
+
+ chp = strchr(base64_table, ch);
+ if (!chp)
+ continue;
+ ch = chp - base64_table;
+
+ switch(i % 4)
+ {
+ case 0:
+ result[j] = ch << 2;
+ break;
+ case 1:
+ result[j++] |= ch >> 4;
+ result[j] = (ch & 0x0f) << 4;
+ break;
+ case 2:
+ result[j++] |= ch >>2;
+ result[j] = (ch & 0x03) << 6;
+ break;
+ case 3:
+ result[j++] |= ch;
+ break;
+ default:
+ break;
+ }
+ i++;
+ }
+
+ k = j;
+ /* mop things up if we ended on a boundary */
+ if (ch == base64_pad)
+ {
+ switch(i % 4)
+ {
+ case 0:
+ case 1:
+ free(result);
+ return 0;
+ case 2:
+ k++;
+ case 3:
+ result[k++] = 0;
+ default:
+ break;
+ }
+ }
+ if (ret_length)
+ {
+ *ret_length = j;
+ }
+ result[k] = '\0';
+ return result;
+}
diff --git a/src/utils/base64.h b/src/utils/base64.h
new file mode 100644
index 000000000..92c230169
--- /dev/null
+++ b/src/utils/base64.h
@@ -0,0 +1,36 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | 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 both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Author: Jim Winstead (jimw@php.net) |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef BASE64_H
+#define BASE64_H
+
+extern unsigned char *php3_base64_encode(const unsigned char *, int, int *);
+extern unsigned char *php3_base64_decode(const unsigned char *, int, int *);
+
+#endif /* BASE64_H */
diff --git a/src/utils/copynpaste.cpp b/src/utils/copynpaste.cpp
new file mode 100644
index 000000000..498c012b5
--- /dev/null
+++ b/src/utils/copynpaste.cpp
@@ -0,0 +1,324 @@
+/*
+ * Retrieve string pasted depending on OS mechanisms.
+ * Copyright (C) 2001-2010 Wormux Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+/*
+ * IMPORTANT!
+ *
+ * This code was taken from Wormux svn trunk at Feb 25 2010. Please don't
+ * make any unnecessary modifications, and try to sync up modifications
+ * when possible.
+ */
+
+#ifdef _MSC_VER
+# include "msvc/config.h"
+#elif defined(HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include <SDL_syswm.h>
+#include "copynpaste.h"
+
+#ifdef WIN32
+bool RetrieveBuffer(std::string& text, std::string::size_type& pos)
+{
+ bool ret = false;
+
+ if (!OpenClipboard(NULL))
+ return false;
+
+ HANDLE h = GetClipboardData(CF_UNICODETEXT);
+ if (h)
+ {
+ LPCWSTR data = (LPCWSTR)GlobalLock(h);
+
+ if (data)
+ {
+ int len = WideCharToMultiByte(CP_UTF8, 0, data, -1, NULL, 0, NULL, NULL);
+ if (len > 0)
+ {
+ // Convert from UTF-16 to UTF-8
+ void *temp = malloc(len);
+ if (WideCharToMultiByte(CP_UTF8, 0, data, -1, (LPSTR)temp, len, NULL, NULL))
+ {
+ text.insert(pos, (char*)temp);
+ pos += len-1;
+ }
+ free(temp);
+ ret = true;
+ }
+ }
+ GlobalUnlock(h);
+ }
+ else
+ {
+ h = GetClipboardData(CF_TEXT);
+
+ if (h)
+ {
+ const char *data = (char*)GlobalLock(h);
+ if (data)
+ {
+ text.insert(pos, data);
+ pos += strlen(data);
+ ret = true;
+ }
+ GlobalUnlock(h);
+ }
+ }
+
+ CloseClipboard();
+ return ret;
+}
+#elif defined(__APPLE__)
+
+#ifdef Status
+#undef Status
+#endif
+
+#include <Carbon/Carbon.h>
+
+// Sorry for the very long code, all nicer OS X APIs are coded in Objective C and not C!
+// Also it does very thorough error handling
+bool GetDataFromPasteboard( PasteboardRef inPasteboard, char* flavorText /* out */, const int bufSize )
+{
+ OSStatus err = noErr;
+ PasteboardSyncFlags syncFlags;
+ ItemCount itemCount;
+
+ syncFlags = PasteboardSynchronize( inPasteboard );
+
+ //require_action( syncFlags & kPasteboardModified, PasteboardOutOfSync,
+ // err = badPasteboardSyncErr );
+
+ err = PasteboardGetItemCount( inPasteboard, &itemCount );
+ require_noerr( err, CantGetPasteboardItemCount );
+
+ for (UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++)
+ {
+ PasteboardItemID itemID;
+ CFArrayRef flavorTypeArray;
+ CFIndex flavorCount;
+
+ err = PasteboardGetItemIdentifier( inPasteboard, itemIndex, &itemID );
+ require_noerr( err, CantGetPasteboardItemIdentifier );
+
+ err = PasteboardCopyItemFlavors( inPasteboard, itemID, &flavorTypeArray );
+ require_noerr( err, CantCopyPasteboardItemFlavors );
+
+ flavorCount = CFArrayGetCount( flavorTypeArray );
+
+ for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
+ {
+ CFStringRef flavorType;
+ CFDataRef flavorData;
+ CFIndex flavorDataSize;
+ flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex);
+
+ // we're only interested by text...
+ if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text")))
+ {
+ err = PasteboardCopyItemFlavorData( inPasteboard, itemID,
+ flavorType, &flavorData );
+ require_noerr( err, CantCopyFlavorData );
+ flavorDataSize = CFDataGetLength( flavorData );
+ flavorDataSize = (flavorDataSize<254) ? flavorDataSize : 254;
+
+ if (flavorDataSize+2 > bufSize)
+ {
+ fprintf(stderr, "Cannot copy clipboard, contents is too big!\n");
+ return false;
+ }
+
+ for (short dataIndex = 0; dataIndex <= flavorDataSize; dataIndex++)
+ {
+ char byte = *(CFDataGetBytePtr( flavorData ) + dataIndex);
+ flavorText[dataIndex] = byte;
+ }
+
+ flavorText[flavorDataSize] = '\0';
+ flavorText[flavorDataSize+1] = '\n';
+
+ CFRelease (flavorData);
+ return true;
+ }
+
+ continue;
+ CantCopyFlavorData: fprintf(stderr, "Cannot copy clipboard, CantCopyFlavorData!\n");
+ }
+
+ CFRelease (flavorTypeArray);
+ continue;
+
+ CantCopyPasteboardItemFlavors: fprintf(stderr, "Cannot copy clipboard, CantCopyPasteboardItemFlavors!\n"); continue;
+ CantGetPasteboardItemIdentifier: fprintf(stderr, "Cannot copy clipboard, CantGetPasteboardItemIdentifier!\n"); continue;
+ }
+ fprintf(stderr, "Cannot copy clipboard, found no acceptable flavour!\n");
+ return false;
+
+ CantGetPasteboardItemCount: fprintf(stderr, "Cannot copy clipboard, CantGetPasteboardItemCount!\n"); return false;
+ //PasteboardOutOfSync: fprintf(stderr, "Cannot copy clipboard, PasteboardOutOfSync!\n"); return false;
+}
+
+bool getClipBoard(char* text /* out */, const int bufSize )
+{
+ OSStatus err = noErr;
+
+ PasteboardRef theClipboard;
+ err = PasteboardCreate( kPasteboardClipboard, &theClipboard );
+ require_noerr( err, PasteboardCreateFailed );
+
+ if (!GetDataFromPasteboard(theClipboard, text, bufSize))
+ {
+ fprintf(stderr, "Cannot copy clipboard, GetDataFromPasteboardFailed!\n");
+ return false;
+ }
+
+ CFRelease(theClipboard);
+
+ return true;
+
+ // ---- error handling
+ PasteboardCreateFailed: fprintf(stderr, "Cannot copy clipboard, PasteboardCreateFailed!\n");
+ CFRelease(theClipboard);
+ return false;
+}
+
+bool RetrieveBuffer(std::string& text, std::string::size_type& pos)
+{
+ const int bufSize = 512;
+ char buffer[bufSize+1];
+
+ if (getClipBoard(buffer, bufSize))
+ {
+ text = buffer;
+ pos += strlen(buffer);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+#elif USE_X11
+static char* getSelection(Display *dpy, Window us, Atom selection)
+{
+ int max_events = 50;
+ Window owner = XGetSelectionOwner (dpy, selection);
+ int ret;
+
+ //printf("XConvertSelection on %s\n", XGetAtomName(dpy, selection));
+ if (owner == None)
+ {
+ //printf("No owner\n");
+ return NULL;
+ }
+ XConvertSelection(dpy, selection, XA_STRING, XA_PRIMARY, us, CurrentTime);
+ XFlush(dpy);
+
+ while (max_events--)
+ {
+ XEvent e;
+
+ XNextEvent(dpy, &e);
+ if(e.type == SelectionNotify)
+ {
+ //printf("Received %s\n", XGetAtomName(dpy, e.xselection.selection));
+ if(e.xselection.property == None)
+ {
+ //printf("Couldn't convert\n");
+ return NULL;
+ }
+
+ long unsigned len, left, dummy;
+ int format;
+ Atom type;
+ unsigned char *data = NULL;
+
+ ret = XGetWindowProperty(dpy, us, e.xselection.property, 0, 0, False,
+ AnyPropertyType, &type, &format, &len, &left,
+ &data);
+ if (left < 1)
+ {
+ if (ret == Success)
+ XFree(data);
+ return NULL;
+ }
+
+ ret = XGetWindowProperty(dpy, us, e.xselection.property, 0, left, False,
+ AnyPropertyType, &type, &format, &len, &dummy,
+ &data);
+ if (ret != Success)
+ {
+ //printf("Failed to get property: %p on %lu\n", data, len);
+ return NULL;
+ }
+
+ //printf(">>> Got %s: len=%lu left=%lu (event %i)\n", data, len, left, 50-max_events);
+ return (char*)data;
+ }
+ }
+ return NULL;
+}
+
+bool RetrieveBuffer(std::string& text, std::string::size_type& pos)
+{
+ SDL_SysWMinfo info;
+
+ //printf("Retrieving buffer...\n");
+ SDL_VERSION(&info.version);
+ if ( SDL_GetWMInfo(&info) )
+ {
+ Display *dpy = info.info.x11.display;
+ Window us = info.info.x11.window;
+ char *data = NULL;
+
+ if (!data)
+ {
+ data = getSelection(dpy, us, XA_PRIMARY);
+ }
+ if (!data)
+ {
+ data = getSelection(dpy, us, XA_SECONDARY);
+ }
+ if (!data)
+ {
+ Atom XA_CLIPBOARD = XInternAtom(dpy, "CLIPBOARD", 0);
+ data = getSelection(dpy, us, XA_CLIPBOARD);
+ }
+ if (data)
+ {
+ // check cursor position
+ if (pos > text.size()) {
+ pos = text.size();
+ }
+
+ text.insert(pos, data);
+ pos += strlen(data);
+ XFree(data);
+
+ return true;
+ }
+ }
+ return false;
+}
+#else
+bool RetrieveBuffer(std::string&, std::string::size_type&) { return false; }
+#endif
diff --git a/src/utils/copynpaste.h b/src/utils/copynpaste.h
new file mode 100644
index 000000000..1a7c81d05
--- /dev/null
+++ b/src/utils/copynpaste.h
@@ -0,0 +1,33 @@
+/*
+ * Retrieve string pasted depending on OS mechanisms.
+ * Copyright (C) 2001-2010 Wormux Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <string>
+
+/**
+ * Attempts to retrieve text from the clipboard buffer and inserts it in
+ * \a text at position \pos. The characters are encoded in utf-8.
+ *
+ * Implemented for Windows, X11 and Mac OS X.
+ *
+ * @return <code>true</code> when successful or <code>false</code> when there
+ * was a problem retrieving the clipboard buffer.
+ */
+bool RetrieveBuffer(std::string& text, std::string::size_type& pos);
+
diff --git a/src/utils/dtor.h b/src/utils/dtor.h
new file mode 100644
index 000000000..a50189c4e
--- /dev/null
+++ b/src/utils/dtor.h
@@ -0,0 +1,54 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UTILS_DTOR_H
+#define UTILS_DTOR_H
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+template<typename T>
+struct dtor : public std::unary_function <T, void>
+{
+ void operator()(T &ptr) { delete ptr; }
+};
+
+template<typename T1, typename T2>
+struct dtor<std::pair<T1, T2> > :
+public std::unary_function <std::pair<T1, T2>, void>
+{
+ void operator()(std::pair<T1, T2> &pair) { delete pair.second; }
+};
+
+template<class Cont>
+inline dtor<typename Cont::value_type> make_dtor(Cont const&)
+{
+ return dtor<typename Cont::value_type>();
+}
+
+template<typename Container>
+inline void delete_all(Container &c)
+{
+ std::for_each(c.begin(), c.end(), make_dtor(c));
+}
+
+#endif
diff --git a/src/utils/gettext.h b/src/utils/gettext.h
new file mode 100644
index 000000000..feeb6595b
--- /dev/null
+++ b/src/utils/gettext.h
@@ -0,0 +1,44 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UTILS_GETTEXT_H
+#define UTILS_GETTEXT_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libintl.h>
+
+#if ENABLE_NLS
+
+#define _(s) (const_cast <char*>(gettext(s)))
+#define N_(s) (const_cast <char*>(s))
+
+#else
+
+#define gettext(s) (const_cast <char*>(s))
+#define _(s) (const_cast <char*>(s))
+#define N_(s) (const_cast <char*>(s))
+
+#endif
+
+#endif // UTILS_GETTEXT_H
diff --git a/src/utils/mathutils.h b/src/utils/mathutils.h
new file mode 100644
index 000000000..4917b5566
--- /dev/null
+++ b/src/utils/mathutils.h
@@ -0,0 +1,114 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UTILS_MATHUTILS_H
+#define UTILS_MATHUTILS_H
+
+#include <stdint.h>
+
+static uint16_t crc_table[256] =
+{
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+inline uint16_t getCrc16(const std::string &str)
+{
+ size_t f = str.size();
+ uint16_t crc16 = 0xffff;
+
+ while (f != 0)
+ {
+ f --;
+ crc16 = static_cast<uint16_t>(
+ crc_table[(crc16 ^ (str[f])) & 0xff] ^ (crc16 >> 8));
+ }
+
+ return crc16;
+}
+
+/* A very fast function to calculate the approximate inverse square root of a
+ * floating point value and a helper function that uses it for getting the
+ * normal squareroot. For an explanation of the inverse squareroot function
+ * read:
+ * http://www.math.purdue.edu/~clomont/Math/Papers/2003/InvSqrt.pdf
+ *
+ * Unfortunately the original creator of this function seems to be unknown.
+ */
+
+inline float fastInvSqrt(float x)
+{
+ union { int i; float x; } tmp;
+ float xhalf = 0.5f * x;
+ tmp.x = x;
+ tmp.i = 0x5f375a86 - (tmp.i >> 1);
+ x = tmp.x;
+ x = x * (1.5f - xhalf * x * x);
+ return x;
+}
+
+inline float fastSqrt(float x)
+{
+ return 1.0f / fastInvSqrt(x);
+}
+
+inline float weightedAverage(float n1, float n2, float w)
+{
+ if (w < 0.0f)
+ return n1;
+
+ if (w > 1.0f)
+ return n2;
+
+ return w * n2 + (1.0f - w) * n1;
+}
+
+#endif // UTILS_MATHUTILS_H
diff --git a/src/utils/mkdir.cpp b/src/utils/mkdir.cpp
new file mode 100644
index 000000000..e7b126ae7
--- /dev/null
+++ b/src/utils/mkdir.cpp
@@ -0,0 +1,118 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <climits>
+#include <cstring>
+#include <cerrno>
+
+#if defined WIN32
+#include <windows.h>
+#endif
+
+#include <sys/stat.h>
+
+#ifdef _MKDIR_TEST_
+// compile with -D_MKDIR_TEST_ to get a standalone binary
+#include <cstdio>
+#include <cstdlib>
+#endif
+
+#include "mkdir.h"
+
+int mkdir_r(const char *pathname)
+{
+ char tmp[PATH_MAX];
+ char *p;
+
+ if (strlen(pathname) >= PATH_MAX - 2)
+ return -1;
+
+ strncpy(tmp, pathname, sizeof(tmp) - 1);
+ tmp[PATH_MAX - 1] = '\0';
+
+ int len = strlen(tmp);
+
+ // terminate the pathname with '/'
+ if (tmp[len - 1] != '/')
+ {
+ tmp[len] = '/';
+ tmp[len + 1] = '\0';
+ }
+
+ for (p = tmp; *p; p++)
+ {
+#if defined WIN32
+ if (*p == '/' || *p == '\\')
+#else
+ if (*p == '/')
+#endif
+ {
+ *p = '\0';
+ // ignore a slash at the beginning of a path
+ if (strlen(tmp) == 0)
+ {
+ *p = '/';
+ continue;
+ }
+
+ // check if the name already exists, but not as directory
+ struct stat statbuf;
+ if (!stat(tmp, &statbuf))
+ {
+ if (S_ISDIR(statbuf.st_mode))
+ {
+ *p = '/';
+ continue;
+ }
+ else
+ return -1;
+ }
+
+#if defined WIN32
+ if (!CreateDirectory(tmp, 0))
+#else
+ if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
+#endif
+ {
+#if defined WIN32
+ // hack, hack. just assume that x: might be a drive
+ // letter, and try again
+ if (!(strlen(tmp) == 2 &&
+ !strcmp(tmp + 1, ":")))
+#endif
+ return -1;
+ }
+
+#ifdef _MKDIR_TEST_
+ printf("%s\n", tmp);
+#endif
+ *p = '/';
+ }
+ }
+ return 0;
+}
+
+#ifdef _MKDIR_TEST_
+int main(int argc, char** argv)
+{
+ if (argc < 2) exit(1);
+ mkdir_r(argv[1]);
+}
+#endif
diff --git a/src/utils/mkdir.h b/src/utils/mkdir.h
new file mode 100644
index 000000000..9369b4e7b
--- /dev/null
+++ b/src/utils/mkdir.h
@@ -0,0 +1,26 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef _MKDIR_H
+#define _MKDIR_H
+
+int mkdir_r(const char *pathname);
+
+#endif
diff --git a/src/utils/mutex.h b/src/utils/mutex.h
new file mode 100644
index 000000000..f98bcdfec
--- /dev/null
+++ b/src/utils/mutex.h
@@ -0,0 +1,97 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef MUTEX_H
+#define MUTEX_H
+
+#include "log.h"
+
+#include <SDL_thread.h>
+
+/**
+ * A mutex provides mutual exclusion of access to certain data that is
+ * accessed by multiple threads.
+ */
+class Mutex
+{
+public:
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+
+private:
+ Mutex(const Mutex&); // prevent copying
+ Mutex& operator=(const Mutex&);
+
+ SDL_mutex *mMutex;
+};
+
+/**
+ * A convenience class for locking a mutex.
+ */
+class MutexLocker
+{
+public:
+ MutexLocker(Mutex *mutex);
+ ~MutexLocker();
+
+private:
+ Mutex *mMutex;
+};
+
+
+inline Mutex::Mutex()
+{
+ mMutex = SDL_CreateMutex();
+}
+
+inline Mutex::~Mutex()
+{
+ SDL_DestroyMutex(mMutex);
+}
+
+inline void Mutex::lock()
+{
+ if (SDL_mutexP(mMutex) == -1)
+ logger->log("Mutex locking failed: %s", SDL_GetError());
+}
+
+inline void Mutex::unlock()
+{
+ if (SDL_mutexV(mMutex) == -1)
+ logger->log("Mutex unlocking failed: %s", SDL_GetError());
+}
+
+
+inline MutexLocker::MutexLocker(Mutex *mutex):
+ mMutex(mutex)
+{
+ mMutex->lock();
+}
+
+inline MutexLocker::~MutexLocker()
+{
+ mMutex->unlock();
+}
+
+#endif // MUTEX_H
diff --git a/src/utils/sha256.cpp b/src/utils/sha256.cpp
new file mode 100644
index 000000000..29bbed29f
--- /dev/null
+++ b/src/utils/sha256.cpp
@@ -0,0 +1,294 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file has been slighly modified as part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2008 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* m_sha256 - Based on m_opersha256 written by Special <john@yarbbles.com>
+ * Modified and improved by Craig Edwards, December 2006.
+ *
+ *
+ * FIPS 180-2 SHA-224/256/384/512 implementation
+ * Last update: 05/23/2005
+ * Issue date: 04/30/2005
+ *
+ * Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "utils/sha256.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <memory.h>
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+#endif
+
+#define SHA256_BLOCK_SIZE (512 / 8)
+
+/** An sha 256 context, used by original m_opersha256 */
+class SHA256Context
+{
+ public:
+ unsigned int tot_len;
+ unsigned int len;
+ unsigned char block[2 * SHA256_BLOCK_SIZE];
+ uint32_t h[8];
+};
+
+#define SHA256_DIGEST_SIZE (256 / 8)
+
+#define SHFR(x, n) (x >> n)
+#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
+#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
+#define CH(x, y, z) ((x & y) ^ (~x & z))
+#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+
+#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
+#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
+
+#define UNPACK32(x, str) \
+{ \
+ *((str) + 3) = (uint8_t) ((x) ); \
+ *((str) + 2) = (uint8_t) ((x) >> 8); \
+ *((str) + 1) = (uint8_t) ((x) >> 16); \
+ *((str) + 0) = (uint8_t) ((x) >> 24); \
+}
+
+#define PACK32(str, x) \
+{ \
+ *(x) = ((uint32_t) *((str) + 3) ) \
+ | ((uint32_t) *((str) + 2) << 8) \
+ | ((uint32_t) *((str) + 1) << 16) \
+ | ((uint32_t) *((str) + 0) << 24); \
+}
+
+/* Macros used for loops unrolling */
+
+#define SHA256_SCR(i) \
+{ \
+ w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
+ + SHA256_F3(w[i - 15]) + w[i - 16]; \
+}
+
+const unsigned int sha256_h0[8] =
+{
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+};
+
+uint32_t sha256_k[64] =
+{
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+void SHA256Init(SHA256Context *ctx);
+
+void SHA256Transform(SHA256Context *ctx,
+ unsigned char *message,
+ unsigned int block_nb);
+
+void SHA256Update(SHA256Context *ctx,
+ unsigned char *message,
+ unsigned int len);
+
+void SHA256Final(SHA256Context *ctx, unsigned char *digest);
+
+std::string SHA256Hash(const char *src, int len);
+
+void SHA256Init(SHA256Context *ctx)
+{
+ for (int i = 0; i < 8; i++)
+ ctx->h[i] = sha256_h0[i];
+ ctx->len = 0;
+ ctx->tot_len = 0;
+}
+
+void SHA256Transform(SHA256Context *ctx,
+ unsigned char *message,
+ unsigned int block_nb)
+{
+ uint32_t w[64];
+ uint32_t wv[8];
+ unsigned char *sub_block;
+ for (unsigned int i = 1; i <= block_nb; i++)
+ {
+ int j;
+ sub_block = message + ((i - 1) << 6);
+
+ for (j = 0; j < 16; j++)
+ PACK32(&sub_block[j << 2], &w[j]);
+ for (j = 16; j < 64; j++)
+ SHA256_SCR(j);
+ for (j = 0; j < 8; j++)
+ wv[j] = ctx->h[j];
+ for (j = 0; j < 64; j++)
+ {
+ uint32_t t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha256_k[j] + w[j];
+ uint32_t t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
+ wv[7] = wv[6];
+ wv[6] = wv[5];
+ wv[5] = wv[4];
+ wv[4] = wv[3] + t1;
+ wv[3] = wv[2];
+ wv[2] = wv[1];
+ wv[1] = wv[0];
+ wv[0] = t1 + t2;
+ }
+ for (j = 0; j < 8; j++)
+ ctx->h[j] += wv[j];
+ }
+}
+
+void SHA256Update(SHA256Context *ctx,
+ unsigned char *message,
+ unsigned int len)
+{
+ /*
+ * XXX here be dragons!
+ * After many hours of pouring over this, I think I've found the problem.
+ * When Special created our module from the reference one, he used:
+ *
+ * unsigned int rem_len = SHA256_BLOCK_SIZE - ctx->len;
+ *
+ * instead of the reference's version of:
+ *
+ * unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len;
+ * unsigned int rem_len = len < tmp_len ? len : tmp_len;
+ *
+ * I've changed back to the reference version of this code, and it seems to work with no errors.
+ * So I'm inclined to believe this was the problem..
+ * -- w00t (January 06, 2008)
+ */
+ unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len;
+ unsigned int rem_len = len < tmp_len ? len : tmp_len;
+
+ memcpy(&ctx->block[ctx->len], message, rem_len);
+ if (ctx->len + len < SHA256_BLOCK_SIZE)
+ {
+ ctx->len += len;
+ return;
+ }
+ unsigned int new_len = len - rem_len;
+ unsigned int block_nb = new_len / SHA256_BLOCK_SIZE;
+ unsigned char *shifted_message = message + rem_len;
+ SHA256Transform(ctx, ctx->block, 1);
+ SHA256Transform(ctx, shifted_message, block_nb);
+ rem_len = new_len % SHA256_BLOCK_SIZE;
+ memcpy(ctx->block, &shifted_message[block_nb << 6],rem_len);
+ ctx->len = rem_len;
+ ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void SHA256Final(SHA256Context *ctx, unsigned char *digest)
+{
+ unsigned int block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE)));
+ unsigned int len_b = (ctx->tot_len + ctx->len) << 3;
+ unsigned int pm_len = block_nb << 6;
+ memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+ ctx->block[ctx->len] = 0x80;
+ UNPACK32(len_b, ctx->block + pm_len - 4);
+ SHA256Transform(ctx, ctx->block, block_nb);
+ for (int i = 0 ; i < 8; i++)
+ UNPACK32(ctx->h[i], &digest[i << 2]);
+}
+
+std::string SHA256Hash(const char *src, int len)
+{
+ // Generate the hash
+ unsigned char bytehash[SHA256_DIGEST_SIZE];
+ SHA256Context ctx;
+ SHA256Init(&ctx);
+ SHA256Update(&ctx, (unsigned char *)src, (unsigned int)len);
+ SHA256Final(&ctx, bytehash);
+ // Convert it to hex
+ const char* hxc = "0123456789abcdef";
+ std::string hash = "";
+ for (int i = 0; i < SHA256_DIGEST_SIZE; i++)
+ {
+ hash += hxc[bytehash[i] / 16];
+ hash += hxc[bytehash[i] % 16];
+ }
+ return hash;
+}
+
+std::string sha256(const std::string &string)
+{
+ return SHA256Hash(string.c_str(), string.length());
+}
diff --git a/src/utils/sha256.h b/src/utils/sha256.h
new file mode 100644
index 000000000..1248e8ddd
--- /dev/null
+++ b/src/utils/sha256.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UTILS_SHA256_H
+#define UTILS_SHA256_H
+
+#include <string>
+
+/**
+ * Returns the SHA-256 hash for the given string.
+ *
+ * @param string the string to create the SHA-256 hash for
+ * @return the SHA-256 hash for the given string.
+ */
+std::string sha256(const std::string &string);
+
+#endif // UTILS_SHA256_H
diff --git a/src/utils/specialfolder.cpp b/src/utils/specialfolder.cpp
new file mode 100644
index 000000000..646077161
--- /dev/null
+++ b/src/utils/specialfolder.cpp
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifdef WIN32
+#include "specialfolder.h"
+#include <windows.h>
+
+#ifdef _SPECIALFOLDERLOCATION_TEST_
+// compile with -D_SPECIALFOLDERLOCATION_TEST_ to get a standalone
+// binary for testing
+#include <iostream>
+#endif
+
+/*
+ * Retrieve the pathname of special folders on win32, or an empty string
+ * on error / if the folder does not exist.
+ * See http://msdn.microsoft.com/en-us/library/bb762494(VS.85).aspx for
+ * a list of folder ids
+ */
+std::string getSpecialFolderLocation(int folderId)
+{
+ std::string ret;
+ LPITEMIDLIST pItemIdList;
+ LPMALLOC pMalloc;
+ char szPath[_MAX_PATH];
+
+ // get the item ID list for folderId
+ HRESULT hr = SHGetSpecialFolderLocation(NULL, folderId, &pItemIdList);
+ if (hr != S_OK)
+ return ret;
+
+ // convert the ID list into a file system path
+ if (SHGetPathFromIDList(pItemIdList, szPath) == FALSE)
+ return ret;
+
+ // get the IMalloc pointer and free all resources we used
+ hr = SHGetMalloc(&pMalloc);
+ pMalloc->Free(pItemIdList);
+ pMalloc->Release();
+
+ ret = szPath;
+ return ret;
+}
+
+#ifdef _SPECIALFOLDERLOCATION_TEST_
+int main()
+{
+ std::cout << "APPDATA " << getSpecialFolderLocation(CSIDL_APPDATA)
+ << std::endl;
+ std::cout << "DESKTOP " << getSpecialFolderLocation(CSIDL_DESKTOP)
+ << std::endl;
+ std::cout << "LOCAL_APPDATA "
+ << getSpecialFolderLocation(CSIDL_LOCAL_APPDATA)
+ << std::endl;
+ std::cout << "MYPICTURES " << getSpecialFolderLocation(CSIDL_MYPICTURES)
+ << std::endl;
+ std::cout << "PERSONAL " << getSpecialFolderLocation(CSIDL_PERSONAL)
+ << std::endl;
+}
+#endif
+#endif
diff --git a/src/utils/specialfolder.h b/src/utils/specialfolder.h
new file mode 100644
index 000000000..c2c2e0bea
--- /dev/null
+++ b/src/utils/specialfolder.h
@@ -0,0 +1,30 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef _SPECIALFOLDER_H
+#define _SPECIALFOLDER_H
+
+#ifdef WIN32
+#include <shlobj.h>
+#include <string>
+std::string getSpecialFolderLocation(int folderId);
+#endif
+
+#endif
diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp
new file mode 100644
index 000000000..e69b03937
--- /dev/null
+++ b/src/utils/stringutils.cpp
@@ -0,0 +1,360 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "utils/stringutils.h"
+
+#include <string.h>
+#include <algorithm>
+#include <cstdarg>
+#include <cstdio>
+#include <list>
+
+static int UTF8_MAX_SIZE = 10;
+
+std::string &trim(std::string &str)
+{
+ std::string::size_type pos = str.find_last_not_of(' ');
+ if (pos != std::string::npos)
+ {
+ str.erase(pos + 1);
+ pos = str.find_first_not_of(' ');
+
+ if (pos != std::string::npos)
+ str.erase(0, pos);
+ }
+ else
+ {
+ // There is nothing else but whitespace in the string
+ str.clear();
+ }
+ return str;
+}
+
+std::string &toLower(std::string &str)
+{
+ std::transform(str.begin(), str.end(), str.begin(), tolower);
+ return str;
+}
+
+std::string &toUpper(std::string &str)
+{
+ std::transform(str.begin(), str.end(), str.begin(), toupper);
+ return str;
+}
+
+unsigned int atox(const std::string &str)
+{
+ unsigned int value;
+ sscanf(str.c_str(), "0x%06x", &value);
+
+ return value;
+}
+
+const char *ipToString(int address)
+{
+ static char asciiIP[18];
+
+ sprintf(asciiIP, "%i.%i.%i.%i",
+ (unsigned char)(address),
+ (unsigned char)(address >> 8),
+ (unsigned char)(address >> 16),
+ (unsigned char)(address >> 24));
+
+ return asciiIP;
+}
+
+std::string strprintf(char const *format, ...)
+{
+ char buf[257];
+ va_list(args);
+ va_start(args, format);
+ int nb = vsnprintf(buf, 256, format, args);
+ va_end(args);
+ if (nb < 256)
+ return buf;
+
+ // The static size was not big enough, try again with a dynamic allocation.
+ ++nb;
+ char *buf2 = new char[nb];
+ va_start(args, format);
+ vsnprintf(buf2, nb, format, args);
+ va_end(args);
+ std::string res(buf2);
+ delete [] buf2;
+ return res;
+}
+
+std::string &removeBadChars(std::string &str)
+{
+ std::string::size_type pos;
+ do
+ {
+ pos = str.find_first_of("@#[]");
+ if (pos != std::string::npos)
+ str.erase(pos, 1);
+ }
+ while (pos != std::string::npos);
+
+ return str;
+}
+
+std::string removeColors(std::string msg)
+{
+ for (unsigned int f = 0; f < msg.length() - 2 && msg.length() > 2; f++)
+ {
+ while (msg.length() > f + 2 && msg.at(f) == '#'
+ && msg.at(f + 1) == '#')
+ {
+ msg = msg.erase(f, 3);
+ }
+ }
+ return msg;
+}
+
+int compareStrI(const std::string &a, const std::string &b)
+{
+ std::string::const_iterator itA = a.begin();
+ std::string::const_iterator endA = a.end();
+ std::string::const_iterator itB = b.begin();
+ std::string::const_iterator endB = b.end();
+
+ for (; itA < endA, itB < endB; ++itA, ++itB)
+ {
+ int comp = tolower(*itA) - tolower(*itB);
+ if (comp)
+ return comp;
+ }
+
+ // Check string lengths
+ if (itA == endA && itB == endB)
+ return 0;
+ else if (itA == endA)
+ return -1;
+ else
+ return 1;
+}
+
+
+bool isWordSeparator(char chr)
+{
+ return (chr == ' ' || chr == ',' || chr == '.' || chr == '"');
+}
+
+const std::string findSameSubstring(const std::string &str1,
+ const std::string &str2)
+{
+ int minLength = str1.length() > str2.length()
+ ? static_cast<int>(str2.length()) : static_cast<int>(str1.length());
+ for (int f = 0; f < minLength; f ++)
+ {
+ if (str1.at(f) != str2.at(f))
+ return str1.substr(0, f);
+ }
+ return str1.substr(0, minLength);
+}
+
+unsigned long findI(std::string str, std::string subStr)
+{
+ str = toLower(str);
+ subStr = toLower(subStr);
+ return str.find(subStr);
+}
+
+unsigned long findI(std::string str, std::list<std::string> &list)
+{
+ str = toLower(str);
+ unsigned long idx;
+ for (std::list<std::string>::iterator i = list.begin();
+ i != list.end(); i++)
+ {
+ std::string subStr = toLower(*i);
+ idx = str.find(subStr);
+ if (idx != std::string::npos)
+ return idx;
+ }
+ return std::string::npos;
+}
+
+int base = 94;
+int start = 33;
+
+const std::string encodeStr(unsigned int value, unsigned int size)
+{
+ std::string buf;
+
+ do
+ {
+ buf += static_cast<char>(value % base + start);
+ value /= base;
+ }
+ while (value);
+
+ while (buf.length() < size)
+ buf += (char)start;
+ return buf;
+}
+
+
+unsigned int decodeStr(const std::string &str)
+{
+ if (str.empty())
+ return 0;
+
+ int res = str[0] - start;
+ int mult = 1;
+ for (unsigned int f = 1; f < str.length(); f ++)
+ {
+ mult *= base;
+ res = res + (str[f] - start) * mult;
+ }
+ return res;
+}
+
+std::string extractNameFromSprite(std::string str)
+{
+ size_t pos1 = str.rfind(".");
+ if (pos1 != std::string::npos)
+ {
+ size_t pos2 = str.rfind("/");
+ size_t pos3 = str.rfind("\\");
+ if (pos3 != std::string::npos)
+ {
+ if (pos2 == std::string::npos || pos3 > pos2)
+ pos2 = pos3;
+ }
+ if (pos2 == std::string::npos)
+ pos2 = -1;
+
+ int size = static_cast<int>(pos1) - static_cast<int>(pos2) - 1;
+ if (size > 0)
+ str = str.substr(pos2 + 1, size);
+ }
+ return str;
+}
+
+std::string removeSpriteIndex(std::string str)
+{
+ size_t pos1 = str.rfind("[");
+
+ if (pos1 != std::string::npos)
+ {
+ size_t pos2 = str.rfind("/");
+ size_t pos3 = str.rfind("\\");
+ if (pos3 != std::string::npos)
+ {
+ if (pos2 == std::string::npos || pos3 > pos2)
+ pos2 = pos3;
+ }
+ if (pos2 == std::string::npos)
+ pos2 = -1;
+
+ int size = static_cast<int>(pos1) - static_cast<int>(pos2) - 1;
+ if (size > 0)
+ str = str.substr(pos2 + 1, size);
+ }
+ return str;
+}
+
+const char* getSafeUtf8String(std::string text)
+{
+ int size = static_cast<int>(text.size()) + UTF8_MAX_SIZE;
+ char* buf = new char[size];
+ memcpy(buf, text.c_str(), text.size());
+ memset(buf + text.size(), 0, UTF8_MAX_SIZE);
+ return buf;
+}
+
+void getSafeUtf8String(std::string text, char *buf)
+{
+ int size = static_cast<int>(text.size()) + UTF8_MAX_SIZE;
+ if (size > 65500)
+ text = text.substr(0, 65500);
+ memcpy(buf, text.c_str(), text.size());
+ memset(buf + text.size(), 0, UTF8_MAX_SIZE);
+ return;
+}
+
+std::string getFileName(std::string path)
+{
+ size_t pos = path.rfind("/");
+ if (pos == std::string::npos)
+ pos = path.rfind("\\");
+ if (pos == std::string::npos)
+ return path;
+ return path.substr(pos + 1);
+}
+
+std::string& replaceAll(std::string& context, const std::string& from,
+ const std::string& to)
+{
+ size_t lookHere = 0;
+ size_t foundHere;
+ while ((foundHere = context.find(from, lookHere)) != std::string::npos)
+ {
+ context.replace(foundHere, from.size(), to);
+ lookHere = foundHere + to.size();
+ }
+ return context;
+}
+
+bool getBoolFromString(const std::string &text)
+{
+ std::string txt = text;
+ toLower(trim(txt));
+ if (txt == "true" || txt == "yes" || txt == "on" || txt == "1")
+ return true;
+ else if (txt == "false" || txt == "no" || txt == "off" || txt == "0")
+ return false;
+ else
+ return (bool) atoi(txt.c_str());
+}
+
+void replaceSpecialChars(std::string &text)
+{
+ size_t idx = 0;
+ size_t pos1 = text.find("&");
+ while (pos1 != std::string::npos)
+ {
+ idx = pos1 + 1;
+ if (idx >= text.size())
+ break;
+
+ unsigned f;
+ for (f = idx; f < text.size(); f ++)
+ {
+ if (text[f] < '0' || text[f] > '9')
+ break;
+ }
+ if (idx + 1 < f && text[f] == ';')
+ {
+ std::string str = " ";
+ str[0] = (char)atoi(text.substr(idx, f - idx).c_str());
+ text = text.substr(0, pos1) + str + text.substr(f + 1);
+ pos1 += 1;
+ }
+ else
+ {
+ pos1 = f + 1;
+ }
+
+ pos1 = text.find("&", pos1);
+ }
+} \ No newline at end of file
diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h
new file mode 100644
index 000000000..4532a5b00
--- /dev/null
+++ b/src/utils/stringutils.h
@@ -0,0 +1,159 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UTILS_STRINGUTILS_H
+#define UTILS_STRINGUTILS_H
+
+#include <string>
+#include <sstream>
+#include <list>
+
+/**
+ * Trims spaces off the end and the beginning of the given string.
+ *
+ * @param str the string to trim spaces off
+ * @return a reference to the trimmed string
+ */
+std::string &trim(std::string &str);
+
+/**
+ * Converts the given string to lower case.
+ *
+ * @param str the string to convert to lower case
+ * @return a reference to the given string converted to lower case
+ */
+std::string &toLower(std::string &str);
+
+/**
+ * Converts the given string to upper case.
+ *
+ * @param str the string to convert to upper case
+ * @return a reference to the given string converted to upper case
+ */
+std::string &toUpper(std::string &str);
+
+
+/**
+ * Converts an ascii hexidecimal string to an integer
+ *
+ * @param str the hex string to convert to an int
+ * @return the integer representation of the hex string
+ */
+unsigned int atox(const std::string &str);
+
+/**
+ * Converts the given value to a string using std::stringstream.
+ *
+ * @param arg the value to convert to a string
+ * @return the string representation of arg
+ */
+template<typename T> std::string toString(const T &arg)
+{
+ std::stringstream ss;
+ ss << arg;
+ return ss.str();
+}
+
+/**
+ * Converts the given IP address to a string.
+ *
+ * The returned string is statically allocated, and shouldn't be freed. It is
+ * changed upon the next use of this method.
+ *
+ * @param address the address to convert to a string
+ * @return the string representation of the address
+ */
+const char *ipToString(int address);
+
+/**
+ * A safe version of sprintf that returns a std::string of the result.
+ */
+std::string strprintf(char const *, ...)
+#ifdef __GNUC__
+ /* This attribute is nice: it even works through gettext invokation. For
+ example, gcc will complain that strprintf(_("%s"), 42) is ill-formed. */
+ __attribute__((__format__(__printf__, 1, 2)))
+#endif
+;
+
+/**
+ * Removes bad characters from a string
+ *
+ * @param str the string to remove the bad chars from
+ * @return a reference to the string without bad chars
+ */
+std::string &removeBadChars(std::string &str);
+
+/**
+ * Removes colors from a string
+ *
+ * @param msg the string to remove the colors from
+ * @return string without colors
+ */
+std::string removeColors(std::string msg);
+
+bool isWordSeparator(char chr);
+
+const std::string findSameSubstring(const std::string &str1,
+ const std::string &str2);
+
+/**
+ * Compares the two strings case-insensitively.
+ *
+ * @param a the first string in the comparison
+ * @param b the second string in the comparison
+ * @return 0 if the strings are equal, positive if the first is greater,
+ * negative if the second is greater
+ */
+int compareStrI(const std::string &a, const std::string &b);
+
+unsigned long findI(std::string str, std::string subStr);
+
+unsigned long findI(std::string str, std::list<std::string> &list);
+
+const std::string encodeStr(unsigned int value, unsigned int size = 0);
+
+unsigned int decodeStr(const std::string &str);
+
+std::string extractNameFromSprite(std::string str);
+
+std::string removeSpriteIndex(std::string str);
+
+const char* getSafeUtf8String(std::string text);
+
+void getSafeUtf8String(std::string text, char *buf);
+
+std::string getFileName(std::string path);
+
+std::string& replaceAll(std::string& context, const std::string& from,
+ const std::string& to);
+
+/**
+ * Returns a bool value depending on the given string value.
+ *
+ * @param text the string used to get the bool value
+ * @return a boolean value..
+ */
+bool getBoolFromString(const std::string &text);
+
+void replaceSpecialChars(std::string &text);
+
+#endif // UTILS_STRINGUTILS_H
diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp
new file mode 100644
index 000000000..9521f377d
--- /dev/null
+++ b/src/utils/xml.cpp
@@ -0,0 +1,164 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "utils/xml.h"
+
+#include "log.h"
+
+#include "resources/resourcemanager.h"
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+namespace XML
+{
+ Document::Document(const std::string &filename, bool useResman):
+ mDoc(0)
+ {
+ int size;
+ char *data = NULL;
+ if (useResman)
+ {
+ ResourceManager *resman = ResourceManager::getInstance();
+ data = (char*) resman->loadFile(filename.c_str(), size);
+ }
+ else
+ {
+ std::ifstream file;
+ file.open(filename.c_str(), std::ios::in);
+
+ if (file.is_open())
+ {
+ // Get length of file
+ file.seekg (0, std::ios::end);
+ size = static_cast<int>(file.tellg());
+ file.seekg(0, std::ios::beg);
+
+ data = (char*) malloc(size);
+
+ file.read(data, size);
+ file.close();
+ }
+ else
+ {
+ logger->log("Error loading XML file %s", filename.c_str());
+ }
+ }
+
+ if (data)
+ {
+ mDoc = xmlParseMemory(data, size);
+ free(data);
+
+ if (!mDoc)
+ logger->log("Error parsing XML file %s", filename.c_str());
+ }
+ else
+ {
+ logger->log("Error loading %s", filename.c_str());
+ }
+ }
+
+ Document::Document(const char *data, int size)
+ {
+ if (data)
+ mDoc = xmlParseMemory(data, size);
+ else
+ mDoc = 0;
+ }
+
+ Document::~Document()
+ {
+ if (mDoc)
+ xmlFreeDoc(mDoc);
+ }
+
+ xmlNodePtr Document::rootNode()
+ {
+ return mDoc ? xmlDocGetRootElement(mDoc) : 0;
+ }
+
+ int getProperty(xmlNodePtr node, const char* name, int def)
+ {
+ int &ret = def;
+
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop)
+ {
+ ret = atoi((char*)prop);
+ xmlFree(prop);
+ }
+
+ return ret;
+ }
+
+ double getFloatProperty(xmlNodePtr node, const char* name, double def)
+ {
+ double &ret = def;
+
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop)
+ {
+ ret = atof((char*)prop);
+ xmlFree(prop);
+ }
+
+ return ret;
+ }
+
+ std::string getProperty(xmlNodePtr node, const char *name,
+ const std::string &def)
+ {
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop)
+ {
+ std::string val = (char*)prop;
+ xmlFree(prop);
+ return val;
+ }
+
+ return def;
+ }
+
+ bool getBoolProperty(xmlNodePtr node, const char* name, bool def)
+ {
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+
+ if (xmlStrEqual(prop, BAD_CAST "true" ))
+ return true;
+ if (xmlStrEqual(prop, BAD_CAST "false"))
+ return false;
+ return def;
+ }
+
+ xmlNodePtr findFirstChildByName(xmlNodePtr parent, const char *name)
+ {
+ for_each_xml_child_node(child, parent)
+ {
+ if (xmlStrEqual(child->name, BAD_CAST name))
+ return child;
+ }
+
+ return NULL;
+ }
+
+} // namespace XML
diff --git a/src/utils/xml.h b/src/utils/xml.h
new file mode 100644
index 000000000..253c4e094
--- /dev/null
+++ b/src/utils/xml.h
@@ -0,0 +1,101 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef XML_H
+#define XML_H
+
+#include <libxml/tree.h>
+
+#include <string>
+
+/**
+ * XML helper functions.
+ */
+namespace XML
+{
+ /**
+ * A helper class for parsing an XML document, which also cleans it up
+ * again (RAII).
+ */
+ class Document
+ {
+ public:
+ /**
+ * Constructor that attempts to load the given file through the
+ * resource manager. Logs errors.
+ */
+ Document(const std::string &filename, bool useResman = true);
+
+ /**
+ * Constructor that attempts to load an XML document from memory.
+ * Does not log errors.
+ *
+ * @param data the string to parse as XML
+ * @param size the length of the string in bytes
+ */
+ Document(const char *data, int size);
+
+ /**
+ * Destructor. Frees the loaded XML file.
+ */
+ ~Document();
+
+ /**
+ * Returns the root node of the document (or NULL if there was a
+ * load error).
+ */
+ xmlNodePtr rootNode();
+
+ private:
+ xmlDocPtr mDoc;
+ };
+
+ /**
+ * Gets an floating point property from an xmlNodePtr.
+ */
+ double getFloatProperty(xmlNodePtr node, const char *name, double def);
+
+ /**
+ * Gets an integer property from an xmlNodePtr.
+ */
+ int getProperty(xmlNodePtr node, const char *name, int def);
+
+ /**
+ * Gets a string property from an xmlNodePtr.
+ */
+ std::string getProperty(xmlNodePtr node, const char *name,
+ const std::string &def);
+
+ /**
+ * Gets a boolean property from an xmlNodePtr.
+ */
+ bool getBoolProperty(xmlNodePtr node, const char *name, bool def);
+
+ /**
+ * Finds the first child node with the given name
+ */
+ xmlNodePtr findFirstChildByName(xmlNodePtr parent, const char *name);
+}
+
+#define for_each_xml_child_node(var, parent) \
+ for (xmlNodePtr var = parent->xmlChildrenNode; var; var = var->next)
+
+#endif // XML_H
diff --git a/src/variabledata.h b/src/variabledata.h
new file mode 100644
index 000000000..517324d39
--- /dev/null
+++ b/src/variabledata.h
@@ -0,0 +1,113 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef VARIABLEDATA_H
+#define VARIABLEDATA_H
+
+#include <string>
+
+namespace Mana
+{
+
+class VariableData
+{
+ public:
+ enum
+ {
+ DATA_NONE = 0,
+ DATA_INT,
+ DATA_STRING,
+ DATA_FLOAT,
+ DATA_BOOL
+ };
+
+ virtual ~VariableData()
+ {};
+
+ virtual int getType() const = 0;
+};
+
+class IntData : public VariableData
+{
+ public:
+ IntData(int value)
+ { mData = value; }
+
+ int getData() const
+ { return mData; }
+
+ int getType() const
+ { return DATA_INT; }
+
+ private:
+ int mData;
+};
+
+class StringData : public VariableData
+{
+ public:
+ StringData(const std::string &value)
+ { mData = value; }
+
+ const std::string &getData() const
+ { return mData; }
+
+ int getType() const
+ { return DATA_STRING; }
+
+ private:
+ std::string mData;
+};
+
+class FloatData : public VariableData
+{
+ public:
+ FloatData(double value)
+ { mData = value; }
+
+ double getData() const
+ { return mData; }
+
+ int getType() const
+ { return DATA_FLOAT; }
+
+ private:
+ double mData;
+};
+
+class BoolData : public VariableData
+{
+ public:
+ BoolData(bool value)
+ { mData = value; }
+
+ bool getData() const
+ { return mData; }
+
+ int getType() const
+ { return DATA_BOOL; }
+
+ private:
+ bool mData;
+};
+
+} // namespace Mana
+
+#endif
diff --git a/src/vector.cpp b/src/vector.cpp
new file mode 100644
index 000000000..e6f4e5bbf
--- /dev/null
+++ b/src/vector.cpp
@@ -0,0 +1,28 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "vector.h"
+
+std::ostream& operator <<(std::ostream &os, const Vector &v)
+{
+ os << "Vector(" << v.x << ", " << v.y << ", " << v.z << ")";
+ return os;
+}
diff --git a/src/vector.h b/src/vector.h
new file mode 100644
index 000000000..163dcdbda
--- /dev/null
+++ b/src/vector.h
@@ -0,0 +1,199 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <math.h>
+
+#include <iostream>
+
+/**
+ * Vector class. Represents either a 3D point in space, a velocity or a force.
+ * Provides several convenient operator overloads.
+ */
+class Vector
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Vector():
+ x(0.0f),
+ y(0.0f),
+ z(0.0f)
+ {}
+
+ /**
+ * Constructor.
+ */
+ Vector(float x, float y, float z = 0.0f):
+ x(x),
+ y(y),
+ z(z)
+ {}
+
+ /**
+ * Copy constructor.
+ */
+ Vector(const Vector &v):
+ x(v.x),
+ y(v.y),
+ z(v.z)
+ {}
+
+ /**
+ * Returns true if all coordinates are set to 0, otherwise returns
+ * false.
+ */
+ bool isNull() const
+ {
+ return x == 0.0f && y == 0.0f && z == 0.0f;
+ }
+
+ /**
+ * Scale vector operator.
+ */
+ Vector operator*(float c) const
+ {
+ return Vector(x * c,
+ y * c,
+ z * c);
+ }
+
+ /**
+ * In-place scale vector operator.
+ */
+ Vector &operator*=(float c)
+ {
+ x *= c;
+ y *= c;
+ z *= c;
+ return *this;
+ }
+
+ /**
+ * Scale vector operator.
+ */
+ Vector operator/(float c) const
+ {
+ return Vector(x / c,
+ y / c,
+ z / c);
+ }
+
+ /**
+ * In-place scale vector operator.
+ */
+ Vector &operator/=(float c)
+ {
+ x /= c;
+ y /= c;
+ z /= c;
+ return *this;
+ }
+
+ /**
+ * Add vector operator.
+ */
+ Vector operator+(const Vector &v) const
+ {
+ return Vector(x + v.x,
+ y + v.y,
+ z + v.z);
+ }
+
+ /**
+ * In-place add vector operator.
+ */
+ Vector &operator+=(const Vector &v)
+ {
+ x += v.x;
+ y += v.y;
+ z += v.z;
+ return *this;
+ }
+
+ /**
+ * Subtract vector operator.
+ */
+ Vector operator-(const Vector &v) const
+ {
+ return Vector(x - v.x,
+ y - v.y,
+ z - v.z);
+ }
+
+ /**
+ * In-place subtract vector operator.
+ */
+ Vector &operator-=(const Vector &v)
+ {
+ x -= v.x;
+ y -= v.y;
+ z -= v.z;
+ return *this;
+ }
+
+ /**
+ * Returns the length of this vector. This method does a relatively
+ * slow square root.
+ */
+ float length() const
+ {
+ return sqrtf(x * x + y * y + z * z);
+ }
+
+ /**
+ * Returns the squared length of this vector. Avoids the square root.
+ */
+ float squaredLength() const
+ {
+ return x * x + y * y + z * z;
+ }
+
+ /**
+ * Returns the manhattan length of this vector.
+ */
+ float manhattanLength() const
+ {
+ return fabsf(x) + fabsf(y) + fabsf(z);
+ }
+
+ /**
+ * Returns a normalized version of this vector. This is a unit vector
+ * running parallel to it.
+ */
+ Vector normalized() const
+ {
+ const float l = length();
+ return Vector(x / l, y / l, z / l);
+ }
+
+ float x, y, z;
+};
+
+/**
+ * Appends a string representation of a vector to the output stream.
+ */
+std::ostream& operator <<(std::ostream &os, const Vector &v);
+
+#endif // VECTOR_H
diff --git a/src/winver.h b/src/winver.h
new file mode 100644
index 000000000..4ff552db1
--- /dev/null
+++ b/src/winver.h
@@ -0,0 +1,6 @@
+/* VERSION DEFINITIONS */
+#define VER_MAJOR 1
+#define VER_MINOR 0
+#define VER_RELEASE 0
+#define VER_BUILD 0
+#define PACKAGE_VERSION "1.0.0"
diff --git a/src/winver.h.in b/src/winver.h.in
new file mode 100644
index 000000000..fb0aac2c0
--- /dev/null
+++ b/src/winver.h.in
@@ -0,0 +1,6 @@
+/* VERSION DEFINITIONS */
+#define VER_MAJOR ${VER_MAJOR}
+#define VER_MINOR ${VER_MINOR}
+#define VER_RELEASE ${VER_RELEASE}
+#define VER_BUILD ${VER_BUILD}
+#define PACKAGE_VERSION "${VERSION}"
diff --git a/toolchain.cmake b/toolchain.cmake
new file mode 100644
index 000000000..dd2e1a90e
--- /dev/null
+++ b/toolchain.cmake
@@ -0,0 +1,33 @@
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Windows)
+
+# toolchain prefix, can be overridden by -DTOOLCHAIN=...
+# IF (NOT TOOLCHAIN)
+SET(TOOLCHAIN "i586-mingw32msvc-")
+# ENDIF()
+
+# which compilers to use for C and C++
+SET(CMAKE_C_COMPILER ${TOOLCHAIN}gcc)
+SET(CMAKE_CXX_COMPILER ${TOOLCHAIN}g++)
+SET(CMAKE_RC_COMPILER ${TOOLCHAIN}windres)
+
+SET(CMAKE_INSTALL_PREFIX ./win)
+SET(CMAKE_BUILD_TYPE RelWithDebInfo)
+
+SET(SDLIMAGE_INCLUDE_DIR ../mana_win/libs/include/SDL)
+SET(SDLMIXER_INCLUDE_DIR ../mana_win/libs/include/SDL)
+SET(SDLNET_INCLUDE_DIR ../mana_win/libs/include/SDL)
+SET(SDLTTF_INCLUDE_DIR ../mana_win/libs/include/SDL)
+SET(SDL_INCLUDE_DIR ../mana_win/libs/include/SDL)
+
+
+# here is the target environment located
+SET(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc /../mana_win/libs )
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
diff --git a/tools/Reorganize.java b/tools/Reorganize.java
new file mode 100644
index 000000000..0b9c86060
--- /dev/null
+++ b/tools/Reorganize.java
@@ -0,0 +1,198 @@
+/* Reorganize (c) 2006 Bjørn Lindeijer
+ * License: GPL, v2 or later
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.util.Vector;
+import java.io.IOException;
+import java.io.File;
+import javax.imageio.ImageIO;
+
+/**
+ * Tool to reorganize the headgears.
+ */
+public class Reorganize
+{
+ private static final int SPRITE_WIDTH = 60;
+ private static final int SPRITE_HEIGHT = 60;
+ private static final int FRAMES = 10;
+ private static final int DIRECTIONS = 4;
+
+ private static final int HAIR_COLORS = 10;
+ private static final int HAIR_FRAMES = 9;
+ private static final int HAIR_SPRITE_WIDTH = 40;
+ private static final int HAIR_SPRITE_HEIGHT = 40;
+
+ private static final int TRANSPARENT = new Color(255, 0, 255).getRGB();
+
+ public static void main(String[] arg)
+ {
+ if (arg.length != 2) {
+ System.out.println("Usage:\n java Reorganize [source] [target]");
+ return;
+ }
+
+ BufferedImage source = null;
+ try {
+ source = ImageIO.read(new File(arg[0]));
+ } catch (IOException e) {
+ System.out.println("Error while trying to read " + arg[0] + ".");
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ // Read the existing frames into a vector
+ Vector<BufferedImage> spriteSet = gridCut(source,
+ HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT,
+ HAIR_FRAMES, 1);
+
+ // Determine minimal rectangle that can still contain the contents of
+ // any frame
+ /*
+ Rectangle cropRect = minimumCropRect(spriteSet);
+
+ if (cropRect == null) {
+ System.out.println(
+ "Error: no optimal crop rect could be determined.");
+ System.exit(1);
+ }
+
+ System.out.println(arg[0] + ": width=\"" +
+ cropRect.width + "\" height=\"" + cropRect.height + "\"");
+ */
+
+ filterHeadgear(spriteSet);
+
+ BufferedImage target = gridDraw(
+ spriteSet,
+ new Rectangle(0, 0, HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT),
+ HAIR_FRAMES - 4, 1);
+
+ // Save the target image
+ try {
+ ImageIO.write(target, "png", new File(arg[1]));
+ } catch (IOException e) {
+ System.out.println("Error while trying to write " + arg[1] + ".");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static Vector<BufferedImage> gridCut(
+ BufferedImage source,
+ int width, int height, int xFrames, int yFrames)
+ {
+ Vector<BufferedImage> spriteSet = new Vector<BufferedImage>();
+
+ for (int y = 0; y < yFrames; y++) {
+ for (int x = 0; x < xFrames; x++) {
+ BufferedImage sprite = source.getSubimage(
+ x * width,
+ y * height,
+ width,
+ height);
+
+ spriteSet.add(sprite);
+ }
+ }
+
+ return spriteSet;
+ }
+
+ private static BufferedImage gridDraw(Vector<BufferedImage> spriteSet,
+ Rectangle cropRect, int xFrames, int yFrames)
+ {
+ // Create a new image
+ BufferedImage target = new BufferedImage(
+ xFrames * cropRect.width,
+ yFrames * cropRect.height,
+ BufferedImage.TYPE_INT_ARGB);
+
+ // Draw the frames onto the target image
+ Graphics g = target.getGraphics();
+ for (int y = 0; y < yFrames; y++) {
+ for (int x = 0; x < xFrames; x++) {
+ g.drawImage(
+ spriteSet.get(x + xFrames * y).getSubimage(
+ cropRect.x,
+ cropRect.y,
+ cropRect.width,
+ cropRect.height),
+ x * cropRect.width,
+ y * cropRect.height,
+ null);
+ }
+ }
+
+ return target;
+ }
+
+ private static Rectangle minimumCropRect(Vector<BufferedImage> spriteSet)
+ {
+ Rectangle cropRect = null;
+
+ for (BufferedImage sprite : spriteSet) {
+ Rectangle frameCropRect = determineCropRect(sprite);
+
+ if (cropRect == null) {
+ cropRect = frameCropRect;
+ } else {
+ cropRect.add(frameCropRect);
+ }
+ }
+
+ // Make crop rect one pixel larger (since we want an inclusive rect)
+ if (cropRect != null) {
+ cropRect.add(
+ cropRect.x + cropRect.width + 1,
+ cropRect.y + cropRect.height + 1);
+ }
+
+ return cropRect;
+ }
+
+ private static Rectangle determineCropRect(BufferedImage image)
+ {
+ // Loop through all the pixels, ignoring transparent ones.
+ Rectangle rect = null;
+
+ for (int y = 0; y < image.getHeight(); y++) {
+ for (int x = 0; x < image.getWidth(); x++) {
+ int color = image.getRGB(x, y);
+
+ if (color != TRANSPARENT && (color & 0xFF000000) != 0) {
+ if (rect == null) {
+ rect = new Rectangle(x, y, 0, 0);
+ } else {
+ rect.add(x, y);
+ }
+ }
+ }
+ }
+
+ return rect;
+ }
+
+ private static void filterHairstyle(Vector<BufferedImage> spriteSet)
+ {
+ // Remove frame 1, 2, 6 and 7 from each color
+ for (int i = HAIR_COLORS - 1; i >= 0; i--) {
+ spriteSet.remove(i * HAIR_FRAMES + 7);
+ spriteSet.remove(i * HAIR_FRAMES + 6);
+ spriteSet.remove(i * HAIR_FRAMES + 2);
+ spriteSet.remove(i * HAIR_FRAMES + 1);
+ }
+ }
+
+ private static void filterHeadgear(Vector<BufferedImage> spriteSet)
+ {
+ // Remove frame 1, 2, 6 and 7
+ spriteSet.remove(7);
+ spriteSet.remove(6);
+ spriteSet.remove(2);
+ spriteSet.remove(1);
+ }
+}
diff --git a/tools/adler32.c b/tools/adler32.c
new file mode 100644
index 000000000..5dd7e4c17
--- /dev/null
+++ b/tools/adler32.c
@@ -0,0 +1,68 @@
+/*
+ * adler32.c (c) 2006 Bjorn Lindeijer
+ * License: GPL, v2 or later
+ *
+ * Calculates Adler-32 checksums for all files passed as argument.
+ *
+ * Usage: adler32 [file]...
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <zlib.h>
+
+/**
+ * Calculates the Adler-32 checksum for the given file.
+ */
+unsigned long fadler32(FILE *file)
+{
+ // Obtain file size
+ fseek(file, 0, SEEK_END);
+ long fileSize = ftell(file);
+ rewind(file);
+
+ // Calculate Adler-32 checksum
+ char *buffer = (char*) malloc(fileSize);
+ fread(buffer, 1, fileSize, file);
+ unsigned long adler = adler32(0L, Z_NULL, 0);
+ adler = adler32(adler, (Bytef*) buffer, fileSize);
+ free(buffer);
+
+ return adler;
+}
+
+/**
+ * Prints out usage and exists.
+ */
+void print_usage()
+{
+ printf("Usage: adler32 [file]...\n");
+ exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+ int i; /**< Loops through arguments. */
+
+ if (argc == 1)
+ {
+ print_usage();
+ }
+
+ for (i = 1; i < argc; ++i)
+ {
+ FILE *file = fopen(argv[i], "r");
+
+ if (!file)
+ {
+ printf("Error while opening '%s' for reading!\n", argv[i]);
+ exit(1);
+ }
+
+ unsigned long adler = fadler32(file);
+ printf("%s %lx\n", argv[i], adler);
+ fclose(file);
+ }
+
+ return 0;
+}
diff --git a/tools/dyecmd/CMakeLists.txt b/tools/dyecmd/CMakeLists.txt
new file mode 100644
index 000000000..485666485
--- /dev/null
+++ b/tools/dyecmd/CMakeLists.txt
@@ -0,0 +1,28 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+PROJECT(MANA_DYECOMMAND)
+
+IF (NOT VERSION)
+ SET(VERSION 1.0.0)
+ENDIF()
+
+STRING(REPLACE "." " " _VERSION ${VERSION})
+SEPARATE_ARGUMENTS(_VERSION)
+LIST(LENGTH _VERSION _LEN)
+IF(NOT (_LEN EQUAL 4 OR _LEN EQUAL 3))
+ MESSAGE(FATAL_ERROR "Version needs to be in the form MAJOR.MINOR.RELEASE[.BUILD]")
+ENDIF()
+
+LIST(GET _VERSION 0 VER_MAJOR)
+LIST(GET _VERSION 1 VER_MINOR)
+LIST(GET _VERSION 2 VER_RELEASE)
+IF(_LEN EQUAL 4)
+ LIST(GET _VERSION 3 VER_BUILD)
+ELSE()
+ SET(VER_BUILD 0)
+ENDIF()
+
+# where to look for cmake modules
+SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
+
+ADD_SUBDIRECTORY(src)
diff --git a/tools/dyecmd/README b/tools/dyecmd/README
new file mode 100644
index 000000000..050a76559
--- /dev/null
+++ b/tools/dyecmd/README
@@ -0,0 +1,12 @@
+DYECMD
+=======
+
+This tool is used to dye item graphics used by the Mana client according to the
+specification described here: http://wiki.themanaworld.org/index.php/Image_dyeing
+
+The tool expects 3 parameters:
+
+dyecmd <source_image> <target_image> <dye_string>
+e.g.:
+dyecmd "armor-legs-shorts.png" "armor-legs-shorts2.png" "W:#222255,6666ff"
+
diff --git a/tools/dyecmd/dyecmd.cbp b/tools/dyecmd/dyecmd.cbp
new file mode 100644
index 000000000..b3d1bb558
--- /dev/null
+++ b/tools/dyecmd/dyecmd.cbp
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="dyecmd" />
+ <Option pch_mode="2" />
+ <Option compiler="gcc" />
+ <Build>
+ <Target title="Debug">
+ <Option output="bin\Debug\dyecmd" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj\Debug\" />
+ <Option type="1" />
+ <Option compiler="gcc" />
+ <Compiler>
+ <Add option="-g" />
+ </Compiler>
+ </Target>
+ <Target title="Release">
+ <Option output="bin\Release\dyecmd" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj\Release\" />
+ <Option type="1" />
+ <Option compiler="gcc" />
+ <Compiler>
+ <Add option="-O2" />
+ </Compiler>
+ <Linker>
+ <Add option="-s" />
+ </Linker>
+ </Target>
+ </Build>
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-fexceptions" />
+ <Add directory="include" />
+ </Compiler>
+ <Linker>
+ <Add library="mingw32" />
+ <Add library="SDLmain" />
+ <Add library="SDL" />
+ <Add library="SDL_image" />
+ <Add library="png12.dll" />
+ <Add directory="lib" />
+ </Linker>
+ <Unit filename="src\dye.cpp" />
+ <Unit filename="src\dye.h" />
+ <Unit filename="src\dyecmd.cpp" />
+ <Unit filename="src\imagewriter.cpp" />
+ <Unit filename="src\imagewriter.h" />
+ <Extensions>
+ <code_completion />
+ <envvars />
+ <debugger />
+ <lib_finder disable_auto="1" />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/tools/dyecmd/run.cmd b/tools/dyecmd/run.cmd
new file mode 100644
index 000000000..86726215f
--- /dev/null
+++ b/tools/dyecmd/run.cmd
@@ -0,0 +1 @@
+bin\debug\dyecmd "armor-legs-shorts.png" "armor-legs-shorts2.png" "W:#222255,6666ff" \ No newline at end of file
diff --git a/tools/dyecmd/src/CMakeLists.txt b/tools/dyecmd/src/CMakeLists.txt
new file mode 100644
index 000000000..f8e717b78
--- /dev/null
+++ b/tools/dyecmd/src/CMakeLists.txt
@@ -0,0 +1,59 @@
+FIND_PACKAGE(SDL REQUIRED)
+FIND_PACKAGE(SDL_image REQUIRED)
+FIND_PACKAGE(PNG REQUIRED)
+
+IF (CMAKE_COMPILER_IS_GNUCXX)
+ # Help getting compilation warnings
+ SET(CMAKE_CXX_FLAGS "-Wall")
+ IF (WIN32)
+ # This includes enough debug information to get something useful
+ # from Dr. Mingw while keeping binary size down. Almost useless
+ # with gdb, though.
+ SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb0 -gstabs2")
+ ENDIF()
+ENDIF()
+
+SET(FLAGS "-DPACKAGE_VERSION=\\\"${VERSION}\\\"")
+SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${PKG_DATADIR}/\\\"")
+SET(FLAGS "${FLAGS} -DLOCALEDIR=\\\"${LOCALEDIR}/\\\"")
+
+IF (CMAKE_BUILD_TYPE)
+ STRING(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TOLOWER)
+ IF((CMAKE_BUILD_TYPE_TOLOWER MATCHES debug) OR
+ (CMAKE_BUILD_TYPE_TOLOWER MATCHES relwithdebinfo))
+ SET(FLAGS "${FLAGS} -DDEBUG")
+ ENDIF()
+ENDIF()
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${SDL_INCLUDE_DIR}
+ ${SDLIMAGE_INCLUDE_DIR}
+ ${PNG_INCLUDE_DIR}
+ )
+
+# Fix some stuff that gets not hidden by mainline modules
+MARK_AS_ADVANCED(SDLIMAGE_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDLIMAGE_LIBRARY)
+MARK_AS_ADVANCED(SDLMAIN_LIBRARY)
+MARK_AS_ADVANCED(SDL_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDL_LIBRARY)
+
+SET(SRCS
+ dye.cpp
+ dye.h
+ dyecmd.cpp
+ imagewriter.cpp
+ imagewriter.h
+ )
+
+SET (PROGRAMS dyecmd)
+
+ADD_EXECUTABLE(dyecmd WIN32 ${SRCS})
+
+TARGET_LINK_LIBRARIES(dyecmd
+ ${SDL_LIBRARY}
+ ${SDLIMAGE_LIBRARY}
+ ${PNG_LIBRARIES})
+
+SET_TARGET_PROPERTIES(dyecmd PROPERTIES COMPILE_FLAGS "${FLAGS}")
diff --git a/tools/dyecmd/src/dye.cpp b/tools/dyecmd/src/dye.cpp
new file mode 100755
index 000000000..77da2ebbb
--- /dev/null
+++ b/tools/dyecmd/src/dye.cpp
@@ -0,0 +1,202 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <algorithm>
+#include <sstream>
+#include <iostream>
+
+#include "dye.h"
+
+Palette::Palette(const std::string &description)
+{
+ mLoaded = false;
+ int size = description.length();
+ if (size == 0) return;
+ if (description[0] != '#')
+ {
+ std::cout << "Missing # in the palette description "
+ << "in the third parameter." << std::endl;
+ return;
+ }
+
+ int pos = 1;
+ for (;;)
+ {
+ if (pos + 6 > size) break;
+ int v = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ char c = description[pos + i];
+ int n;
+ if ('0' <= c && c <= '9')
+ n = c - '0';
+ else if ('A' <= c && c <= 'F')
+ n = c - 'A' + 10;
+ else if ('a' <= c && c <= 'f')
+ n = c - 'a' + 10;
+ else
+ {
+ std::cout << "invalid Hexadecimal description: "
+ << description << std::endl;
+ return;
+ }
+
+ v = (v << 4) | n;
+ }
+ Color c = { { v >> 16, v >> 8, v } };
+ mColors.push_back(c);
+ pos += 6;
+ if (pos == size)
+ {
+ mLoaded = true;
+ return;
+ }
+ if (description[pos] != ',')
+ break;
+
+ ++pos;
+ }
+
+ mLoaded = true;
+}
+
+void Palette::getColor(int intensity, int color[3]) const
+{
+ // Return implicit black
+ if (intensity == 0)
+ {
+ color[0] = 0;
+ color[1] = 0;
+ color[2] = 0;
+ return;
+ }
+
+ int last = mColors.size();
+ if (last == 0) return;
+
+ int i = intensity * last / 255;
+ int t = intensity * last % 255;
+
+ int j = t != 0 ? i : i - 1;
+ // Get the exact color if any, the next color otherwise.
+ int r2 = mColors[j].value[0],
+ g2 = mColors[j].value[1],
+ b2 = mColors[j].value[2];
+
+ if (t == 0)
+ {
+ // Exact color.
+ color[0] = r2;
+ color[1] = g2;
+ color[2] = b2;
+ return;
+ }
+
+ // Get the previous color. First color is implicitly black.
+ int r1 = 0, g1 = 0, b1 = 0;
+ if (i > 0)
+ {
+ r1 = mColors[i - 1].value[0];
+ g1 = mColors[i - 1].value[1];
+ b1 = mColors[i - 1].value[2];
+ }
+
+ // Perform a linear interpolation.
+ color[0] = ((255 - t) * r1 + t * r2) / 255;
+ color[1] = ((255 - t) * g1 + t * g2) / 255;
+ color[2] = ((255 - t) * b1 + t * b2) / 255;
+}
+
+Dye::Dye(const std::string &description)
+{
+ mLoaded = false;
+ for (int i = 0; i < 7; ++i)
+ mPalettes[i] = 0;
+
+ if (description.empty()) return;
+
+ std::string::size_type next_pos = 0, length = description.length();
+ do
+ {
+ std::string::size_type pos = next_pos;
+ next_pos = description.find(';', pos);
+ if (next_pos == std::string::npos)
+ next_pos = length;
+ if (next_pos <= pos + 3 || description[pos + 1] != ':')
+ {
+ std::cout << "Dyeing: Missing ':' in channel description."
+ << std::endl;
+ return;
+ }
+ int i = 0;
+ switch (description[pos])
+ {
+ case 'R': i = 0; break;
+ case 'G': i = 1; break;
+ case 'Y': i = 2; break;
+ case 'B': i = 3; break;
+ case 'M': i = 4; break;
+ case 'C': i = 5; break;
+ case 'W': i = 6; break;
+ default:
+ std::cout << "Dyeing: Invalid channel. Not in [R,G,Y,B,M,C,W]"
+ << std::endl;
+ return;
+ }
+ mPalettes[i] = new Palette(
+ description.substr(pos + 2, next_pos - pos - 2));
+
+ if (!mPalettes[i]->loaded())
+ return;
+
+ ++next_pos;
+ }
+ while (next_pos < length);
+
+ mLoaded = true;
+}
+
+Dye::~Dye()
+{
+ for (int i = 0; i < 7; ++i)
+ delete mPalettes[i];
+}
+
+void Dye::update(int color[3]) const
+{
+ int cmax = std::max(color[0], std::max(color[1], color[2]));
+ if (cmax == 0) return;
+
+ int cmin = std::min(color[0], std::min(color[1], color[2]));
+ int intensity = color[0] + color[1] + color[2];
+
+ if (cmin != cmax &&
+ (cmin != 0 || (intensity != cmax && intensity != 2 * cmax)))
+ {
+ // not pure
+ return;
+ }
+
+ int i = (color[0] != 0) | ((color[1] != 0) << 1) | ((color[2] != 0) << 2);
+
+ if (mPalettes[i - 1])
+ mPalettes[i - 1]->getColor(cmax, color);
+}
diff --git a/tools/dyecmd/src/dye.h b/tools/dyecmd/src/dye.h
new file mode 100755
index 000000000..922f3370e
--- /dev/null
+++ b/tools/dyecmd/src/dye.h
@@ -0,0 +1,105 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2007-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef DYE_H
+#define DYE_H
+
+#include <vector>
+
+#include <string>
+
+/**
+ * Class for performing a linear interpolation between colors.
+ */
+class Palette
+{
+ public:
+
+ /**
+ * Creates a palette based on the given string.
+ * The string is either a file name or a sequence of hexadecimal RGB
+ * values separated by ',' and starting with '#'.
+ */
+ Palette(const std::string &);
+
+ /**
+ * Gets a pixel color depending on its intensity.
+ */
+ void getColor(int intensity, int color[3]) const;
+
+ /**
+ * Tells if the palette was successfully loaded.
+ */
+ bool loaded() const
+ { return mLoaded; }
+
+ private:
+
+ struct Color { unsigned char value[3]; };
+
+ std::vector< Color > mColors;
+
+ bool mLoaded;
+};
+
+/**
+ * Class for dispatching pixel-recoloring amongst several palettes.
+ */
+class Dye
+{
+ public:
+
+ /**
+ * Creates a set of palettes based on the given string.
+ *
+ * The parts of string are separated by semi-colons. Each part starts
+ * by an uppercase letter, followed by a colon and then a palette name.
+ */
+ Dye(const std::string &);
+
+ /**
+ * Destroys the associated palettes.
+ */
+ ~Dye();
+
+ /**
+ * Tells if the dye description was successfully loaded.
+ */
+ bool loaded() const
+ { return mLoaded; }
+
+ /**
+ * Modifies a pixel color.
+ */
+ void update(int color[3]) const;
+
+ private:
+
+ /**
+ * The order of the palettes, as well as their uppercase letter, is:
+ *
+ * Red, Green, Yellow, Blue, Magenta, White (or rather gray).
+ */
+ Palette *mPalettes[7];
+ bool mLoaded;
+};
+
+#endif
diff --git a/tools/dyecmd/src/dyecmd.cpp b/tools/dyecmd/src/dyecmd.cpp
new file mode 100755
index 000000000..5e06e500d
--- /dev/null
+++ b/tools/dyecmd/src/dyecmd.cpp
@@ -0,0 +1,155 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2008-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <iostream>
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+
+#include "dye.h"
+#include "imagewriter.h"
+
+using namespace std;
+
+// return values
+enum ReturnValues
+{
+ RETURN_OK = 0,
+ INVALID_PARAMETER_LIST = 100,
+ INVALID_INPUT_IMAGE = 101,
+ INVALID_OUTPUT_IMAGE = 102,
+ INVALID_DYE_PARAMETER = 105
+};
+
+SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye)
+{
+ SDL_PixelFormat rgba;
+ rgba.palette = NULL;
+ rgba.BitsPerPixel = 32;
+ rgba.BytesPerPixel = 4;
+ rgba.Rmask = 0xFF000000; rgba.Rloss = 0; rgba.Rshift = 24;
+ rgba.Gmask = 0x00FF0000; rgba.Gloss = 0; rgba.Gshift = 16;
+ rgba.Bmask = 0x0000FF00; rgba.Bloss = 0; rgba.Bshift = 8;
+ rgba.Amask = 0x000000FF; rgba.Aloss = 0; rgba.Ashift = 0;
+ rgba.colorkey = 0;
+ rgba.alpha = 255;
+
+ SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE);
+ //SDL_FreeSurface(tmpImage); <-- We'll free the surface later.
+
+ Uint32 *pixels = static_cast< Uint32 * >(surf->pixels);
+ for (Uint32 *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
+ {
+ int alpha = (*pixels >> rgba.Ashift) & 255;
+ if (!alpha) continue;
+ int v[3];
+
+ v[0] = (*pixels >> rgba.Rshift) & 255;
+ v[1] = (*pixels >> rgba.Gshift) & 255;
+ v[2] = (*pixels >> rgba.Bshift) & 255;
+ dye->update(v);
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ *pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha;
+#else
+ *pixels = v[0] | (v[1] << 8) | (v[2] << 16) | (alpha << 24);
+#endif
+ }
+
+ return surf;
+}
+
+void printHelp()
+{
+ cout << endl
+ << "This tool is used to dye item graphics used by the Mana client "
+ << "according to the specification described here: "
+ << endl << "http://doc.manasource.org/image_dyeing_system"
+ << endl << endl <<
+ "The tool expects 3 parameters:" << endl
+ << "dyecmd <source_image> <target_image> <dye_string>" << endl
+ << "e.g.:" << endl
+ << "dyecmd \"armor-legs-shorts.png\" "
+ <<"\"armor-legs-shorts2.png\" \"W:#222255,6666ff\"" << std::endl;
+}
+
+int main(int argc, char* argv[])
+{
+ Dye* dye = NULL;
+ SDL_Surface* source = NULL, *target = NULL;
+ ReturnValues returnValue = RETURN_OK;
+
+ if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
+ {
+ printHelp();
+ }
+ // not enough or to many parameters
+ else if (argc != 4)
+ {
+ cout << INVALID_PARAMETER_LIST << " - INVALID_PARAMETER_LIST";
+ printHelp();
+ returnValue = INVALID_PARAMETER_LIST;
+ }
+ else
+ {
+ // Start dyeing process.
+ string inputFile = argv[1];
+ string outputFile = argv[2];
+ string dyeDescription = argv[3];
+
+ dye = new Dye(dyeDescription);
+ if (!dye->loaded())
+ {
+ cout << INVALID_DYE_PARAMETER << " - INVALID_DYE_PARAMETER";
+ printHelp();
+ returnValue = INVALID_DYE_PARAMETER;
+ }
+ else
+ {
+ source = IMG_Load(inputFile.c_str());
+ if (!source)
+ {
+ cout << INVALID_INPUT_IMAGE << " - INVALID_INPUT_IMAGE";
+ printHelp();
+ returnValue = INVALID_INPUT_IMAGE;
+ }
+ else
+ {
+ target = recolor(source, dye);
+
+ if (!ImageWriter::writePNG(target, outputFile))
+ {
+ cout << INVALID_OUTPUT_IMAGE << " - INVALID_OUTPUT_IMAGE";
+ printHelp();
+ returnValue = INVALID_OUTPUT_IMAGE;
+ }
+ } // Valid source image file
+ } // Valid dye parameter
+ } // Parameters ok
+
+ if (source)
+ SDL_FreeSurface(source);
+ if (target)
+ SDL_FreeSurface(target);
+ if (dye)
+ delete dye;
+
+ return returnValue;
+}
diff --git a/tools/dyecmd/src/imagewriter.cpp b/tools/dyecmd/src/imagewriter.cpp
new file mode 100755
index 000000000..d237abbfb
--- /dev/null
+++ b/tools/dyecmd/src/imagewriter.cpp
@@ -0,0 +1,113 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "imagewriter.h"
+
+#include <png.h>
+#include <iostream>
+#include <string>
+#include <SDL/SDL.h>
+
+bool ImageWriter::writePNG(SDL_Surface *surface,
+ const std::string &filename)
+{
+ // TODO Maybe someone can make this look nice?
+ FILE *fp = fopen(filename.c_str(), "wb");
+ if (!fp)
+ {
+ std::cout << "PNG writer: Could not open file for writing: "
+ << filename << std::endl;
+ return false;
+ }
+
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_bytep *row_pointers;
+ int colortype;
+
+ if (SDL_MUSTLOCK(surface)) {
+ SDL_LockSurface(surface);
+ }
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!png_ptr)
+ {
+ std::cout << "PNG writer: Had trouble creating png_structp"
+ << std::endl;
+ return false;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ std::cout << "PNG writer: Could not create png_info" << std::endl;
+ return false;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ std::cout << "PNG writer: problem writing to : "
+ << filename << std::endl;
+ return false;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ colortype = (surface->format->BitsPerPixel == 24) ?
+ PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
+
+ png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8, colortype,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ png_write_info(png_ptr, info_ptr);
+
+ png_set_packing(png_ptr);
+
+ row_pointers = new png_bytep[surface->h];
+ if (!row_pointers)
+ {
+ std::cout
+ << "PNG writer: Had trouble converting surface to row pointers"
+ << std::endl;
+ return false;
+ }
+
+ for (int i = 0; i < surface->h; i++)
+ {
+ row_pointers[i] = (png_bytep)(Uint8 *)surface->pixels + i * surface->pitch;
+ }
+
+ png_write_image(png_ptr, row_pointers);
+ png_write_end(png_ptr, info_ptr);
+
+ fclose(fp);
+
+ delete [] row_pointers;
+
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+
+ if (SDL_MUSTLOCK(surface))
+ SDL_UnlockSurface(surface);
+
+ return true;
+}
diff --git a/tools/dyecmd/src/imagewriter.h b/tools/dyecmd/src/imagewriter.h
new file mode 100755
index 000000000..a8bcdf57d
--- /dev/null
+++ b/tools/dyecmd/src/imagewriter.h
@@ -0,0 +1,31 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <iosfwd>
+
+struct SDL_Surface;
+
+class ImageWriter
+{
+ public:
+ static bool writePNG(SDL_Surface *surface,
+ const std::string &filename);
+};
diff --git a/tools/tmxcopy/base64.cpp b/tools/tmxcopy/base64.cpp
new file mode 100644
index 000000000..8cea60f90
--- /dev/null
+++ b/tools/tmxcopy/base64.cpp
@@ -0,0 +1,148 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2000 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | 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 both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Author: Jim Winstead (jimw@php.net) |
+ +----------------------------------------------------------------------+
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "base64.h"
+
+static char base64_table[] =
+{
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
+};
+static char base64_pad = '=';
+
+unsigned char *php3_base64_encode(const unsigned char *string, int length, int *ret_length) {
+ const unsigned char *current = string;
+ int i = 0;
+ unsigned char *result = (unsigned char *)malloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char));
+
+ while (length > 2) { /* keep going until we have less than 24 bits */
+ result[i++] = base64_table[current[0] >> 2];
+ result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
+ result[i++] = base64_table[current[2] & 0x3f];
+
+ current += 3;
+ length -= 3; /* we just handle 3 octets of data */
+ }
+
+ /* now deal with the tail end of things */
+ if (length != 0) {
+ result[i++] = base64_table[current[0] >> 2];
+ if (length > 1) {
+ result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ result[i++] = base64_table[(current[1] & 0x0f) << 2];
+ result[i++] = base64_pad;
+ }
+ else {
+ result[i++] = base64_table[(current[0] & 0x03) << 4];
+ result[i++] = base64_pad;
+ result[i++] = base64_pad;
+ }
+ }
+ if(ret_length) {
+ *ret_length = i;
+ }
+ result[i] = '\0';
+ return result;
+}
+
+/* as above, but backwards. :) */
+unsigned char *php3_base64_decode(const unsigned char *string, int length, int *ret_length) {
+ const unsigned char *current = string;
+ int ch, i = 0, j = 0, k;
+ char *chp;
+
+ unsigned char *result = (unsigned char *)malloc(length + 1);
+
+ if (result == NULL) {
+ return NULL;
+ }
+
+ /* run through the whole string, converting as we go */
+ while ((ch = *current++) != '\0') {
+ if (ch == base64_pad) break;
+
+ /* When Base64 gets POSTed, all pluses are interpreted as spaces.
+ This line changes them back. It's not exactly the Base64 spec,
+ but it is completely compatible with it (the spec says that
+ spaces are invalid). This will also save many people considerable
+ headache. - Turadg Aleahmad <turadg@wise.berkeley.edu>
+ */
+
+ if (ch == ' ') ch = '+';
+
+ chp = strchr(base64_table, ch);
+ if (chp == NULL) continue;
+ ch = chp - base64_table;
+
+ switch(i % 4) {
+ case 0:
+ result[j] = ch << 2;
+ break;
+ case 1:
+ result[j++] |= ch >> 4;
+ result[j] = (ch & 0x0f) << 4;
+ break;
+ case 2:
+ result[j++] |= ch >>2;
+ result[j] = (ch & 0x03) << 6;
+ break;
+ case 3:
+ result[j++] |= ch;
+ break;
+ }
+ i++;
+ }
+
+ k = j;
+ /* mop things up if we ended on a boundary */
+ if (ch == base64_pad) {
+ switch(i % 4) {
+ case 0:
+ case 1:
+ free(result);
+ return NULL;
+ case 2:
+ k++;
+ case 3:
+ result[k++] = 0;
+ }
+ }
+ if(ret_length) {
+ *ret_length = j;
+ }
+ result[k] = '\0';
+ return result;
+}
diff --git a/tools/tmxcopy/base64.h b/tools/tmxcopy/base64.h
new file mode 100644
index 000000000..92c230169
--- /dev/null
+++ b/tools/tmxcopy/base64.h
@@ -0,0 +1,36 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | 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 both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Author: Jim Winstead (jimw@php.net) |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef BASE64_H
+#define BASE64_H
+
+extern unsigned char *php3_base64_encode(const unsigned char *, int, int *);
+extern unsigned char *php3_base64_decode(const unsigned char *, int, int *);
+
+#endif /* BASE64_H */
diff --git a/tools/tmxcopy/map.cpp b/tools/tmxcopy/map.cpp
new file mode 100644
index 000000000..3e1f9bdaf
--- /dev/null
+++ b/tools/tmxcopy/map.cpp
@@ -0,0 +1,679 @@
+/*
+ * TMXCopy
+ * Copyright (C) 2007 Philipp Sehmisch
+ * Copyright (C) 2009 Steve Cotton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <cstring>
+#include <iostream>
+#include <list>
+
+#include <string.h>
+#include <zlib.h>
+#include <cassert>
+#include <ctime>
+
+#include "xmlutils.h"
+#include "zlibutils.h"
+#include "base64.h"
+#include "tostring.h"
+
+#include "map.hpp"
+
+Map::Map(std::string filename):
+ mMaxGid(0)
+{
+ std::cout<<"Loading map "<<filename<<std::endl;
+ //load XML tree
+ mXmlDoc = xmlReadFile(filename.c_str(), NULL, 0);
+
+ if (!mXmlDoc)
+ {
+ std::cerr<<"Could not load "<<filename;
+ throw 1;
+ }
+
+ xmlNodePtr rootNode = xmlDocGetRootElement(mXmlDoc);
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "map")) {
+ std::cerr<<filename<<"is not a Tiled map file!";
+ throw 1;
+ }
+
+ mWidth = XML::getProperty(rootNode, "width", 0);
+ mHeight = XML::getProperty(rootNode, "height", 0);
+ int layerNum = 0;
+ for_each_xml_child_node(node, rootNode)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "tileset"))
+ {
+ //add tilesets to vector of used tilesets
+ Tileset* tileset = new Tileset;
+ tileset->name = XML::getProperty(node, "name", "Unnamed");
+ tileset->tilewidth = XML::getProperty(node, "tilewidth", 0);
+ tileset->tileheight = XML::getProperty(node, "tileheight", 0);
+ tileset->firstgid = XML::getProperty(node, "firstgid", 0);
+ for_each_xml_child_node(imageNode, node)
+ {
+ if (xmlStrEqual(imageNode->name, BAD_CAST "image"))
+ tileset->imagefile = XML::getProperty(imageNode, "source", "");
+ }
+
+ //add tileset to tileset list
+ Map::mTilesets.push_back(tileset);
+ }
+ }
+
+ for_each_xml_child_node(node, rootNode)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "layer"))
+ {
+ //build layer information
+ std::string name = XML::getProperty(node, "name", "");
+ Layer* layer = new Layer(name, mWidth * mHeight);
+ if (
+ (mWidth != XML::getProperty(node, "width" , 0)) ||
+ (mHeight != XML::getProperty(node, "height", 0)) ||
+ (0 != XML::getProperty(node, "x" , 0)) ||
+ (0 != XML::getProperty(node, "y" , 0)))
+ {
+ std::cerr<<"Error: layer size does not match map size for layer \""<<name<<"\" in "<<filename<<std::endl;
+ throw 1;
+ }
+
+ for_each_xml_child_node(dataNode, node)
+ {
+ if (!xmlStrEqual(dataNode->name, BAD_CAST "data")) continue;
+
+ std::string encoding = XML::getProperty(dataNode, "encoding", "");
+ std::string compression = XML::getProperty(dataNode, "compression", "");
+
+ if (encoding != "base64")
+ {
+ std::cerr<<"Layers in "<<filename<<" are not base64 encoded!";
+ return;
+ }
+
+ // Read base64 encoded map file
+ xmlNodePtr dataChild = dataNode->xmlChildrenNode;
+ if (!dataChild)
+ continue;
+
+ int len = strlen((const char*)dataChild->content) + 1;
+ unsigned char *charData = new unsigned char[len + 1];
+ const char *charStart = (const char*)dataChild->content;
+ unsigned char *charIndex = charData;
+
+ while (*charStart) {
+ if (*charStart != ' ' && *charStart != '\t' &&
+ *charStart != '\n')
+ {
+ *charIndex = *charStart;
+ charIndex++;
+ }
+ charStart++;
+ }
+ *charIndex = '\0';
+
+ int binLen;
+ unsigned char *binData =
+ php3_base64_decode(charData, strlen((char*)charData), &binLen);
+
+ delete[] charData;
+
+ if (binData) {
+ if (compression == "gzip")
+ {
+ unsigned char *inflated;
+ unsigned int inflatedSize =
+ inflateMemory(binData, binLen, inflated);
+ free(binData);
+ binData = inflated;
+ binLen = inflatedSize;
+ if (inflated == NULL)
+ {
+ std::cerr<<"Error: while decompressing layer "<<layerNum<<" in "<<filename;
+ throw 1;
+ }
+ }
+
+ int c = 0;
+ for (int i = 0; i < binLen - 3; i += 4) {
+ int gid = binData[i] |
+ binData[i + 1] << 8 |
+ binData[i + 2] << 16 |
+ binData[i + 3] << 24;
+
+ if (gid == 0)
+ {
+ layer->at(c).tileset = -1;
+ layer->at(c).index = 0;
+ }
+ else
+ {
+ for (int s = mTilesets.size()-1; s >= 0; s--)
+ {
+ if (mTilesets.at(s)->firstgid <= gid)
+ {
+ layer->at(c).tileset = s;
+ layer->at(c).index = gid - mTilesets.at(s)->firstgid;
+ if (mMaxGid < gid) mMaxGid = gid;
+ break;
+ }
+ }
+ }
+
+ c++;
+ }
+ free(binData);
+ } else {
+ std::cerr<<"error processing layer data in "<<filename<<std::endl;
+ }
+ }
+ mLayers.push_back(layer);
+ layerNum++;
+ }
+ }
+
+ std::cout<<"tilesets: "<<mTilesets.size()<<std::endl;
+ std::cout<<"layers:"<<mLayers.size()<<std::endl;
+ std::cout<<"largest GID:"<<mMaxGid<<std::endl<<std::endl;
+}
+
+/**
+ * When copying tiles from another map, add new tilesets to this map, and return the translation table.
+ */
+std::map<int, int> Map::addAndTranslateTilesets(const Map* srcMap)
+{
+ std::map<int, int> translation;
+ translation[-1] = -1;
+ std::vector<Tileset*>* srcTilesets = const_cast<Map*>(srcMap)->getTilesets();
+
+ for (std::vector<Tileset*>::size_type a = 0; a < srcTilesets->size(); a++)
+ {
+ std::vector<Tileset*>::size_type b;
+ for (b = 0; b < mTilesets.size(); b++)
+ {
+ if (*srcTilesets->at(a) == *mTilesets.at(b))
+ {
+ break;
+ }
+ }
+ if (b == mTilesets.size())
+ {
+ mMaxGid += srcTilesets->at(a)->firstgid;
+ Tileset* destTileset = new Tileset(*srcTilesets->at(a));
+ destTileset->firstgid = mMaxGid;//it is possible to get some holes in the gid index this way but who cares, we got 32bit.
+ mTilesets.push_back(destTileset);
+ }
+ translation[a] = b;
+ }
+ return translation;
+}
+
+bool Map::overwrite( Map* srcMap,
+ int srcX, int srcY, int srcWidth, int srcHeight,
+ int destX, int destY,
+ const ConfigurationOptions& config)
+{
+ //plausibility check of coordinates
+ bool checkPassed = true;
+ if (srcX + srcWidth > srcMap->getWidth()) {
+ std::cerr<<"Error: Area exceeds right map border of source map!"<<std::endl;
+ checkPassed = false;
+ }
+ if (srcY + srcHeight > srcMap->getHeight()) {
+ std::cerr<<"Error: Area exceeds lower map border of source map!"<<std::endl;
+ checkPassed = false;
+ }
+ if (destX + srcWidth > mWidth) {
+ std::cerr<<"Error: Area exceeds right map border of target map!"<<std::endl;
+ checkPassed = false;
+ }
+ if (destY + srcHeight > mHeight) {
+ std::cerr<<"Error: Area exceeds lower map border of target map!"<<std::endl;
+ checkPassed = false;
+ }
+ if (!config.createMissingLayers)
+ {
+ if (config.copyLayersByOrdinal)
+ {
+ if (srcMap->getNumberOfLayers() > mLayers.size()) {
+ std::cerr<<"Error: Source has more layers than target map"<<std::endl
+ <<"(and the command-line \"create layers\" option was not used)"<<std::endl;
+ checkPassed = false;
+ }
+ }
+ else
+ {
+ for (size_t i = 0; i < srcMap->getNumberOfLayers(); i++)
+ {
+ Layer* srcLayer = srcMap->getLayer(i);
+ Layer* destLayer = getLayer(srcLayer->getName());
+ if (!destLayer)
+ {
+ std::cerr<<"Error: target map has no layer named \""<<srcLayer->getName()<<"\""<<std::endl
+ <<"(and the command-line \"create layers\" option was not used)"<<std::endl;
+ checkPassed = false;
+ }
+ }
+ }
+ }
+
+ if (!checkPassed) return false;
+
+ std::map<int, int> translation = addAndTranslateTilesets(srcMap);
+
+
+ //combining layer information
+ for (size_t i = 0; i < srcMap->getNumberOfLayers(); i++)
+ {
+ Layer* srcLayer = srcMap->getLayer(i);
+ Layer* destLayer = NULL;
+ if (config.copyLayersByOrdinal)
+ {
+ if (i < mLayers.size())
+ {
+ destLayer = mLayers.at(i);
+ }
+ }
+ else
+ {
+ destLayer = getLayer(srcLayer->getName());
+ }
+
+ if (!destLayer)
+ {
+ assert(config.createMissingLayers); /* Tested earlier, in the checkPassed section */
+ /* Generate a name for the new layer, which must be
+ * unique in the target map, and should be unique in
+ * the source map (to avoid collisions later in the
+ * copying process).
+ * Start by trying the name of the source layer.
+ */
+ std::string name = srcLayer->getName();
+ if (getLayer(name))
+ {
+ int k=0;
+ do
+ {
+ name = "Layer" + toString(k);
+ k++;
+ } while (getLayer(name) || srcMap->getLayer(name));
+ }
+
+ destLayer = new Layer(name, mWidth * mHeight);
+ mLayers.push_back(destLayer);
+ std::cout<<"Created new layer "<<name<<std::endl;
+ }
+
+ for (int y=0; y<srcHeight; y++)
+ {
+
+ for (int x=0; x<srcWidth; x++)
+ {
+ int srcIndex = srcMap->getWidth() * (y + srcY) + (x + srcX);
+ int tgtIndex = mWidth * (y + destY) + (x + destX);
+ Tile tmpTile = srcLayer->at(srcIndex);
+ tmpTile.tileset = translation[tmpTile.tileset];
+ destLayer->at(tgtIndex) = tmpTile;
+ }
+ }
+ }
+
+ std::clog<<"copying successful!"<<std::endl;
+ return true;
+}
+
+bool Map::randomFill(Map* templateMap, const std::string& destLayerName,
+ int destX, int destY, int destWidth, int destHeight,
+ const ConfigurationOptions& config)
+{
+ //plausibility check of coordinates
+ bool checkPassed = true;
+ if (destX + destWidth > mWidth)
+ {
+ std::cerr<<"Error: Area exceeds right map border of target map!"<<std::endl;
+ checkPassed = false;
+ }
+ if (destY + destHeight > mHeight)
+ {
+ std::cerr<<"Error: Area exceeds lower map border of target map!"<<std::endl;
+ checkPassed = false;
+ }
+ if (destWidth < templateMap->getWidth())
+ {
+ std::cerr<<"Error: Template is wider than target area"<<std::endl;
+ checkPassed = false;
+ }
+ if (destWidth < templateMap->getHeight())
+ {
+ std::cerr<<"Error: Template is higher than target area"<<std::endl;
+ checkPassed = false;
+ }
+ if (templateMap->getNumberOfLayers() == 0)
+ {
+ std::cerr<<"Error: Template has no layers"<<std::endl;
+ checkPassed = false;
+ }
+ if (!config.createMissingLayers && !getLayer(destLayerName))
+ {
+ std::cerr<<"Error: target map has no layer named \""<<destLayerName<<"\""<<std::endl
+ <<"(and the command-line \"create layers\" option was not used)"<<std::endl;
+ checkPassed = false;
+ }
+ if (!checkPassed) return false;
+
+ std::map<int, int> translation = addAndTranslateTilesets(templateMap);
+
+
+ Layer* destLayer = getLayer(destLayerName);
+ if (!destLayer)
+ {
+ destLayer = new Layer(destLayerName, mWidth * mHeight);
+ mLayers.push_back(destLayer);
+ std::cout<<"Created new layer "<<destLayerName<<std::endl;
+ }
+
+ /* Now generate extra tiles.
+ *
+ * After considering ways to specify the number of objects to add, I think
+ * the best user interface (without integrating it with Tiled) is to place
+ * a small number of objects each time, and have the user run the utility
+ * several times, reloading the map in Tiled each time until it looks
+ * right. Simpler than typing magic numbers in at a command prompt.
+ *
+ * This algorithm completes after a fixed number of attempts at placing an
+ * object; regardless of how many attempts are successful.
+ * For 2x1 trees, destWidth*destHeight/10 is very sparse, dW*dH/2 is dense.
+ */
+ srand(time(NULL));
+ int patternsGenerated = 0;
+ int occupiedAreas = 0;
+ for (int i = destWidth*destHeight / 10; i > 0; i--)
+ {
+ /* Pick a random location, with enough tiles left and down from it to
+ * fit the template in (the +1 is because it starts on tile (x,y))
+ */
+ int x = destX + (rand() % (destWidth - templateMap->getWidth () + 1));
+ int y = destY + (rand() % (destHeight - templateMap->getHeight() + 1));
+
+ bool areaIsClear = true;
+
+ for (int loop_y=0; loop_y<templateMap->getHeight(); loop_y++)
+ {
+ for (int loop_x=0; loop_x<templateMap->getWidth(); loop_x++)
+ {
+ if (! destLayer->getTile(x+loop_x, y+loop_y, mWidth).empty())
+ {
+ areaIsClear = false;
+ }
+ }
+ }
+
+ if (areaIsClear)
+ {
+ int p = rand() % templateMap->getNumberOfLayers();
+
+ Layer* srcLayer = templateMap->getLayer(p);
+ for (int loop_y=0; loop_y<templateMap->getHeight(); loop_y++)
+ {
+ for (int loop_x=0; loop_x<templateMap->getWidth(); loop_x++)
+ {
+ Tile& srcTile = srcLayer->getTile(loop_x, loop_y, templateMap->getWidth());
+ Tile& destTile = destLayer->getTile(x+loop_x, y+loop_y, mWidth);
+ destTile.tileset = translation[srcTile.tileset];
+ destTile.index = srcTile.index;
+ }
+ }
+ patternsGenerated++;
+ }
+ else
+ {
+ occupiedAreas++;
+ }
+ }
+
+ std::clog<<"Generated " << patternsGenerated << " new objects" <<std::endl;
+ (void) occupiedAreas; // Unused at the moment, but keep it without a compiler warning about unused variables
+ return true;
+}
+
+bool Map::translateAllLayers(Map* templateMap, const std::string& destLayerName,
+ const ConfigurationOptions& config)
+{
+ bool checkPassed = true;
+ if (templateMap->getNumberOfLayers() != 2)
+ {
+ std::cerr<<"Error: template should have exactly 2 layers"<<std::endl;
+ checkPassed = false;
+ }
+ if (!config.createMissingLayers && !getLayer(destLayerName))
+ {
+ std::cerr<<"Error: target map has no layer named \""<<destLayerName<<"\""<<std::endl
+ <<"(and the command-line \"create layers\" option was not used)"<<std::endl;
+ checkPassed = false;
+ }
+ if (!checkPassed) return false;
+
+ //TODO This will unnecessarily add tilesets that are in the template but
+ //not used in the main map
+ std::map<int, int> tilesetTranslation = addAndTranslateTilesets(templateMap);
+
+ //Lacking a better name, we'll say this is translating visible layers to collision
+ std::map<Tile, Tile> collisionTranslation;
+
+ Layer* fromLayer = templateMap->getLayer(0);
+ Layer* toLayer = templateMap->getLayer(1);
+ for (int xy = (templateMap->getWidth() * templateMap->getHeight() -1);
+ xy >= 0; xy--)
+ {
+ Tile fromTile = fromLayer->at(xy);
+ Tile toTile = toLayer->at(xy);
+ if (!fromTile.empty())
+ {
+ fromTile.tileset = tilesetTranslation[fromTile.tileset];
+ toTile.tileset = tilesetTranslation[toTile.tileset];
+
+ collisionTranslation[fromTile] = toTile;
+ }
+ }
+
+ /* Now apply that template to the game map */
+ Layer* destLayer = getLayer(destLayerName);
+ if (!destLayer)
+ {
+ destLayer = new Layer(destLayerName, mWidth * mHeight);
+ mLayers.push_back(destLayer);
+ std::cout<<"Created new layer "<<destLayerName<<std::endl;
+ }
+
+ for (std::vector<Layer*>::iterator layer = mLayers.begin();
+ layer != mLayers.end();
+ layer++)
+ {
+ if ((*layer)->getName() == destLayerName)
+ continue;
+
+ for (int xy = mWidth * mHeight -1; xy >= 0; xy--)
+ {
+ Tile& fromTile = (*layer)->at(xy);
+ Tile& toTile = destLayer->at(xy);
+ std::map<Tile,Tile>::iterator iteratedTile = collisionTranslation.find(fromTile);
+
+ if (iteratedTile != collisionTranslation.end())
+ {
+ toTile = (*iteratedTile).second;
+ }
+ }
+
+ }
+
+ return true;
+}
+
+
+
+int Map::save(std::string filename)
+{
+ //remove old tileset and layer information in XML tree
+ xmlNodePtr rootNode = xmlDocGetRootElement(mXmlDoc);
+ std::list<xmlNodePtr> toRemove;
+ for_each_xml_child_node(node, rootNode)
+ {
+ if ( xmlStrEqual(node->name, BAD_CAST "tileset")
+ || xmlStrEqual(node->name, BAD_CAST "layer"))
+ {
+ toRemove.push_back(node);
+ }
+ }
+
+ while (!toRemove.empty())
+ {
+ xmlUnlinkNode(toRemove.back());
+ xmlFreeNode(toRemove.back());
+ toRemove.pop_back();
+ }
+
+ //TODO: reorganize GIDs
+
+ //add new tileset information to XML tree
+ for (size_t i = 0; i< mTilesets.size(); i++)
+ {
+ xmlNodePtr newNode;
+
+ xmlAddChild(rootNode, xmlNewDocText(mXmlDoc, BAD_CAST " "));
+ newNode = xmlNewNode(NULL, BAD_CAST "tileset");
+ xmlNewProp(newNode, BAD_CAST "name", BAD_CAST mTilesets.at(i)->name.c_str());
+ xmlNewProp(newNode, BAD_CAST "firstgid", BAD_CAST toString(mTilesets.at(i)->firstgid).c_str());
+ xmlNewProp(newNode, BAD_CAST "tilewidth", BAD_CAST toString(mTilesets.at(i)->tilewidth).c_str());
+ xmlNewProp(newNode, BAD_CAST "tileheight", BAD_CAST toString(mTilesets.at(i)->tileheight).c_str());
+ xmlAddChild(newNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n "));
+ xmlNodePtr imageNode = xmlNewNode(NULL, BAD_CAST "image");
+ xmlNewProp(imageNode, BAD_CAST "source", BAD_CAST mTilesets.at(i)->imagefile.c_str());
+ xmlAddChild(newNode, imageNode);
+ xmlAddChild(newNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n "));
+ xmlAddChild(rootNode, newNode);
+ xmlAddChild(rootNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n"));
+ }
+
+ //add new layer information to XML tree
+ for (size_t i = 0; i < mLayers.size(); i++)
+ {
+ //lay out layer information in binary
+ unsigned char* binData = (unsigned char*)malloc(mWidth * mHeight * 4);
+
+ for (int a=0; a < mWidth * mHeight; a++)
+ {
+ Tile tile = mLayers.at(i)->at(a);
+ int ldata;
+ if (tile.tileset != -1)
+ {
+ ldata = tile.index + mTilesets.at(tile.tileset)->firstgid;
+ } else {
+ ldata = 0;
+ }
+
+ binData[a * 4 + 0] = (ldata & 0x000000ff);
+ binData[a * 4 + 1] = (ldata & 0x0000ff00) >> 8;
+ binData[a * 4 + 2] = (ldata & 0x00ff0000) >> 16;
+ binData[a * 4 + 3] = (ldata & 0xff000000) >> 24;
+ }
+
+
+ //GZIP layer information
+ /*
+ unsigned char* gzipData = (unsigned char*)malloc((mWidth * mHeight * 4) + 128);
+ unsigned int gzipLen;
+ compressMemory (binData, (mWidth * mHeight * 4) + 128, gzipData, gzipLen);
+ free (binData);
+ std::cout<<"GZIP length: "<<gzipLen<<std::endl;
+ */
+
+ //encode layer information in base64
+ unsigned char* base64Data;
+ int base64len;
+ //base64Data = php3_base64_encode(gzipData, gzipLen, &base64len);
+ base64Data = php3_base64_encode(binData, (mWidth * mHeight * 4), &base64len);
+ //free(gzipData);
+
+ xmlNodePtr newNode;
+ xmlAddChild(rootNode, xmlNewDocText(mXmlDoc, BAD_CAST " "));
+ newNode = xmlNewNode(NULL, BAD_CAST "layer");
+ xmlNewProp(newNode, BAD_CAST "name", BAD_CAST (mLayers.at(i)->getName()).c_str());
+ xmlNewProp(newNode, BAD_CAST "width", BAD_CAST toString(mWidth).c_str());
+ xmlNewProp(newNode, BAD_CAST "height", BAD_CAST toString(mHeight).c_str());
+ xmlAddChild(newNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n "));
+ xmlNodePtr dataNode = xmlNewNode(NULL, BAD_CAST "data");
+ xmlNewProp(dataNode, BAD_CAST "encoding", BAD_CAST "base64");
+ //xmlNewProp(dataNode, BAD_CAST "compression", BAD_CAST "gzip");
+ xmlAddChild(dataNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n "));
+ xmlAddChild(dataNode, xmlNewDocText(mXmlDoc, BAD_CAST base64Data));
+ xmlAddChild(dataNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n "));
+ xmlAddChild(newNode, dataNode);
+ xmlAddChild(newNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n "));
+ xmlAddChild(rootNode, newNode);
+ xmlAddChild(rootNode, xmlNewDocText(mXmlDoc, BAD_CAST "\n"));
+
+ free(base64Data);
+ free(binData);
+ }
+
+ //save XML tree
+ int retval = xmlSaveFile(filename.c_str(), mXmlDoc);
+
+ if (retval == -1)
+ {
+ std::cerr<<"Could not write outfile "<<filename<<std::endl;
+ return false;
+ }
+ else
+ {
+ std::cout<<"File saved successfully to "<<filename<<std::endl;
+ return true;
+ }
+}
+
+Layer* Map::getLayer(std::string name)
+{
+ for (std::vector<Layer*>::iterator layer = mLayers.begin();
+ layer != mLayers.end();
+ layer++)
+ {
+ if ((*layer)->getName() == name)
+ return *layer;
+ }
+ return NULL;
+}
+
+Map::~Map()
+{
+ for (std::vector<Layer*>::iterator layer = mLayers.begin();
+ layer != mLayers.end();
+ layer++)
+ {
+ delete *layer;
+ }
+
+ for (std::vector<Tileset*>::iterator tileset = mTilesets.begin();
+ tileset != mTilesets.end();
+ tileset++)
+ {
+ delete *tileset;
+ }
+
+ xmlFreeDoc(mXmlDoc);
+}
diff --git a/tools/tmxcopy/map.hpp b/tools/tmxcopy/map.hpp
new file mode 100644
index 000000000..ff878811a
--- /dev/null
+++ b/tools/tmxcopy/map.hpp
@@ -0,0 +1,183 @@
+/*
+ * TMXCopy
+ * Copyright (C) 2007 Philipp Sehmisch
+ * Copyright (C) 2009 Steve Cotton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <string>
+#include <vector>
+#include <set>
+#include <map>
+#include <libxml/parser.h>
+
+struct ConfigurationOptions
+{
+ /* When copying map layers, how to match source layer to
+ * destination layer.
+ *
+ * True: Pair the first layer to the first layer, the second
+ * to the second, etc.
+ *
+ * False: Pair up layers with matching names.
+ */
+ bool copyLayersByOrdinal;
+
+ /* Create extra layers in the target as necessary. */
+ bool createMissingLayers;
+};
+
+struct Tileset
+{
+ std::string imagefile;
+ int firstgid;
+ std::string name;
+ int tilewidth;
+ int tileheight;
+
+ bool operator== (Tileset const& a)
+ {
+ return (imagefile == a.imagefile &&
+ tilewidth == a.tilewidth &&
+ tileheight == a.tileheight
+ );
+ }
+
+ Tileset()
+ {
+ }
+
+ Tileset(const Tileset& src) :
+ imagefile(src.imagefile), firstgid(src.firstgid),
+ name(src.name),
+ tilewidth(src.tilewidth), tileheight(src.tileheight)
+ {
+ }
+
+};
+
+/**
+ * A tile in a layer of a map.
+ *
+ * With the exception of the emptyTile and empty() function,
+ * interpreting what this tile represents depends on the map it
+ * belongs to (specifically the ordering of that map's tilesets).
+ */
+struct Tile
+{
+ int tileset; // number of tileset
+ size_t index; // index in said tileset
+
+ bool empty()
+ {
+ return (tileset == -1);
+ }
+
+ /* This is to allow std::map<Tile,Tile> */
+ bool operator< (const Tile& b) const
+ {
+ return ((tileset < b.tileset) ||
+ ((tileset == b.tileset) && (index < b.index)));
+ }
+
+ bool operator!= (const Tile& b) const
+ {
+ return ((tileset != b.tileset) || (index != b.index));
+ }
+};
+
+typedef std::vector<Tile> LayerTiles;
+
+/* This represents an empty tile in the layer.
+ * Note that {0,0} would be the first tile in the first tileset.
+ */
+const Tile emptyTile = {-1, 0};
+
+class Layer
+{
+ public:
+ /* name - the name of the layer, as shown in Tiled
+ * tileCount - total number of tiles (width*height)
+ */
+ Layer(std::string name, LayerTiles::size_type tileCount)
+ : mTiles(tileCount, emptyTile),
+ mName (name)
+ {
+ }
+
+ std::string getName() { return mName; }
+ Tile& at(LayerTiles::size_type c) { return mTiles.at(c); }
+ Tile& getTile(int x, int y, int mapWidth) { return mTiles.at(x + y*mapWidth); }
+
+ private:
+ LayerTiles mTiles;
+ std::string mName;
+};
+
+class Map
+{
+ public:
+ Map(std::string filename);
+ ~Map();
+
+ /**
+ * Copies an area from srcMap, replacing its current contents.
+ */
+ bool overwrite(Map* srcMap,
+ int srcX, int srcY, int srcWidth, int srcHeight,
+ int destX, int destY,
+ const ConfigurationOptions& config);
+
+ /**
+ * Fills an area of this map with random parts of the template.
+ * Currently, each layer of the template is treated as an object that
+ * should be copied in its entirity.
+ */
+ bool randomFill(Map* templateMap, const std::string& destLayerName,
+ int destX, int destY, int destWidth, int destHeight,
+ const ConfigurationOptions& config);
+
+ /**
+ * Translates a layer - using the template, generates collision from visible layers (for example).
+ * TODO - avoid confusion with the geometry term "translate"
+ */
+ bool translateAllLayers(Map* templateMap, const std::string& destLayerName,
+ const ConfigurationOptions& config);
+
+ int save(std::string filename);
+
+ size_t getNumberOfLayers() { return mLayers.size(); }
+
+ Layer* getLayer(size_t num) { return mLayers.at(num); }
+ Layer* getLayer(std::string name);
+
+ std::vector<Tileset*>* getTilesets() { return &mTilesets; }
+
+ int getWidth() { return mWidth; }
+ int getHeight() { return mHeight; }
+
+ private:
+ std::map<int, int> addAndTranslateTilesets(const Map* srcMap);
+
+ std::vector<Layer*> mLayers;
+
+ int mWidth;
+ int mHeight;
+ int mMaxGid;
+
+ std::vector<Tileset*> mTilesets;
+
+ xmlDocPtr mXmlDoc;
+};
diff --git a/tools/tmxcopy/readme.txt b/tools/tmxcopy/readme.txt
new file mode 100644
index 000000000..d130edd60
--- /dev/null
+++ b/tools/tmxcopy/readme.txt
@@ -0,0 +1,104 @@
+=== TMX Map Tools ===
+
+A set of tools for manipulating TMX map files.
+
+After using any of these tools, load the map in Tiled and save it again; until this is done the game may not be able to load the file (see Bugs for an explanation).
+
+
+=== TMXCopy ===
+
+Tmxcopy is a little tool that allows to copy parts of one TMX map to another map. This will make it much easier to match the border areas of maps. The program is command line based. The usage is:
+
+ tmxcopy [-c] [-n] srcFile x y width height tgtFile x y [outfile]
+
+Here an example:
+When you want to copy the lower right corner (20x20 tiles) of mapA.tmx to the upper left corner of mapB.txt you would open map A with tiled and check at which coordinates the area you want to copy begins. Let's say mapA is 120x130 tiles. Then the area you want to copy would begin at 100:110 and would be 20x20 tiles large. So the first part of the command is:
+
+ tmxcopy mapA.tmx 100 110 20 20
+
+Then you open the target map to check the coordinates where you want to put the copied map part. We want the upper left corner, so the coordinates are 0:0. That means the next part of the command would be:
+
+ mapB.tmx 0 0
+
+The command is now complete:
+
+ tmxcopy mapA.tmx 100 110 20 20 mapB.tmx 0 0
+
+But when you enter this command the mapB will be overwritten. This could be a problem when you made an error in the command. So it is saver to write the output to a new map file so we can look at the result in Tiled before we replace the original map:
+
+ tmxcopy mapA.tmx 100 110 20 20 mapB.tmx 0 0 temp.tmx
+
+Now we can check temp.tmx to see if the copying worked correctly.
+
+
+Which layer gets copied to which:
+By default layers are copied to layers of the same name. The -n option will make it copy by layer number instead.
+
+ mapA: Ground, Fringe, Over, Collision, Object
+ mapB: Ground, Fencing, Fringe, Over, Collision, Object
+ The default copies Ground->Ground, Fringe->Fringe, Over->Over, Collision->Collision (the object layer is not affected)
+ -n copies Ground->Ground, Fringe->Fencing, Over->Fringe, Collision->Over (mapB's collision and object layers are not affected)
+
+ mapA: Ground, Fringe, Over, Collision, Object
+ mapC: Ground, Fringe, Overhead, Collision, Object
+ The default quits with an error
+ -n copies Over->Overhead
+
+The -c option creates layers as needed. Using it to copy mapB to mapA will add a Fencing layer to mapA.
+
+
+=== TMX Random Fill ===
+
+This is for generating big areas of woodland (or other things that want lots of randomly-placed patterns).
+
+Usage: tmx_random_fill mapFile destLayer x y width height templateFile [-o outfile]
+ -c create layers, if they don't already exist in the target
+ -o save results to outfile, instead of overwriting the original
+
+Fill a rectangular area of mapFile's layer 'destLayer' with a random selection from the templateFile.
+
+The template is a map where each layer is a pattern. For example, to make a woodland:
+ Create a new 2x1 tile map (yes, this is tiny, and only the base of the tree will be visible).
+ Add the Woodland_x3 tileset, using the correct height (96 pixels).
+ Make a layer, add a tree.
+ Make a layer, add the second tree.
+ Make a layer, add the third tree.
+ Save this as template_trees.tmx
+ Run tmx_random_fill with the appropriate options (destLayer will be "Fringe")
+
+It will then randomly place trees, but only in places where they won't overlap with other things on that layer. The size of the template map is the size of the area which must be empty in the destination layer.
+
+Running it several times (without specifying an output file) will add more objects. After considering ways to specify the number of objects to add, I think the easiest is to just reload the map in Tiled each time until it looks right (you don't need to quit Tiled while running tmx_random_fill).
+
+
+=== TMX Collide / Translate ===
+
+A big woodland with lots of randomly-placed trees needs a complex collision layer, most of which can be generated from the visible layers.
+This tool does that automatic generation.
+
+It's not limited to adding collision tiles; it can be used for any task where tiles are added to one layer based on the tiles present in other layers.
+
+Usage: tmxcollide [-c] mapFile destLayer templateFile [-o outfile]
+ -c create layers, if they don't already exist in the target
+ -o save results to outfile, instead of overwriting the original
+
+To fill the collision layer, "destLayer" should be "Collision".
+
+As with TMX Random Fill, this tool takes a template map; for this tool it should have exactly two layers.
+ Upper layer: tiles to translate to (collision tiles)
+ Lower layer: tiles to translate from (visible tiles)
+Blank tiles in the lower layer will be ignored (put a blank in the upper layer too).
+
+
+=== Bugs (for all these programs) ===
+
+The programs work so far but there are still some minor problems:
+
+-Only tested for Mana-compilant maps. I don't guarantee that it works with Tiled maps that are made for other games and thus use different features.
+-Compressed maps (tmx.gz) can not be handled yet (but compressed or uncompressed layers work properly)
+-When the target map has an object layer it is moved to the bottom of the layer list of the map (no problem for the game but inconvenient for editing). Objects on the source map are ignored.
+-All tilesets included in the srcFile (TMXCopy) or template (TMXRandomFill and TMXCollide) will be added to the output file, even if they aren't needed for the tiles that are added.
+-Layer data of output file isn't gzip-compressed yet
+-Created TMX file is a bit malformated (but working properly)
+
+The last 2 problems can be solved easily by opening and saving the map in Tiled.
diff --git a/tools/tmxcopy/tmx_random_fill.cpp b/tools/tmxcopy/tmx_random_fill.cpp
new file mode 100644
index 000000000..0039ff8b2
--- /dev/null
+++ b/tools/tmxcopy/tmx_random_fill.cpp
@@ -0,0 +1,115 @@
+/*
+ * TMXRandomFill
+ * Copyright (C) 2007 Philipp Sehmisch
+ * Copyright (C) 2009 Steve Cotton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <iostream>
+#include <string>
+#include <unistd.h>
+
+#include "map.hpp"
+
+void printUsage()
+{
+ std::cerr<<"Usage: tmx_random_fill [-c] mapFile destLayer x y width height templateFile [-o outfile]"<<std::endl
+ <<" -c create layers, if they don't already exist in the target"<<std::endl
+ <<" -o save results to outfile, instead of overwriting the original"<<std::endl
+ <<std::endl
+ <<"Fill a rectangular area of mapFile's layer 'destLayer' with a random selection from the templateFile"<<std::endl
+ <<"See readme.txt for full documentation"<<std::endl;
+}
+
+int main(int argc, char * argv[] )
+{
+ ConfigurationOptions config = {0};
+ std::string outFile;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "co:")) != -1)
+ {
+ switch (opt)
+ {
+ case 'c':
+ config.createMissingLayers = true;
+ break;
+ case 'o':
+ if (optarg)
+ {
+ outFile = optarg;
+ } else {
+ printUsage();
+ return -1;
+ }
+ break;
+ case '?':
+ std::cerr<<"Unrecognized option"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ }
+
+ if ((argc-optind) < 7)
+ {
+ std::cerr<<"Too few args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ if ((argc-optind) > 7)
+ {
+ std::cerr<<"Too many args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+
+ std::string mapFile = argv[optind+0];
+ std::string destLayer = argv[optind+1];
+ int destX= atoi(argv[optind+2]);
+ int destY= atoi(argv[optind+3]);
+ int width= atoi(argv[optind+4]);
+ int height=atoi(argv[optind+5]);
+ std::string templateFile = argv[optind+6];
+ if (outFile.empty())
+ {
+ outFile = mapFile;
+ }
+
+ // plausibility check of command line options
+ if (height < 1 || width < 1 || destX < 0 || destY < 0)
+ {
+ std::cerr<<"Illegal coordinates!"<<std::endl;
+ printUsage();
+ return -1;
+ }
+
+ try
+ {
+ Map* mainMap = new Map(mapFile);
+ Map* templateMap = new Map(templateFile);
+ if (mainMap->randomFill(templateMap, destLayer, destX, destY, width, height, config))
+ {
+ mainMap->save(outFile);
+ } else {
+ return -1;
+ }
+ delete mainMap;
+ delete templateMap;
+ }
+ catch (int)
+ {
+ return -1;
+ }
+}
diff --git a/tools/tmxcopy/tmxcollide.cpp b/tools/tmxcopy/tmxcollide.cpp
new file mode 100644
index 000000000..75b0a6a27
--- /dev/null
+++ b/tools/tmxcopy/tmxcollide.cpp
@@ -0,0 +1,103 @@
+/*
+ * TMXTranslate / TMXCollide
+ * Copyright (C) 2007 Philipp Sehmisch
+ * Copyright (C) 2009 Steve Cotton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <iostream>
+#include <string>
+#include <unistd.h>
+
+#include "map.hpp"
+
+void printUsage()
+{
+ std::cerr<<"Usage: tmxcollide [-c] mapFile destLayer templateFile [-o outfile]"<<std::endl
+ <<" -c create layers, if they don't already exist in the target"<<std::endl
+ <<" -o save results to outfile, instead of overwriting the original"<<std::endl
+ <<std::endl
+ <<"Using the template, translate visible layers to the collision layer"<<std::endl
+ <<"See readme.txt for full documentation"<<std::endl;
+}
+
+int main(int argc, char * argv[] )
+{
+ ConfigurationOptions config = {0};
+ std::string outFile;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "co:")) != -1)
+ {
+ switch (opt)
+ {
+ case 'c':
+ config.createMissingLayers = true;
+ break;
+ case 'o':
+ if (optarg)
+ {
+ outFile = optarg;
+ } else {
+ printUsage();
+ return -1;
+ }
+ break;
+ case '?':
+ std::cerr<<"Unrecognized option"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ }
+
+ if ((argc-optind) < 3)
+ {
+ std::cerr<<"Too few args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ if ((argc-optind) > 3)
+ {
+ std::cerr<<"Too many args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+
+ std::string mapFile = argv[optind+0];
+ std::string destLayer = argv[optind+1];
+ std::string templateFile = argv[optind+2];
+ if (outFile.empty())
+ {
+ outFile = mapFile;
+ }
+
+ try
+ {
+ Map* mainMap = new Map(mapFile);
+ Map* templateMap = new Map(templateFile);
+ if (mainMap->translateAllLayers(templateMap, destLayer, config))
+ {
+ mainMap->save(outFile);
+ } else {
+ return -1;
+ }
+ delete mainMap;
+ delete templateMap;
+ }
+ catch (int)
+ {
+ return -1;
+ }
+}
diff --git a/tools/tmxcopy/tmxcopy.cbp b/tools/tmxcopy/tmxcopy.cbp
new file mode 100644
index 000000000..237f6fdee
--- /dev/null
+++ b/tools/tmxcopy/tmxcopy.cbp
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="untitled" />
+ <Option pch_mode="0" />
+ <Option compiler="gcc" />
+ <Build>
+ <Target title="default">
+ <Option output="TMXCopy.exe" prefix_auto="0" extension_auto="0" />
+ <Option type="1" />
+ <Option compiler="gcc" />
+ <Option projectResourceIncludeDirsRelation="1" />
+ <Linker>
+ <Add library="libxml2" />
+ <Add library="z" />
+ </Linker>
+ </Target>
+ </Build>
+ <VirtualTargets>
+ <Add alias="All" targets="default;" />
+ </VirtualTargets>
+ <Unit filename="base64.cpp" />
+ <Unit filename="base64.h" />
+ <Unit filename="main.cpp" />
+ <Unit filename="map.cpp" />
+ <Unit filename="map.hpp" />
+ <Unit filename="tostring.h" />
+ <Unit filename="xmlutils.cpp" />
+ <Unit filename="xmlutils.h" />
+ <Unit filename="zlibutils.cpp" />
+ <Unit filename="zlibutils.h" />
+ <Extensions>
+ <code_completion />
+ <envvars />
+ <debugger />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/tools/tmxcopy/tmxcopy.cpp b/tools/tmxcopy/tmxcopy.cpp
new file mode 100644
index 000000000..9c9655d71
--- /dev/null
+++ b/tools/tmxcopy/tmxcopy.cpp
@@ -0,0 +1,106 @@
+/*
+ * TMXCopy
+ * Copyright (C) 2007 Philipp Sehmisch
+ * Copyright (C) 2009 Steve Cotton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 <iostream>
+#include <string>
+#include <unistd.h>
+
+#include "map.hpp"
+
+void printUsage()
+{
+ std::cerr<<"Usage: tmxcopy [-c] [-n] srcFile x y width height tgtFile x y [outfile]"<<std::endl
+ <<" -c create layers, if they don't already exist in the target"<<std::endl
+ <<" -n copy layers by number, not name"<<std::endl;
+}
+
+int main(int argc, char * argv[] )
+{
+ ConfigurationOptions config = {0};
+ int opt;
+ while ((opt = getopt(argc, argv, "cn")) != -1)
+ {
+ switch (opt)
+ {
+ case 'c':
+ config.createMissingLayers = true;
+ break;
+ case 'n':
+ config.copyLayersByOrdinal = true;
+ break;
+ case '?':
+ std::cerr<<"Unrecognized option"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ }
+
+ if ((argc-optind) < 8)
+ {
+ std::cerr<<"Too few args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ if ((argc-optind) > 9)
+ {
+ std::cerr<<"Too many args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+
+ std::string srcFile = argv[optind+0];
+ int srcX= atoi(argv[optind+1]);
+ int srcY= atoi(argv[optind+2]);
+ int width= atoi(argv[optind+3]);
+ int height=atoi(argv[optind+4]);
+ std::string tgtFile = argv[optind+5];
+ int destX=atoi(argv[optind+6]);
+ int destY=atoi(argv[optind+7]);
+ std::string outFile = tgtFile;
+ if (argc == optind+9)
+ {
+ outFile = argv[optind+8];
+ }
+
+ // plausibility check of command line options
+ if (height < 1 || width < 1 || srcX < 0 || srcY < 0 || destX < 0 || destY < 0)
+ {
+ std::cerr<<"Illegal coordinates!"<<std::endl;
+ printUsage();
+ return -1;
+ }
+
+ try
+ {
+ Map* srcMap = new Map(srcFile);
+ Map* tgtMap = new Map(tgtFile);
+ if (tgtMap->overwrite(srcMap, srcX, srcY, width, height, destX, destY, config))
+ {
+ tgtMap->save(outFile);
+ } else {
+ return -1;
+ }
+ delete srcMap;
+ delete tgtMap;
+ }
+ catch (int)
+ {
+ return -1;
+ }
+}
diff --git a/tools/tmxcopy/tostring.h b/tools/tmxcopy/tostring.h
new file mode 100644
index 000000000..63c0a1a8c
--- /dev/null
+++ b/tools/tmxcopy/tostring.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef UTILS_TOSTRING_H
+#define UTILS_TOSTRING_H
+
+#include <sstream>
+
+template<typename T>
+std::string toString(const T &arg)
+{
+ std::stringstream ss;
+ ss << arg;
+ return ss.str();
+}
+
+#endif
diff --git a/tools/tmxcopy/xmlutils.cpp b/tools/tmxcopy/xmlutils.cpp
new file mode 100644
index 000000000..a4984a6a2
--- /dev/null
+++ b/tools/tmxcopy/xmlutils.cpp
@@ -0,0 +1,75 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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 "xmlutils.h"
+
+namespace XML
+{
+ int
+ getProperty(xmlNodePtr node, const char* name, int def)
+ {
+ int &ret = def;
+
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop) {
+ ret = atoi((char*)prop);
+ xmlFree(prop);
+ }
+
+ return ret;
+ }
+
+ double
+ getFloatProperty(xmlNodePtr node, const char* name, double def)
+ {
+ double &ret = def;
+
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop) {
+ ret = atof((char*)prop);
+ xmlFree(prop);
+ }
+
+ return ret;
+ }
+
+ std::string
+ getProperty(xmlNodePtr node, const char *name, const std::string &def)
+ {
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop) {
+ std::string val = (char*)prop;
+ xmlFree(prop);
+ return val;
+ }
+
+ return def;
+ }
+
+ xmlNodePtr findFirstChildByName(xmlNodePtr parent, const char *name)
+ {
+ for_each_xml_child_node(child, parent)
+ if (xmlStrEqual(child->name, BAD_CAST name))
+ return child;
+
+ return NULL;
+ }
+}
diff --git a/tools/tmxcopy/xmlutils.h b/tools/tmxcopy/xmlutils.h
new file mode 100644
index 000000000..3d9c5d7a7
--- /dev/null
+++ b/tools/tmxcopy/xmlutils.h
@@ -0,0 +1,61 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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/>.
+ */
+
+#ifndef _XMLUTILS_H
+#define _XMLUTILS_H
+
+#include <libxml/tree.h>
+
+#include <string>
+
+/**
+ * XML helper functions.
+ */
+namespace XML
+{
+ /**
+ * Gets an integer property from an xmlNodePtr.
+ */
+ int
+ getProperty(xmlNodePtr node, const char *name, int def);
+
+ /**
+ * Gets an floating point property from an xmlNodePtr.
+ */
+ double
+ getFloatProperty(xmlNodePtr node, const char *name, double def);
+
+ /**
+ * Gets a string property from an xmlNodePtr.
+ */
+ std::string
+ getProperty(xmlNodePtr node, const char *name, const std::string &def);
+
+ /**
+ * Finds the first child node with the given name
+ */
+ xmlNodePtr findFirstChildByName(xmlNodePtr parent, const char *name);
+}
+
+#define for_each_xml_child_node(var, parent) \
+ for (xmlNodePtr var = parent->xmlChildrenNode; var; var = var->next)
+
+#endif
diff --git a/tools/tmxcopy/zlibutils.cpp b/tools/tmxcopy/zlibutils.cpp
new file mode 100644
index 000000000..39c19aeef
--- /dev/null
+++ b/tools/tmxcopy/zlibutils.cpp
@@ -0,0 +1,122 @@
+
+#include <stdlib.h>
+#include <iostream>
+#include <cassert>
+#include <zlib.h>
+
+/**
+ * Inflates either zlib or gzip deflated memory. The inflated memory is
+ * expected to be freed by the caller.
+ */
+int
+inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out, unsigned int &outLength)
+{
+ int bufferSize = 256 * 1024;
+ int ret;
+ z_stream strm;
+
+ out = (unsigned char*) malloc(bufferSize);
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.next_in = in;
+ strm.avail_in = inLength;
+ strm.next_out = out;
+ strm.avail_out = bufferSize;
+
+ ret = inflateInit2(&strm, 15 + 32);
+
+ if (ret != Z_OK)
+ return ret;
+
+ do
+ {
+ if (strm.next_out == NULL)
+ {
+ inflateEnd(&strm);
+ return Z_MEM_ERROR;
+ }
+
+ ret = inflate(&strm, Z_NO_FLUSH);
+ assert(ret != Z_STREAM_ERROR);
+
+ switch (ret) {
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ (void) inflateEnd(&strm);
+ return ret;
+ }
+
+ if (ret != Z_STREAM_END)
+ {
+ out = (unsigned char*) realloc(out, bufferSize * 2);
+
+ if (out == NULL)
+ {
+ inflateEnd(&strm);
+ return Z_MEM_ERROR;
+ }
+
+ strm.next_out = out + bufferSize;
+ strm.avail_out = bufferSize;
+ bufferSize *= 2;
+ }
+ }
+ while (ret != Z_STREAM_END);
+ assert(strm.avail_in == 0);
+
+ outLength = bufferSize - strm.avail_out;
+ (void) inflateEnd(&strm);
+ return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+int
+inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out)
+{
+ unsigned int outLength = 0;
+ int ret = inflateMemory(in, inLength, out, outLength);
+
+ if (ret != Z_OK || out == NULL)
+ {
+ if (ret == Z_MEM_ERROR)
+ {
+ std::cerr<<"Error: Out of memory while decompressing map data!";
+ }
+ else if (ret == Z_VERSION_ERROR)
+ {
+ std::cerr<<"Error: Incompatible zlib version!";
+ }
+ else if (ret == Z_DATA_ERROR)
+ {
+ std::cerr<<"Error: Incorrect zlib compressed data!";
+ }
+ else
+ {
+ std::cerr<<"Error: Unknown error while decompressing map data!";
+ }
+
+ free(out);
+ out = NULL;
+ outLength = 0;
+ }
+
+ return outLength;
+}
+
+/*
+int
+compressMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out, unsigned int &outLength)
+{
+ uLongf fOutLen = outLength;
+ int ret = compress((Bytef*)out, &fOutLen, (Bytef*)in, inLength);
+ outLength = fOutLen;
+
+ assert (ret == Z_OK);
+}
+*/
diff --git a/tools/tmxcopy/zlibutils.h b/tools/tmxcopy/zlibutils.h
new file mode 100644
index 000000000..300c72ad9
--- /dev/null
+++ b/tools/tmxcopy/zlibutils.h
@@ -0,0 +1,11 @@
+int
+inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out, unsigned int &outLength);
+
+int
+inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out);
+
+int
+compressMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out, unsigned int &outLength);
diff --git a/tools/upalyzer/analyze.php b/tools/upalyzer/analyze.php
new file mode 100644
index 000000000..bdb56d41d
--- /dev/null
+++ b/tools/upalyzer/analyze.php
@@ -0,0 +1,191 @@
+<?php
+/* analyze.php
+ * Copyright 2007 Bjørn Lindeijer
+ *
+ * This file is part of upalyzer.
+ *
+ * upalyzer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * upalyzer 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 upalyzer. If not, see <http://www.gnu.org/licenses/>.
+ */
+header("Content-type: text/html");
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+?>
+<html>
+<head><title>Update analysis</title></head>
+<body>
+<pre>
+List of current updates:
+
+<?php
+$download_url_base = 'http://updates.themanaworld.org/tmwdata/';
+$checkout_path = '/home/eathena/public_html/updates/tmwdata/';
+$update_file = array_filter(array_reverse(file('resources2.txt')));
+$updates = array();
+$update_file_maxlen = 0;
+$data_size = 0;
+$data_uncompressed_size = 0;
+$data_used_size = 0;
+$data_overhead_size = 0;
+$update_entries = array();
+$update_entry_maxlen = 0;
+
+foreach ($update_file as $update_line)
+{
+ list($file, $hash) = explode(' ', trim($update_line), 2);
+ $update = array(
+ 'file' => $file,
+ 'adler32' => $hash,
+ 'filesize' => filesize($file),
+ 'size' => 0,
+ 'used_entry_count' => 0,
+ 'used_size' => 0,
+ 'uncompressed_size' => 0);
+ $update_file_maxlen = max($update_file_maxlen, strlen($file));
+
+ $entries = array();
+ $zip = zip_open(realpath($file));
+
+ if ($zip && !is_int($zip)) {
+ while ($zip_entry = zip_read($zip)) {
+ $update['uncompressed_size'] += zip_entry_filesize($zip_entry);
+ $entry_name = zip_entry_name($zip_entry);
+ $entry_size = zip_entry_compressedsize($zip_entry);
+ $entry_exists = file_exists($checkout_path . $entry_name);
+ $entry_used = !array_key_exists($entry_name, $update_entries);
+ $entries[$entry_name] = array(
+ 'name' => $entry_name,
+ 'size' => $entry_size,
+ 'used' => $entry_used,
+ 'obsolete' => !$entry_exists);
+ $update['size'] += $entry_size;
+
+ if ($entry_used) {
+ if ($entry_exists) {
+ $update['used_entry_count']++;
+ $update['used_size'] += $entry_size;
+ }
+ $update_entries[$entry_name] = $update;
+ }
+
+ $update_entry_maxlen = max($update_entry_maxlen, strlen($entry_name));
+ }
+ zip_close($zip);
+ }
+ else {
+ $update['zip_error'] = $zip or true;
+ }
+
+ ksort($entries);
+ $update['entries'] = $entries;
+ $update['used_percentage'] = $update['used_size'] / $update['size'];
+ $updates[] = $update;
+
+ $data_used_size += $update['used_size'];
+ $data_size += $update['size'];
+ $data_uncompressed_size += $update['uncompressed_size'];
+ $data_overhead_size += $update['filesize'] - $update['size'];
+}
+
+function print_update_name($update, $pad = true)
+{
+ global $update_file_maxlen;
+ printf("<a href=\"#%s\">%s</a>", $update['file'], $update['file']);
+ if ($pad)
+ echo str_repeat(' ', $update_file_maxlen - strlen($update['file']));
+}
+
+// Print overall statistics
+
+foreach (array_reverse($updates) as $update)
+{
+ print_update_name($update);
+ printf(" %8s", $update['adler32']);
+ printf(" %4d kb", $update['filesize'] / 1024);
+ if (!$update['zip_error']) {
+ printf(" %4d kb", $update['uncompressed_size'] / 1024);
+ printf(" %3d%% used (%d/%d files)", $update['used_percentage'] * 100,
+ $update['used_entry_count'],
+ count($update['entries']));
+ } else {
+ printf(" Error! ");
+ if (is_int($update['zip_error']))
+ echo $update['zip_error'];
+ }
+ echo "\n";
+}
+
+printf("\n");
+printf("Amount of data: %4d kb (+%d kb zip file overhead)\n",
+ $data_size / 1024,
+ $data_overhead_size / 1024);
+printf("Uncompressed: %4d kb\n", $data_uncompressed_size / 1024);
+printf("Obsoleted data: %4d kb (%d%%)\n",
+ ($data_size - $data_used_size) / 1024,
+ 100 - ($data_used_size / $data_size) * 100);
+
+printf("\n");
+
+
+// Print list of update entries and the update they are loaded from
+
+ksort($update_entries);
+
+foreach ($update_entries as $entry => $update)
+{
+ $exists = file_exists($checkout_path . $entry);
+ printf("<span style=\"color: %s;\">%-{$update_entry_maxlen}s</span> ",
+ $exists ? "black" : "rgb(100,100,100)",
+ $entry);
+ print_update_name($update, true);
+
+ if ($exists && substr($entry, strlen($entry) - 1) != '/')
+ printf(' <a href="%s%s">download</a>', $download_url_base, $entry);
+ echo "\n";
+}
+
+
+// For each update, print its list of files and indicate whether they are used
+
+foreach (array_reverse($updates) as $update)
+{
+ print "\n<a name=\"".$update['file']."\"/><b>".$update['file']."</b>\n";
+
+ foreach ($update['entries'] as $entry_name => $entry) {
+ printf("%s%-{$update_entry_maxlen}s%s",
+ $entry['obsolete'] ? "<span style=\"color: rgb(100,100,100);\">" : "",
+ $entry_name,
+ $entry['obsolete'] ? "</span>" : "");
+ if ($entry['used'] && !$entry['obsolete']) {
+ echo ' *';
+ } elseif (!$entry['obsolete']) {
+ echo ' ';
+ print_update_name($update_entries[$entry_name], false);
+ }
+ echo "\n";
+ }
+}
+
+/*
+if ($dh = opendir('.')) {
+ while (($file = readdir($dh)) !== false) {
+ }
+ closedir($dh);
+}
+*/
+?>
+</pre>
+</body>
+</html>
diff --git a/tools/update-copyright.sh b/tools/update-copyright.sh
new file mode 100755
index 000000000..8f924f53c
--- /dev/null
+++ b/tools/update-copyright.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Copyright (C) 2001-2010 Wormux Team.
+# Copyright (C) 2010 The ManaWorld Development Team.
+
+new_year="$1"
+[[ -z $new_year ]] && echo "Missing parameter: year" && exit 1
+
+[[ ! -e src ]] && echo "This script should be ran from the top mana/manaserv dir" && exit 2
+
+tmp_file="w$RANDOM$RANDOM$RANDOM$RANDOM"
+[[ -e $tmp_file ]] && tmp_file="w$RANDOM$RANDOM$RANDOM$RANDOM"
+
+# update the dates, creating the interval if it doesn't exist yet
+find -iname "*.cpp" -or -iname "*.h" -or -iname "*.hpp" |
+ xargs sed -i "/Copyright.*The Mana World Development Team/ s,\(20[0-9]*\) \|\(20[0-9]*\)-20[0-9]* ,\1\2-$new_year ,"
+
+# do a semi-automated commit check
+git diff > $tmp_file
+echo "The next +/- counts mentioning copyrights should match:"
+grep "^[-+][^-+]" $tmp_file | sort | uniq -c
+echo "If they don't, try finding the offending files with grep -rl <\$bad_line>"
+
+# Remove temp file
+[[ -e $tmp_file ]] && rm $tmp_file
diff --git a/update-creator.sh b/update-creator.sh
new file mode 100755
index 000000000..edda56131
--- /dev/null
+++ b/update-creator.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+find -name \*.cpp \
+ -o -name \*.h \
+ -o -name \*.am \
+ -o -name \*.txt \
+ -o -name \*.xml \
+ -o -name \*.mana \
+ | sort > mana.files